arm: add ARM support to M5
[gem5.git] / src / arch / isa_parser.py
index 64a120c4ccd1283b840da04a6bc3f358ca98fc43..bbdd95bb00fe76b5f3179cc4be6be38321290b7a 100755 (executable)
@@ -1235,6 +1235,9 @@ class Operand(object):
     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
@@ -1414,6 +1417,43 @@ class ControlRegOperand(Operand):
               self.base_name
         return wb
 
+class 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 wb
+
 class ControlBitfieldOperand(ControlRegOperand):
     def makeRead(self):
         bit_select = 0
@@ -1464,6 +1504,25 @@ class MemOperand(Operand):
     def makeAccSize(self):
         return self.size
 
+class UPCOperand(Operand):
+    def makeConstructor(self):
+        return ''
+
+    def makeRead(self):
+        return '%s = xc->readMicroPC();\n' % self.base_name
+
+    def makeWrite(self):
+        return 'xc->setMicroPC(%s);\n' % self.base_name
+
+class NUPCOperand(Operand):
+    def makeConstructor(self):
+        return ''
+
+    def makeRead(self):
+        return '%s = xc->readNextMicroPC();\n' % self.base_name
+
+    def makeWrite(self):
+        return 'xc->setNextMicroPC(%s);\n' % self.base_name
 
 class NPCOperand(Operand):
     def makeConstructor(self):
@@ -1554,6 +1613,8 @@ def buildOperandNameMap(userDict, lineno):
     global operandsWithExtRE
     operandsWithExtRE = re.compile(operandsWithExtREString, re.MULTILINE)
 
+maxInstSrcRegs = 0
+maxInstDestRegs = 0
 
 class OperandList:
 
@@ -1617,6 +1678,12 @@ class OperandList:
                 if self.memOperand:
                     error(0, "Code block has more than one memory operand.")
                 self.memOperand = op_desc
+        global maxInstSrcRegs
+        global maxInstDestRegs
+        if maxInstSrcRegs < self.numSrcRegs:
+            maxInstSrcRegs = self.numSrcRegs
+        if maxInstDestRegs < self.numDestRegs:
+            maxInstDestRegs = self.numDestRegs
         # now make a final pass to finalize op_desc fields that may depend
         # on the register enumeration
         for op_desc in self.items:
@@ -1836,6 +1903,22 @@ namespace %(namespace)s {
 %(decode_function)s
 '''
 
+max_inst_regs_template = '''
+/*
+ * DO NOT EDIT THIS FILE!!!
+ *
+ * It was automatically generated from the ISA description in %(filename)s
+ */
+
+namespace %(namespace)s {
+
+    const int MaxInstSrcRegs = %(MaxInstSrcRegs)d;
+    const int MaxInstDestRegs = %(MaxInstDestRegs)d;
+
+} // namespace %(namespace)s
+
+'''
+
 
 # Update the output file only if the new contents are different from
 # the current contents.  Minimizes the files that need to be rebuilt
@@ -1935,6 +2018,16 @@ def parse_isa_desc(isa_desc_file, output_dir):
         update_if_needed(output_dir + '/' + cpu.filename,
                           file_template % vars())
 
+    # The variable names here are hacky, but this will creat local variables
+    # which will be referenced in vars() which have the value of the globals.
+    global maxInstSrcRegs
+    MaxInstSrcRegs = maxInstSrcRegs
+    global maxInstDestRegs
+    MaxInstDestRegs = maxInstDestRegs
+    # max_inst_regs.hh
+    update_if_needed(output_dir + '/max_inst_regs.hh', \
+            max_inst_regs_template % vars())
+
 # global list of CpuModel objects (see cpu_models.py)
 cpu_models = []