isa_parser.py
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· Python 代码 · 共 1,867 行 · 第 1/5 页
PY
1,867 行
####################################################################### Force the argument to be a list. Useful for flags, where a caller# can specify a singleton flag or a list of flags. Also usful for# converting tuples to lists so they can be modified.def makeList(arg): if isinstance(arg, list): return arg elif isinstance(arg, tuple): return list(arg) elif not arg: return [] else: return [ arg ]# Generate operandTypeMap from the user's 'def operand_types'# statement.def buildOperandTypeMap(userDict, lineno): global operandTypeMap operandTypeMap = {} for (ext, (desc, size)) in userDict.iteritems(): if desc == 'signed int': ctype = 'int%d_t' % size is_signed = 1 elif desc == 'unsigned int': ctype = 'uint%d_t' % size is_signed = 0 elif desc == 'float': is_signed = 1 # shouldn't really matter if size == 32: ctype = 'float' elif size == 64: ctype = 'double' elif desc == 'twin64 int': is_signed = 0 ctype = 'Twin64_t' elif desc == 'twin32 int': is_signed = 0 ctype = 'Twin32_t' if ctype == '': error(lineno, 'Unrecognized type description "%s" in userDict') operandTypeMap[ext] = (size, ctype, is_signed)#### Base class for operand descriptors. An instance of this class (or# actually a class derived from this one) represents a specific# operand for a code block (e.g, "Rc.sq" as a dest). Intermediate# derived classes encapsulates the traits of a particular operand type# (e.g., "32-bit integer register").#class Operand(object): def __init__(self, full_name, ext, is_src, is_dest): self.full_name = full_name self.ext = ext self.is_src = is_src self.is_dest = is_dest # The 'effective extension' (eff_ext) is either the actual # extension, if one was explicitly provided, or the default. if ext: self.eff_ext = ext else: self.eff_ext = self.dflt_ext (self.size, self.ctype, self.is_signed) = operandTypeMap[self.eff_ext] # note that mem_acc_size is undefined for non-mem operands... # template must be careful not to use it if it doesn't apply. if self.isMem(): self.mem_acc_size = self.makeAccSize() if self.ctype in ['Twin32_t', 'Twin64_t']: self.mem_acc_type = 'Twin' else: self.mem_acc_type = 'uint' # Finalize additional fields (primarily code fields). This step # is done separately since some of these fields may depend on the # register index enumeration that hasn't been performed yet at the # time of __init__(). def finalize(self): self.flags = self.getFlags() self.constructor = self.makeConstructor() self.op_decl = self.makeDecl() if self.is_src: self.op_rd = self.makeRead() self.op_src_decl = self.makeDecl() else: self.op_rd = '' self.op_src_decl = '' if self.is_dest: self.op_wb = self.makeWrite() self.op_dest_decl = self.makeDecl() else: self.op_wb = '' self.op_dest_decl = '' def isMem(self): return 0 def isReg(self): return 0 def isFloatReg(self): return 0 def isIntReg(self): return 0 def isControlReg(self): return 0 def isIControlReg(self): return 0 def getFlags(self): # note the empty slice '[:]' gives us a copy of self.flags[0] # instead of a reference to it my_flags = self.flags[0][:] if self.is_src: my_flags += self.flags[1] if self.is_dest: my_flags += self.flags[2] return my_flags def makeDecl(self): # Note that initializations in the declarations are solely # to avoid 'uninitialized variable' errors from the compiler. return self.ctype + ' ' + self.base_name + ' = 0;\n';class IntRegOperand(Operand): def isReg(self): return 1 def isIntReg(self): return 1 def makeConstructor(self): c = '' if self.is_src: c += '\n\t_srcRegIdx[%d] = %s;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: c += '\n\t_destRegIdx[%d] = %s;' % \ (self.dest_reg_idx, self.reg_spec) return c def makeRead(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read integer register as FP') if (self.size == self.dflt_size): return '%s = xc->readIntRegOperand(this, %d);\n' % \ (self.base_name, self.src_reg_idx) elif (self.size > self.dflt_size): int_reg_val = 'xc->readIntRegOperand(this, %d)' % \ (self.src_reg_idx) if (self.is_signed): int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val) return '%s = %s;\n' % (self.base_name, int_reg_val) else: return '%s = bits(xc->readIntRegOperand(this, %d), %d, 0);\n' % \ (self.base_name, self.src_reg_idx, self.size-1) def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write integer register as FP') if (self.size != self.dflt_size and self.is_signed): final_val = 'sext<%d>(%s)' % (self.size, self.base_name) else: final_val = self.base_name wb = ''' { %s final_val = %s; xc->setIntRegOperand(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } }''' % (self.dflt_ctype, final_val, self.dest_reg_idx) return wbclass FloatRegOperand(Operand): def isReg(self): return 1 def isFloatReg(self): return 1 def makeConstructor(self): c = '' if self.is_src: c += '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \ (self.dest_reg_idx, self.reg_spec) return c def makeRead(self): bit_select = 0 width = 0; if (self.ctype == 'float'): func = 'readFloatRegOperand' width = 32; elif (self.ctype == 'double'): func = 'readFloatRegOperand' width = 64; else: func = 'readFloatRegOperandBits' if (self.ctype == 'uint32_t'): width = 32; elif (self.ctype == 'uint64_t'): width = 64; if (self.size != self.dflt_size): bit_select = 1 if width: base = 'xc->%s(this, %d, %d)' % \ (func, self.src_reg_idx, width) else: base = 'xc->%s(this, %d)' % \ (func, self.src_reg_idx) if bit_select: return '%s = bits(%s, %d, 0);\n' % \ (self.base_name, base, self.size-1) else: return '%s = %s;\n' % (self.base_name, base) def makeWrite(self): final_val = self.base_name final_ctype = self.ctype widthSpecifier = '' width = 0 if (self.ctype == 'float'): width = 32 func = 'setFloatRegOperand' elif (self.ctype == 'double'): width = 64 func = 'setFloatRegOperand' elif (self.ctype == 'uint32_t'): func = 'setFloatRegOperandBits' width = 32 elif (self.ctype == 'uint64_t'): func = 'setFloatRegOperandBits' width = 64 else: func = 'setFloatRegOperandBits' final_ctype = 'uint%d_t' % self.dflt_size if (self.size != self.dflt_size and self.is_signed): final_val = 'sext<%d>(%s)' % (self.size, self.base_name) if width: widthSpecifier = ', %d' % width wb = ''' { %s final_val = %s; xc->%s(this, %d, final_val%s);\n if (traceData) { traceData->setData(final_val); } }''' % (final_ctype, final_val, func, self.dest_reg_idx, widthSpecifier) return wbclass ControlRegOperand(Operand): def isReg(self): return 1 def isControlReg(self): return 1 def makeConstructor(self): c = '' if self.is_src: c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \ (self.dest_reg_idx, self.reg_spec) return c def makeRead(self): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) else: return '%s = bits(%s, %d, 0);\n' % \ (self.base_name, base, self.size-1) def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \ (self.dest_reg_idx, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wbclass IControlRegOperand(Operand): def isReg(self): return 1 def isIControlReg(self): return 1 def makeConstructor(self): c = '' if self.is_src: c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \ (self.dest_reg_idx, self.reg_spec) return c def makeRead(self): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') base = 'xc->readMiscReg(%s)' % self.reg_spec if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) else: return '%s = bits(%s, %d, 0);\n' % \ (self.base_name, base, self.size-1) def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') wb = 'xc->setMiscReg(%s, %s);\n' % \ (self.reg_spec, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wbclass ControlBitfieldOperand(ControlRegOperand): def makeRead(self): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') base = 'xc->readMiscReg(%s)' % self.reg_spec name = self.base_name return '%s = bits(%s, %s_HI, %s_LO);' % \ (name, base, name, name) def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') base = 'xc->readMiscReg(%s)' % self.reg_spec name = self.base_name wb_val = 'insertBits(%s, %s_HI, %s_LO, %s)' % \ (base, name, name, self.base_name) wb = 'xc->setMiscRegOperand(this, %s, %s );\n' % (self.dest_reg_idx, wb_val) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wbclass MemOperand(Operand): def isMem(self): return 1 def makeConstructor(self): return '' def makeDecl(self): # Note that initializations in the declarations are solely # to avoid 'uninitialized variable' errors from the compiler. # Declare memory data variable. if self.ctype in ['Twin32_t','Twin64_t']: return "%s %s; %s.a = 0; %s.b = 0;\n" % (self.ctype, self.base_name, self.base_name, self.base_name) c = '%s %s = 0;\n' % (self.ctype, self.base_name) return c def makeRead(self):
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?