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 + -
显示快捷键?