X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Farch%2Fisa_parser.py;h=d5b5bbe4f9c56586082475689918e2ffc335da2c;hb=931405da2f8828c23463d83f0b77b551d633565c;hp=fb398d152efeabc650c220fe4ac2bd05cc4ace9e;hpb=0fd999ca403f427ab5278bf69b005ed1ce851876;p=gem5.git diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index fb398d152..d5b5bbe4f 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -25,7 +25,6 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Steve Reinhardt -# Korey Sewell import os import sys @@ -116,7 +115,7 @@ t_SEMI = r';' t_DOT = r'\.' t_COLON = r':' t_DBLCOLON = r'::' -t_ASTERISK = r'\*' +t_ASTERISK = r'\*' # Identifiers and reserved words reserved_map = { } @@ -345,7 +344,7 @@ def p_def_operands(t): error(t.lexer.lineno, 'error: operand types must be defined before operands') try: - userDict = eval('{' + t[3] + '}') + userDict = eval('{' + t[3] + '}', exportContext) except Exception, exc: error(t.lexer.lineno, 'error: %s in def operands block "%s".' % (exc, t[3])) @@ -480,7 +479,7 @@ def p_excess_args_param(t): # # A decode block looks like: -# decode [, ]* [default ] { ... } +# decode [, ]* [default ] { ... } # def p_decode_block(t): 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' @@ -1149,7 +1148,7 @@ def buildOperandTypeMap(userDict, lineno): ctype = 'uint%d_t' % size is_signed = 0 elif desc == 'float': - is_signed = 1 # shouldn't really matter + is_signed = 1 # shouldn't really matter if size == 32: ctype = 'float' elif size == 64: @@ -1174,6 +1173,39 @@ def buildOperandTypeMap(userDict, lineno): # (e.g., "32-bit integer register"). # class Operand(object): + def buildReadCode(self, func = None): + code = self.read_code % {"name": self.base_name, + "func": func, + "op_idx": self.src_reg_idx, + "reg_idx": self.reg_spec, + "size": self.size, + "ctype": self.ctype} + if self.size != self.dflt_size: + return '%s = bits(%s, %d, 0);\n' % \ + (self.base_name, code, self.size-1) + else: + return '%s = %s;\n' % \ + (self.base_name, code) + + def buildWriteCode(self, func = None): + 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 + code = self.write_code % {"name": self.base_name, + "func": func, + "op_idx": self.dest_reg_idx, + "reg_idx": self.reg_spec, + "size": self.size, + "ctype": self.ctype, + "final_val": final_val} + return ''' + { + %s final_val = %s; + %s; + if (traceData) { traceData->setData(final_val); } + }''' % (self.dflt_ctype, final_val, code) + def __init__(self, full_name, ext, is_src, is_dest): self.full_name = full_name self.ext = ext @@ -1270,6 +1302,8 @@ class IntRegOperand(Operand): def makeRead(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read integer register as FP') + if self.read_code != None: + return self.buildReadCode('readIntRegOperand') if (self.size == self.dflt_size): return '%s = xc->readIntRegOperand(this, %d);\n' % \ (self.base_name, self.src_reg_idx) @@ -1286,6 +1320,8 @@ class IntRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write integer register as FP') + if self.write_code != None: + return self.buildWriteCode('setIntRegOperand') if (self.size != self.dflt_size and self.is_signed): final_val = 'sext<%d>(%s)' % (self.size, self.base_name) else: @@ -1317,27 +1353,15 @@ class FloatRegOperand(Operand): def makeRead(self): bit_select = 0 - width = 0; - if (self.ctype == 'float'): - func = 'readFloatRegOperand' - width = 32; - elif (self.ctype == 'double'): + if (self.ctype == 'float' or 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) + base = 'xc->%s(this, %d)' % (func, self.src_reg_idx) + if self.read_code != None: + return self.buildReadCode(func) if bit_select: return '%s = bits(%s, %d, 0);\n' % \ (self.base_name, base, self.size-1) @@ -1347,34 +1371,23 @@ class FloatRegOperand(Operand): 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 + if (self.ctype == 'float' or self.ctype == 'double'): func = 'setFloatRegOperand' - elif (self.ctype == 'uint32_t'): - func = 'setFloatRegOperandBits' - width = 32 - elif (self.ctype == 'uint64_t'): + elif (self.ctype == 'uint32_t' or 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 + if self.write_code != None: + return self.buildWriteCode(func) wb = ''' { %s final_val = %s; - xc->%s(this, %d, final_val%s);\n + xc->%s(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } - }''' % (final_ctype, final_val, func, self.dest_reg_idx, - widthSpecifier) + }''' % (final_ctype, final_val, func, self.dest_reg_idx) return wb class ControlRegOperand(Operand): @@ -1398,6 +1411,8 @@ class ControlRegOperand(Operand): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') + if self.read_code != None: + return self.buildReadCode('readMiscRegOperand') base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) @@ -1408,34 +1423,14 @@ class ControlRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') + if self.write_code != None: + return self.buildWriteCode('setMiscRegOperand') wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \ (self.dest_reg_idx, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wb -class 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 wb - class MemOperand(Operand): def isMem(self): return 1 @@ -1454,9 +1449,13 @@ class MemOperand(Operand): return c def makeRead(self): + if self.read_code != None: + return self.buildReadCode() return '' def makeWrite(self): + if self.write_code != None: + return self.buildWriteCode() return '' # Return the memory access size *in bits*, suitable for @@ -1469,9 +1468,13 @@ class UPCOperand(Operand): return '' def makeRead(self): + if self.read_code != None: + return self.buildReadCode('readMicroPC') return '%s = xc->readMicroPC();\n' % self.base_name def makeWrite(self): + if self.write_code != None: + return self.buildWriteCode('setMicroPC') return 'xc->setMicroPC(%s);\n' % self.base_name class NUPCOperand(Operand): @@ -1479,9 +1482,13 @@ class NUPCOperand(Operand): return '' def makeRead(self): + if self.read_code != None: + return self.buildReadCode('readNextMicroPC') return '%s = xc->readNextMicroPC();\n' % self.base_name def makeWrite(self): + if self.write_code != None: + return self.buildWriteCode('setNextMicroPC') return 'xc->setNextMicroPC(%s);\n' % self.base_name class NPCOperand(Operand): @@ -1489,9 +1496,13 @@ class NPCOperand(Operand): return '' def makeRead(self): + if self.read_code != None: + return self.buildReadCode('readNextPC') return '%s = xc->readNextPC();\n' % self.base_name def makeWrite(self): + if self.write_code != None: + return self.buildWriteCode('setNextPC') return 'xc->setNextPC(%s);\n' % self.base_name class NNPCOperand(Operand): @@ -1499,16 +1510,33 @@ class NNPCOperand(Operand): return '' def makeRead(self): + if self.read_code != None: + return self.buildReadCode('readNextNPC') return '%s = xc->readNextNPC();\n' % self.base_name def makeWrite(self): + if self.write_code != None: + return self.buildWriteCode('setNextNPC') return 'xc->setNextNPC(%s);\n' % self.base_name def buildOperandNameMap(userDict, lineno): global operandNameMap operandNameMap = {} for (op_name, val) in userDict.iteritems(): - (base_cls_name, dflt_ext, reg_spec, flags, sort_pri) = val + (base_cls_name, dflt_ext, reg_spec, flags, sort_pri) = val[:5] + if len(val) > 5: + read_code = val[5] + else: + read_code = None + if len(val) > 6: + write_code = val[6] + else: + write_code = None + if len(val) > 7: + error(lineno, + 'error: too many attributes for operand "%s"' % + base_cls_name) + (dflt_size, dflt_ctype, dflt_is_signed) = operandTypeMap[dflt_ext] # Canonical flag structure is a triple of lists, where each list # indicates the set of flags implied by this operand always, when @@ -1533,7 +1561,8 @@ def buildOperandNameMap(userDict, lineno): # Accumulate attributes of new operand class in tmp_dict tmp_dict = {} for attr in ('dflt_ext', 'reg_spec', 'flags', 'sort_pri', - 'dflt_size', 'dflt_ctype', 'dflt_is_signed'): + 'dflt_size', 'dflt_ctype', 'dflt_is_signed', + 'read_code', 'write_code'): tmp_dict[attr] = eval(attr) tmp_dict['base_name'] = op_name # New class name will be e.g. "IntReg_Ra" @@ -1555,9 +1584,9 @@ def buildOperandNameMap(userDict, lineno): operands = userDict.keys() operandsREString = (r''' - (?