Changes to the isa_parser and affected files to fix an indexing problem with split...
authorGabe Black <gblack@eecs.umich.edu>
Sat, 16 Dec 2006 12:10:04 +0000 (07:10 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Sat, 16 Dec 2006 12:10:04 +0000 (07:10 -0500)
src/arch/isa_parser.py:
    Rearranged things so that classes with more than one execute function treat operands properly.
    1. Eliminated the CodeBlock class
    2. Created a SubOperandList
    3. Redefined how InstObjParams is constructed

    To define an InstObjParam, you can either pass in a single code literal which will be named "code", or you can pass in a dictionary of code snippets which will be substituted into the Templates. In order to get this to work, there is a new restriction that each template has only one function in it. These changes should only affect memory instructions which have regular and split execute functions.

    Also changed the MiscRegs so that they use the instrunctions srcReg and destReg arrays.
src/arch/sparc/isa/formats/basic.isa:
src/arch/sparc/isa/formats/branch.isa:
src/arch/sparc/isa/formats/integerop.isa:
src/arch/sparc/isa/formats/mem/basicmem.isa:
src/arch/sparc/isa/formats/mem/blockmem.isa:
src/arch/sparc/isa/formats/mem/util.isa:
src/arch/sparc/isa/formats/nop.isa:
src/arch/sparc/isa/formats/priv.isa:
src/arch/sparc/isa/formats/trap.isa:
    Rearranged to work with new InstObjParam scheme.
src/cpu/o3/sparc/dyn_inst.hh:
    Added functions to access the miscregs using the indexes from instructions srcReg and destReg arrays. Also changed the names of the other accessors so that they have the suffix "Operand" if they use those arrays.
src/cpu/simple/base.hh:
    Added functions to access the miscregs using the indexes from instructions srcReg and destReg arrays.

--HG--
extra : convert_revision : c91e1073138b72bcf4113a721e0ed40ec600cf2e

12 files changed:
src/arch/isa_parser.py
src/arch/sparc/isa/formats/basic.isa
src/arch/sparc/isa/formats/branch.isa
src/arch/sparc/isa/formats/integerop.isa
src/arch/sparc/isa/formats/mem/basicmem.isa
src/arch/sparc/isa/formats/mem/blockmem.isa
src/arch/sparc/isa/formats/mem/util.isa
src/arch/sparc/isa/formats/nop.isa
src/arch/sparc/isa/formats/priv.isa
src/arch/sparc/isa/formats/trap.isa
src/cpu/o3/sparc/dyn_inst.hh
src/cpu/simple/base.hh

index a96622d4a25287ca91ef067cf4a09b167af8dfa2..aacdf455f57230ddce51a8d00041b2591d1c06f6 100755 (executable)
@@ -808,8 +808,7 @@ class GenCode:
 # a defineInst() method that generates the code for an instruction
 # definition.
 
-exportContextSymbols = ('InstObjParams', 'CodeBlock',
-                        'makeList', 're', 'string')
+exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
 
 exportContext = {}
 
@@ -1003,27 +1002,83 @@ def substBitOps(code):
 # Template objects are format strings that allow substitution from
 # the attribute spaces of other objects (e.g. InstObjParams instances).
 
+labelRE = re.compile(r'[^%]%\(([^\)]+)\)[sd]')
+
 class Template:
     def __init__(self, t):
         self.template = t
 
     def subst(self, d):
-        # Start with the template namespace.  Make a copy since we're
-        # going to modify it.
-        myDict = templateMap.copy()
-        # if the argument is a dictionary, we just use it.
-        if isinstance(d, dict):
-            myDict.update(d)
-        # if the argument is an object, we use its attribute map.
-        elif hasattr(d, '__dict__'):
-            myDict.update(d.__dict__)
-        else:
-            raise TypeError, "Template.subst() arg must be or have dictionary"
+        myDict = None
+
         # Protect non-Python-dict substitutions (e.g. if there's a printf
         # in the templated C++ code)
         template = protect_non_subst_percents(self.template)
         # CPU-model-specific substitutions are handled later (in GenCode).
         template = protect_cpu_symbols(template)
+
+        # if we're dealing with an InstObjParams object, we need to be a
+        # little more sophisticated. Otherwise, just do what we've always
+        # done
+        if isinstance(d, InstObjParams):
+            # The instruction wide parameters are already formed, but the
+            # parameters which are only function wide still need to be
+            # generated.
+            perFuncNames = ['op_decl', 'op_src_decl', 'op_dest_decl', \
+                            'op_rd', 'op_wb', 'mem_acc_size', 'mem_acc_type']
+            compositeCode = ''
+
+            myDict = templateMap.copy()
+            myDict.update(d.__dict__)
+            # The "operands" and "snippets" attributes of the InstObjParams
+            # objects are for internal use and not substitution.
+            del myDict['operands']
+            del myDict['snippets']
+
+            for name in labelRE.findall(template):
+                # Don't try to find a snippet to go with things that will
+                # match against attributes of d, or that are other templates,
+                # or that we're going to generate later, or that we've already
+                # found.
+                if  not hasattr(d, name) and \
+                    not templateMap.has_key(name) and \
+                    not myDict.has_key(name) and \
+                    name not in perFuncNames:
+                    myDict[name] = d.snippets[name]
+                    if isinstance(myDict[name], str):
+                        myDict[name] = substMungedOpNames(substBitOps(myDict[name]))
+                        compositeCode += (" " + myDict[name])
+            operands = SubOperandList(compositeCode, d.operands)
+
+            myDict['op_decl'] = operands.concatAttrStrings('op_decl')
+
+            is_src = lambda op: op.is_src
+            is_dest = lambda op: op.is_dest
+
+            myDict['op_src_decl'] = \
+                      operands.concatSomeAttrStrings(is_src, 'op_src_decl')
+            myDict['op_dest_decl'] = \
+                      operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
+
+            myDict['op_rd'] = operands.concatAttrStrings('op_rd')
+            myDict['op_wb'] = operands.concatAttrStrings('op_wb')
+
+            if d.operands.memOperand:
+                myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
+                myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
+
+        else:
+            # Start with the template namespace.  Make a copy since we're
+            # going to modify it.
+            myDict = templateMap.copy()
+            # if the argument is a dictionary, we just use it.
+            if isinstance(d, dict):
+                myDict.update(d)
+            # if the argument is an object, we use its attribute map.
+            elif hasattr(d, '__dict__'):
+                myDict.update(d.__dict__)
+            else:
+                raise TypeError, "Template.subst() arg must be or have dictionary"
         return template % myDict
 
     # Convert to string.  This handles the case when a template with a
@@ -1296,10 +1351,10 @@ class ControlRegOperand(Operand):
     def makeConstructor(self):
         c = ''
         if self.is_src:
-            c += '\n\t_srcRegIdx[%d] = %s;' % \
+            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;' % \
+            c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
                  (self.dest_reg_idx, self.reg_spec)
         return c
 
@@ -1307,7 +1362,7 @@ class ControlRegOperand(Operand):
         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
+        base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx
         if self.size == self.dflt_size:
             return '%s = %s;\n' % (self.base_name, base)
         else:
@@ -1317,7 +1372,8 @@ class ControlRegOperand(Operand):
     def makeWrite(self):
         if (self.ctype == 'float' or self.ctype == 'double'):
             error(0, 'Attempt to write control register as FP')
-        wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name)
+        wb = 'xc->setMiscRegOperandWithEffect(this, %s, %s);\n' % \
+             (self.dest_reg_idx, self.base_name)
         wb += 'if (traceData) { traceData->setData(%s); }' % \
               self.base_name
         return wb
@@ -1550,6 +1606,48 @@ class OperandList:
     def sort(self):
         self.items.sort(lambda a, b: a.sort_pri - b.sort_pri)
 
+class SubOperandList(OperandList):
+
+    # Find all the operands in the given code block.  Returns an operand
+    # descriptor list (instance of class OperandList).
+    def __init__(self, code, master_list):
+        self.items = []
+        self.bases = {}
+        # delete comments so we don't match on reg specifiers inside
+        code = commentRE.sub('', code)
+        # search for operands
+        next_pos = 0
+        while 1:
+            match = operandsRE.search(code, next_pos)
+            if not match:
+                # no more matches: we're done
+                break
+            op = match.groups()
+            # regexp groups are operand full name, base, and extension
+            (op_full, op_base, op_ext) = op
+            # find this op in the master list
+            op_desc = master_list.find_base(op_base)
+            if not op_desc:
+                error(0, 'Found operand %s which is not in the master list!' \
+                        ' This is an internal error' % \
+                          op_base)
+            else:
+                # See if we've already found this operand
+                op_desc = self.find_base(op_base)
+                if not op_desc:
+                    # if not, add a reference to it to this sub list
+                    self.append(master_list.bases[op_base])
+
+            # start next search after end of current match
+            next_pos = match.end()
+        self.sort()
+        self.memOperand = None
+        for op_desc in self.items:
+            if op_desc.isMem():
+                if self.memOperand:
+                    error(0, "Code block has more than one memory operand.")
+                self.memOperand = op_desc
+
 # Regular expression object to match C++ comments
 # (used in findOperands())
 commentRE = re.compile(r'//.*\n')
@@ -1583,11 +1681,28 @@ def makeFlagConstructor(flag_list):
     code = pre + string.join(flag_list, post + pre) + post
     return code
 
-class CodeBlock:
-    def __init__(self, code):
-        self.orig_code = code
-        self.operands = OperandList(code)
-        self.code = substMungedOpNames(substBitOps(code))
+# Assume all instruction flags are of the form 'IsFoo'
+instFlagRE = re.compile(r'Is.*')
+
+# OpClass constants end in 'Op' except No_OpClass
+opClassRE = re.compile(r'.*Op|No_OpClass')
+
+class InstObjParams:
+    def __init__(self, mnem, class_name, base_class = '',
+                 snippets = None, opt_args = []):
+        self.mnemonic = mnem
+        self.class_name = class_name
+        self.base_class = base_class
+        compositeCode = ''
+        if snippets:
+            if not isinstance(snippets, dict):
+                snippets = {'code' : snippets}
+            for snippet in snippets.values():
+                if isinstance(snippet, str):
+                    compositeCode += (" " + snippet)
+        self.snippets = snippets
+
+        self.operands = OperandList(compositeCode)
         self.constructor = self.operands.concatAttrStrings('constructor')
         self.constructor += \
                  '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
@@ -1597,28 +1712,10 @@ class CodeBlock:
                  '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
         self.constructor += \
                  '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
-
-        self.op_decl = self.operands.concatAttrStrings('op_decl')
-
-        is_src = lambda op: op.is_src
-        is_dest = lambda op: op.is_dest
-
-        self.op_src_decl = \
-                  self.operands.concatSomeAttrStrings(is_src, 'op_src_decl')
-        self.op_dest_decl = \
-                  self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
-
-        self.op_rd = self.operands.concatAttrStrings('op_rd')
-        self.op_wb = self.operands.concatAttrStrings('op_wb')
-
         self.flags = self.operands.concatAttrLists('flags')
 
-        if self.operands.memOperand:
-            self.mem_acc_size = self.operands.memOperand.mem_acc_size
-            self.mem_acc_type = self.operands.memOperand.mem_acc_type
-
         # Make a basic guess on the operand class (function unit type).
-        # These are good enough for most cases, and will be overridden
+        # These are good enough for most cases, and can be overridden
         # later otherwise.
         if 'IsStore' in self.flags:
             self.op_class = 'MemWriteOp'
@@ -1629,48 +1726,6 @@ class CodeBlock:
         else:
             self.op_class = 'IntAluOp'
 
-# Assume all instruction flags are of the form 'IsFoo'
-instFlagRE = re.compile(r'Is.*')
-
-# OpClass constants end in 'Op' except No_OpClass
-opClassRE = re.compile(r'.*Op|No_OpClass')
-
-class InstObjParams:
-    def __init__(self, mnem, class_name, base_class = '',
-                 code = None, opt_args = [], extras = {}):
-        self.mnemonic = mnem
-        self.class_name = class_name
-        self.base_class = base_class
-        if code:
-            #If the user already made a CodeBlock, pick the parts from it
-            if isinstance(code, CodeBlock):
-                origCode = code.orig_code
-                codeBlock = code
-            else:
-                origCode = code
-                codeBlock = CodeBlock(code)
-            stringExtras = {}
-            otherExtras = {}
-            for (k, v) in extras.items():
-                if type(v) == str:
-                    stringExtras[k] = v
-                else:
-                    otherExtras[k] = v
-            compositeCode = "\n".join([origCode] + stringExtras.values())
-            # compositeCode = '\n'.join([origCode] +
-            #      [pair[1] for pair in extras])
-            compositeBlock = CodeBlock(compositeCode)
-            for code_attr in compositeBlock.__dict__.keys():
-                setattr(self, code_attr, getattr(compositeBlock, code_attr))
-            for (key, snippet) in stringExtras.items():
-                setattr(self, key, CodeBlock(snippet).code)
-            for (key, item) in otherExtras.items():
-                setattr(self, key, item)
-            self.code = codeBlock.code
-            self.orig_code = origCode
-        else:
-            self.constructor = ''
-            self.flags = []
         # Optional arguments are assumed to be either StaticInst flags
         # or an OpClass value.  To avoid having to import a complete
         # list of these values to match against, we do it ad-hoc
index a4c05387bc893ffb9d274e441cb03529cfb7d7b4..56e9337636b005a177d97b3b4db0f6204956e867 100644 (file)
@@ -95,8 +95,7 @@ def template BasicDecodeWithMnemonic {{
 
 // The most basic instruction format... used only for a few misc. insts
 def format BasicOperate(code, *flags) {{
-        iop = InstObjParams(name, Name, 'SparcStaticInst',
-                CodeBlock(code), flags)
+        iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
index 3062f38b2f51bdd19c5828d867b39c0bd307a09b..2db7563200e67f861181bcf49dfb7be4347e2704 100644 (file)
@@ -248,7 +248,6 @@ def format Branch(code, *opt_flags) {{
 // Primary format for branch instructions:
 def format BranchN(bits, code, *opt_flags) {{
         code = re.sub(r'handle_annul', handle_annul, code)
-        codeBlk = CodeBlock(code)
         new_opt_flags = []
         for flag in opt_flags:
             if flag == ',a':
@@ -256,7 +255,7 @@ def format BranchN(bits, code, *opt_flags) {{
                 Name += 'Annul'
             else:
                 new_opt_flags += flag
-        iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags)
+        iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         exec_output = BranchExecute.subst(iop)
@@ -266,8 +265,7 @@ def format BranchN(bits, code, *opt_flags) {{
 // Primary format for branch instructions:
 def format BranchSplit(code, *opt_flags) {{
         code = re.sub(r'handle_annul', handle_annul, code)
-        codeBlk = CodeBlock(code)
-        iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
+        iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         exec_output = BranchExecute.subst(iop)
index 4f8ebebcc9173f7fcc8261e997de9a27041d5186..363aca1a13bc7aa01b710d7f81c18eab17f37a2f 100644 (file)
@@ -263,14 +263,15 @@ let {{
     def doIntFormat(code, ccCode, name, Name, opt_flags):
         (usesImm, code, immCode,
          rString, iString) = splitOutImm(code)
-        iop = InstObjParams(name, Name,        'IntOp', code,
-                opt_flags, {"cc_code": ccCode})
+        iop = InstObjParams(name, Name,        'IntOp',
+                {"code": code, "cc_code": ccCode},
+                opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         exec_output = IntOpExecute.subst(iop)
         if usesImm:
             imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
-                    immCode, opt_flags, {"cc_code": ccCode})
+                    {"code": immCode, "cc_code": ccCode}, opt_flags)
             header_output += BasicDeclare.subst(imm_iop)
             decoder_output += BasicConstructor.subst(imm_iop)
             exec_output += IntOpExecute.subst(imm_iop)
@@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{
 
 def format SetHi(code, *opt_flags) {{
     iop = InstObjParams(name, Name, 'SetHi',
-            code, opt_flags, {"cc_code": ''})
+            {"code": code, "cc_code": ''}, opt_flags)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
     exec_output = IntOpExecute.subst(iop)
index cb6c2f161d16732b0729cc0d0282442a5e653088..d5b17d720c61075be5dac0295d29c02bacdaa941 100644 (file)
@@ -55,15 +55,20 @@ let {{
     def doMemFormat(code, execute, faultCode, name, Name, opt_flags):
         addrCalcReg = 'EA = Rs1 + Rs2;'
         addrCalcImm = 'EA = Rs1 + imm;'
-        iop = InstObjParams(name, Name, 'Mem', code,
-                opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg})
-        iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
-                opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm})
+        iop = InstObjParams(name, Name, 'Mem',
+                {"code": code, "fault_check": faultCode,
+                 "ea_code": addrCalcReg},
+                opt_flags)
+        iop_imm = InstObjParams(name, Name + "Imm", 'MemImm',
+                {"code": code, "fault_check": faultCode,
+                 "ea_code": addrCalcImm},
+                opt_flags)
         header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
         decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
         decode_block = ROrImmDecode.subst(iop)
-        exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, execute,
-                faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags)
+        exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm,
+                execute, faultCode, name, name + "Imm",
+                Name, Name + "Imm", opt_flags)
         return (header_output, decoder_output, exec_output, decode_block)
 }};
 
@@ -71,7 +76,7 @@ def format LoadAlt(code, *opt_flags) {{
         (header_output,
          decoder_output,
          exec_output,
-         decode_block) = doMemFormat(code, LoadExecute,
+         decode_block) = doMemFormat(code, LoadFuncs,
             AlternateAsiPrivFaultCheck, name, Name, opt_flags)
 }};
 
@@ -79,7 +84,7 @@ def format StoreAlt(code, *opt_flags) {{
         (header_output,
          decoder_output,
          exec_output,
-         decode_block) = doMemFormat(code, StoreExecute,
+         decode_block) = doMemFormat(code, StoreFuncs,
             AlternateAsiPrivFaultCheck, name, Name, opt_flags)
 }};
 
@@ -88,7 +93,7 @@ def format Load(code, *opt_flags) {{
          decoder_output,
          exec_output,
          decode_block) = doMemFormat(code,
-             LoadExecute, '', name, Name, opt_flags)
+             LoadFuncs, '', name, Name, opt_flags)
 }};
 
 def format Store(code, *opt_flags) {{
@@ -96,5 +101,5 @@ def format Store(code, *opt_flags) {{
          decoder_output,
          exec_output,
          decode_block) = doMemFormat(code,
-             StoreExecute, '', name, Name, opt_flags)
+             StoreFuncs, '', name, Name, opt_flags)
 }};
index 8b4aca473c2f97f86dfd52fcfefa793b576559cb..c124dc600e8d15135412be618096af468cebd614 100644 (file)
@@ -293,14 +293,14 @@ let {{
             else:
                 flag_code = "flags[IsDelayedCommit] = true;"
             pcedCode = matcher.sub("Frd_%d" % microPc, code)
-            iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
-                    opt_flags, {"ea_code": addrCalcReg,
+            iop = InstObjParams(name, Name, 'BlockMem',
+                    {"code": pcedCode, "ea_code": addrCalcReg,
                     "fault_check": faultCode, "micro_pc": microPc,
-                    "set_flags": flag_code})
-            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
-                    opt_flags, {"ea_code": addrCalcImm,
+                    "set_flags": flag_code}, opt_flags)
+            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
+                    {"code": pcedCode, "ea_code": addrCalcImm,
                     "fault_check": faultCode, "micro_pc": microPc,
-                    "set_flags": flag_code})
+                    "set_flags": flag_code}, opt_flags)
             decoder_output += BlockMemMicroConstructor.subst(iop)
             decoder_output += BlockMemMicroConstructor.subst(iop_imm)
             exec_output += doDualSplitExecute(
@@ -315,25 +315,25 @@ let {{
 }};
 
 def format BlockLoad(code, *opt_flags) {{
-        # We need to make sure to check the highest priority fault last.
-        # That way, if other faults have been detected, they'll be overwritten
-        # rather than the other way around.
-        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
-        (header_output,
-         decoder_output,
-         exec_output,
-         decode_block) = doBlockMemFormat(code, faultCode,
-             LoadExecute, name, Name, opt_flags)
+    # We need to make sure to check the highest priority fault last.
+    # That way, if other faults have been detected, they'll be overwritten
+    # rather than the other way around.
+    faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
+    (header_output,
+     decoder_output,
+     exec_output,
+     decode_block) = doBlockMemFormat(code, faultCode,
+         LoadFuncs, name, Name, opt_flags)
 }};
 
 def format BlockStore(code, *opt_flags) {{
-        # We need to make sure to check the highest priority fault last.
-        # That way, if other faults have been detected, they'll be overwritten
-        # rather than the other way around.
-        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
-        (header_output,
-         decoder_output,
-         exec_output,
-         decode_block) = doBlockMemFormat(code, faultCode,
-             StoreExecute, name, Name, opt_flags)
+    # We need to make sure to check the highest priority fault last.
+    # That way, if other faults have been detected, they'll be overwritten
+    # rather than the other way around.
+    faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
+    (header_output,
+     decoder_output,
+     exec_output,
+     decode_block) = doBlockMemFormat(code, faultCode,
+         StoreFuncs, name, Name, opt_flags)
 }};
index f3adbe19f81fd61cf9d2a5517414d671fd56d8a5..e872230003ba848a9f496f89deb262e93747316a 100644 (file)
@@ -162,15 +162,17 @@ def template LoadExecute {{
 
             return fault;
         }
+}};
 
+def template LoadInitiateAcc {{
         Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
                 Trace::InstRecord * traceData) const
         {
             Fault fault = NoFault;
             Addr EA;
             uint%(mem_acc_size)s_t Mem;
-            %(ea_decl)s;
-            %(ea_rd)s;
+            %(op_decl)s;
+            %(op_rd)s;
             %(ea_code)s;
             DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
             %(fault_check)s;
@@ -180,18 +182,20 @@ def template LoadExecute {{
             }
             return fault;
         }
+}};
 
+def template LoadCompleteAcc {{
         Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
                 Trace::InstRecord * traceData) const
         {
             Fault fault = NoFault;
-            %(code_decl)s;
-            %(code_rd)s;
+            %(op_decl)s;
+            %(op_rd)s;
             Mem = pkt->get<typeof(Mem)>();
             %(code)s;
             if(fault == NoFault)
             {
-                %(code_wb)s;
+                %(op_wb)s;
             }
             return fault;
         }
@@ -228,7 +232,9 @@ def template StoreExecute {{
 
             return fault;
         }
+}};
 
+def template StoreInitiateAcc {{
         Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
                 Trace::InstRecord * traceData) const
         {
@@ -255,7 +261,9 @@ def template StoreExecute {{
             }
             return fault;
         }
+}};
 
+def template StoreCompleteAcc {{
         Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
                 Trace::InstRecord * traceData) const
         {
@@ -275,6 +283,8 @@ def template CompleteAccDeclare {{
 
 //Here are some code snippets which check for various fault conditions
 let {{
+    LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
+    StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
     # The LSB can be zero, since it's really the MSB in doubles and quads
     # and we're dealing with doubles
     BlockAlignmentFaultCheck = '''
@@ -308,20 +318,10 @@ let {{
 //and in the other they're distributed across two. Also note that for
 //execute functions, the name of the base class doesn't matter.
 let {{
-    def doSplitExecute(code, execute, name, Name, opt_flags, microParam):
-        codeParam = microParam.copy()
-        codeParam["ea_code"] = ''
-        codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam)
-        eaIop = InstObjParams(name, Name, '', microParam["ea_code"],
-                opt_flags, microParam)
-        iop = InstObjParams(name, Name, '', code, opt_flags, microParam)
-        (iop.ea_decl,
-         iop.ea_rd,
-         iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
-        (iop.code_decl,
-         iop.code_rd,
-         iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
-        return execute.subst(iop)
+    def doSplitExecute(execute, name, Name, opt_flags, microParam):
+        iop = InstObjParams(name, Name, '', microParam, opt_flags)
+        (execf, initf, compf) = execute
+        return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
 
 
     def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
@@ -330,8 +330,9 @@ let {{
         for (eaCode, name, Name) in (
                 (eaRegCode, nameReg, NameReg),
                 (eaImmCode, nameImm, NameImm)):
-            microParams = {"ea_code" : eaCode, "fault_check": faultCode}
-            executeCode += doSplitExecute(code, execute, name, Name,
+            microParams = {"code": code, "ea_code": eaCode,
+                "fault_check": faultCode}
+            executeCode += doSplitExecute(execute, name, Name,
                     opt_flags, microParams)
         return executeCode
 }};
index 37ef2e8d0fd90b0611685263fdaf86fc7eb005e5..de2ba2f54bf646f5c4e21b78dc6e7db798d981e9 100644 (file)
@@ -88,9 +88,7 @@ def template NopExecute {{
 
 // Primary format for integer operate instructions:
 def format Nop(code, *opt_flags) {{
-        orig_code = code
-        cblk = CodeBlock(code)
-        iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags)
+        iop = InstObjParams(name, Name, 'Nop', code, opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
index 3d47ca02f9ac7b49d4e5af954de169647418e3ba..36403afb4ef5698fd55d4b65d338cefc84e99b15 100644 (file)
@@ -235,8 +235,9 @@ let {{
                 name = mnem
                 regBase = 'WrPriv'
                 break
-        iop = InstObjParams(name, Name, regBase, code,
-                opt_flags, {"check": checkCode, "reg_name": regName})
+        iop = InstObjParams(name, Name, regBase,
+                {"code": code, "check": checkCode, "reg_name": regName},
+                opt_flags)
         header_output = BasicDeclare.subst(iop)
         if regName == '':
             decoder_output = BasicConstructor.subst(iop)
@@ -245,7 +246,8 @@ let {{
         exec_output = PrivExecute.subst(iop)
         if usesImm:
             imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
-                    immCode, opt_flags, {"check": checkCode, "reg_name": regName})
+                    {"code": immCode, "check": checkCode, "reg_name": regName},
+                    opt_flags)
             header_output += BasicDeclare.subst(imm_iop)
             if regName == '':
                 decoder_output += BasicConstructor.subst(imm_iop)
index 04d467cfe6100493d3c79e758d782f7f2f78ea7d..9c118b22719514f578d1a2e9e52667cd296f400b 100644 (file)
@@ -83,9 +83,7 @@ def template TrapExecute {{
 }};
 
 def format Trap(code, *opt_flags) {{
-        orig_code = code
-        cblk = CodeBlock(code)
-        iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags)
+        iop = InstObjParams(name, Name, 'Trap', code, opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
index 2d73ca8d1d517243ecae306dae74168860a905a3..fda99cb6c1948947caa7a12498e1ecd3033d1ee3 100644 (file)
@@ -106,6 +106,45 @@ class SparcDynInst : public BaseDynInst<Impl>
                                                this->threadNumber);
     }
 
+    /** Reads a miscellaneous register. */
+    TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+    {
+        return this->cpu->readMiscReg(
+                si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+                this->threadNumber);
+    }
+
+    /** Reads a misc. register, including any side-effects the read
+     * might have as defined by the architecture.
+     */
+    TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+    {
+        return this->cpu->readMiscRegWithEffect(
+                si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+                this->threadNumber);
+    }
+
+    /** Sets a misc. register. */
+    void setMiscRegOperand(const StaticInst * si,
+            int idx, const TheISA::MiscReg &val)
+    {
+        this->instResult.integer = val;
+        return this->cpu->setMiscReg(
+                si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+                val, this->threadNumber);
+    }
+
+    /** Sets a misc. register, including any side-effects the write
+     * might have as defined by the architecture.
+     */
+    void setMiscRegOperandWithEffect(
+            const StaticInst *si, int idx, const TheISA::MiscReg &val)
+    {
+        return this->cpu->setMiscRegWithEffect(
+                si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+                val, this->threadNumber);
+    }
+
 #if FULL_SYSTEM
     /** Calls hardware return from error interrupt. */
     Fault hwrei();
@@ -130,30 +169,31 @@ class SparcDynInst : public BaseDynInst<Impl>
     // storage (which is pretty hard to imagine they would have reason
     // to do).
 
-    uint64_t readIntReg(const StaticInst *si, int idx)
+    uint64_t readIntRegOperand(const StaticInst *si, int idx)
     {
         uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]);
         DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val);
         return this->cpu->readIntReg(this->_srcRegIdx[idx]);
     }
 
-    TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width)
+    TheISA::FloatReg readFloatRegOperand(const StaticInst *si,
+            int idx, int width)
     {
         return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
     }
 
-    TheISA::FloatReg readFloatReg(const StaticInst *si, int idx)
+    TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx)
     {
         return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
     }
 
-    TheISA::FloatRegBits readFloatRegBits(const StaticInst *si,
+    TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si,
             int idx, int width)
     {
         return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
     }
 
-    TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
+    TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
     {
         return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
     }
@@ -161,38 +201,38 @@ class SparcDynInst : public BaseDynInst<Impl>
     /** @todo: Make results into arrays so they can handle multiple dest
      *  registers.
      */
-    void setIntReg(const StaticInst *si, int idx, uint64_t val)
+    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
     {
         DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val);
         this->cpu->setIntReg(this->_destRegIdx[idx], val);
-        BaseDynInst<Impl>::setIntReg(si, idx, val);
+        BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
     }
 
-    void setFloatReg(const StaticInst *si, int idx,
+    void setFloatRegOperand(const StaticInst *si, int idx,
             TheISA::FloatReg val, int width)
     {
         this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
-        BaseDynInst<Impl>::setFloatReg(si, idx, val, width);
+        BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
     }
 
-    void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val)
+    void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val)
     {
         this->cpu->setFloatReg(this->_destRegIdx[idx], val);
-        BaseDynInst<Impl>::setFloatReg(si, idx, val);
+        BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
     }
 
-    void setFloatRegBits(const StaticInst *si, int idx,
+    void setFloatRegOperandBits(const StaticInst *si, int idx,
             TheISA::FloatRegBits val, int width)
     {
         this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
-        BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
+        BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
     }
 
-    void setFloatRegBits(const StaticInst *si,
+    void setFloatRegOperandBits(const StaticInst *si,
             int idx, TheISA::FloatRegBits val)
     {
         this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
-        BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
+        BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
     }
 
   public:
index c39bfa9cd43ae5acaa4f5c4fd770818104d270ad..dd178f64d3795be259805c69938ad5d9fb0e9c35 100644 (file)
@@ -303,6 +303,31 @@ class BaseSimpleCPU : public BaseCPU
         return thread->setMiscRegWithEffect(misc_reg, val);
     }
 
+    MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->readMiscReg(reg_idx);
+    }
+
+    MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->readMiscRegWithEffect(reg_idx);
+    }
+
+    void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->setMiscReg(reg_idx, val);
+    }
+
+    void setMiscRegOperandWithEffect(
+            const StaticInst *si, int idx, const MiscReg &val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->setMiscRegWithEffect(reg_idx, val);
+    }
+
 #if FULL_SYSTEM
     Fault hwrei() { return thread->hwrei(); }
     void ev5_trap(Fault fault) { fault->invoke(tc); }