Reworked x86 a bit
authorGabe Black <gblack@eecs.umich.edu>
Tue, 10 Apr 2007 17:25:15 +0000 (17:25 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Tue, 10 Apr 2007 17:25:15 +0000 (17:25 +0000)
--HG--
extra : convert_revision : def1a30e54b59c718c451a631a1be6f8e787e843

src/arch/x86/isa/formats/multi.isa
src/arch/x86/isa/macroop.isa
src/arch/x86/isa/microasm.isa
src/arch/x86/isa/microops/base.isa
src/arch/x86/isa/specialize.isa

index 7ad5ecd4817909df1e1b062e98b3a08addda4f97..8f91c249c1176d3d7b7a0d9d0372c280afac2aa2 100644 (file)
@@ -72,7 +72,7 @@ def format Inst(*opTypeSet) {{
     (header_output,
      decoder_output,
      decode_block,
-     exec_output) = doInst(name, Name, list(opTypeSet))
+     exce_output) = doInst(name, Name, list(opTypeSet)).makeList()
 }};
 
 def format MultiInst(switchVal, *opTypeSets) {{
@@ -82,5 +82,5 @@ def format MultiInst(switchVal, *opTypeSets) {{
     (header_output,
      decoder_output,
      decode_block,
-     exec_output) = doSplitDecode(name, Name, doInst, switchVal, switcher)
+     exec_output) = doSplitDecode(name, Name, doInst, switchVal, switcher).makeList()
 }};
index 7d41a2deadb4564c75f141351551ab036109987c..663ec7aeeed33dbeb74616b68456a5e2b708a3d6 100644 (file)
 //
 // Authors: Gabe Black
 
+//////////////////////////////////////////////////////////////////////////////
+//
+//  Architecture independent
+//
+
 // Execute method for macroops.
 def template MacroExecPanic {{
         Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
         {
             panic("Tried to execute macroop directly!");
-            M5_DUMMY_RETURN
+            return NoFault;
         }
 }};
 
 output header {{
 
-        // Base class for most macroops, except ones that need to commit as
-        // they go.
-        class X86MacroInst : public StaticInst
+        // Base class for macroops
+        class MacroOp : public StaticInst
         {
           protected:
             const uint32_t numMicroOps;
 
             //Constructor.
-            X86MacroInst(const char *mnem, ExtMachInst _machInst,
+            MacroOp(const char *mnem, ExtMachInst _machInst,
                     uint32_t _numMicroOps)
                         : StaticInst(mnem, _machInst, No_OpClass),
                         numMicroOps(_numMicroOps)
@@ -84,7 +88,7 @@ output header {{
                 flags[IsMacroOp] = true;
             }
 
-            ~X86MacroInst()
+            ~MacroOp()
             {
                 delete [] microOps;
             }
@@ -97,10 +101,29 @@ output header {{
                 return microOps[microPC];
             }
 
+            std::string generateDisassembly(Addr pc,
+                    const SymbolTable *symtab) const
+            {
+                return mnemonic;
+            }
+
             %(MacroExecPanic)s
         };
 }};
 
+// Basic instruction class declaration template.
+def template MacroDeclare {{
+        /**
+         * Static instruction class for "%(mnemonic)s".
+         */
+        class %(class_name)s : public %(base_class)s
+        {
+          public:
+            // Constructor.
+            %(class_name)s(ExtMachInst machInst);
+        };
+}};
+
 // Basic instruction class constructor template.
 def template MacroConstructor {{
         inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
@@ -113,23 +136,27 @@ def template MacroConstructor {{
         }
 }};
 
+//////////////////////////////////////////////////////////////////////////////
+//
+//  X86 specific
+//
+
 let {{
     def genMacroOp(name, Name, opSeq):
-        baseClass = 'X86MacroInst'
-        numMicroOps = len(opSeq.ops)
+        numMicroOps = len(opSeq)
         allocMicroOps = ''
         micropc = 0
-        for op in opSeq.ops:
+        for op in opSeq:
             allocMicroOps += \
                 "microOps[%d] = %s;\n" % \
-                (micropc, op.getAllocator(True, op.delayed,
+                (micropc, op.getAllocator('"' + name + '"', True, False, #op.delayed,
                                           micropc == 0,
                                           micropc == numMicroOps - 1))
             micropc += 1
-        iop = InstObjParams(name, Name, baseClass,
+        iop = InstObjParams(name, Name, 'MacroOp',
                 {'code' : '', 'num_micro_ops' : numMicroOps,
                 'alloc_micro_ops' : allocMicroOps})
-        header_output = BasicDeclare.subst(iop)
+        header_output = MacroDeclare.subst(iop)
         decoder_output = MacroConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
         exec_output = ''
index 23567aae9e22ac81caf66fc4a9ed45d8ea53d48a..9d21b6bcc1f8deed74110463ad30b0817b5ca1e8 100644 (file)
@@ -85,7 +85,7 @@ let {{
                     text += ", false"
             return text
 
-        def getAllocator(self, *microFlags):
+        def getAllocator(self, mnemonic, *microFlags):
             args = ''
             signature = "<"
             emptySig = True
@@ -104,7 +104,7 @@ let {{
                 else:
                     raise Exception, "Unrecognized operand type."
             signature += ">"
-            return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args)
+            return 'new %s%s(machInst, %s%s%s)' % (self.className, signature, mnemonic, self.microFlagsText(microFlags), args)
 }};
 
 let{{
@@ -123,7 +123,7 @@ let{{
         # the beginning of the line, so the previous component is stripped
         # before continuing.
         labelRe = re.compile(r'^[ \t]*(?P<label>\w\w*)[ \t]:')
-        lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$')
+        lineRe = re.compile(r'^(?P<line>..*)(\n|$)')
         classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)')
         # This recognizes three different flavors of operands:
         # 1. Raw decimal numbers composed of digits between 0 and 9
@@ -145,14 +145,14 @@ let{{
             # Get a line and seperate it from the rest of the code
             line = lineMatch.group("line")
             orig_line = line
-            # print "Parsing line %s" % line
+            #print "Parsing line %s" % line
             code = lineRe.sub('', code, 1)
 
             # Find the label, if any
             labelMatch = labelRe.search(line)
             if labelMatch != None:
                 statement.label = labelMatch.group("label")
-                # print "Found label %s." % statement.label
+                #print "Found label %s." % statement.label
             # Clear the label from the statement
             line = labelRe.sub('', line, 1)
 
@@ -163,7 +163,7 @@ let{{
                         % orig_line
             else:
                 statement.className = classMatch.group("className")
-                # print "Found class name %s." % statement.className
+                #print "Found class name %s." % statement.className
 
             # Clear the class name from the statement
             line = classRe.sub('', line, 1)
@@ -185,9 +185,9 @@ let{{
                     print "Problem parsing operand in statement: %s" \
                             % orig_line
                 line = opRe.sub('', line, 1)
-                # print "Found operand %s." % statement.args[-1]
+                #print "Found operand %s." % statement.args[-1]
                 opMatch = opRe.search(line)
-            # print "Found operands", statement.args
+            #print "Found operands", statement.args
 
             # Add this statement to our collection
             statements.append(statement)
@@ -215,11 +215,14 @@ let{{
                     arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1
             micropc += 1
 
+        if len(statements) == 0:
+            raise Exception, "Didn't find any microops in microcode: \n%s" % orig_code
+
         # If we can implement this instruction with exactly one microop, just
         # use that directly.
         if len(statements) == 1:
             decode_block = "return %s;" % \
-                            statements[0].getAllocator()
+                            statements[0].getAllocator('"' + name + '"')
             return ('', '', decode_block, '')
         else:
             # Build a macroop to contain the sequence of microops we've
index 4254994f3a82290919a2ec7a97c89e9a6d23df52..f0aab78720da8c65b06ffc1adf0f7fc9a0c4e289 100644 (file)
@@ -69,20 +69,33 @@ output header {{
     class X86MicroOpBase : public X86StaticInst
     {
       protected:
+        const char * instMnem;
         uint8_t opSize;
         uint8_t addrSize;
 
-        X86MicroOpBase(bool isMicro, bool isDelayed,
+        X86MicroOpBase(ExtMachInst _machInst,
+                const char *mnem, const char *_instMnem,
+                bool isMicro, bool isDelayed,
                 bool isFirst, bool isLast,
-                const char *mnem, ExtMachInst _machInst,
                 OpClass __opClass) :
-            X86StaticInst(mnem, _machInst, __opClass)
+            X86StaticInst(mnem, _machInst, __opClass),
+            instMnem(_instMnem)
         {
             flags[IsMicroOp] = isMicro;
             flags[IsDelayedCommit] = isDelayed;
             flags[IsFirstMicroOp] = isFirst;
             flags[IsLastMicroOp] = isLast;
         }
+
+        std::string generateDisassembly(Addr pc,
+                const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+
+            ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
+
+            return ss.str();
+        }
     };
 }};
 
@@ -127,7 +140,7 @@ let {{
 }};
 
 // A tmeplate for building a specialized version of the microcode
-// instruction which knows specifies which arguments it wants
+// instruction which specifies which arguments it wants
 def template MicroOpDeclare {{
     template<>
     class %(class_name)s%(signature)s : public X86MicroOpBase
@@ -137,11 +150,15 @@ def template MicroOpDeclare {{
         void buildMe();
 
       public:
-        %(class_name)s(bool isMicro, bool isDelayed,
-                bool isFirst, bool isLast,
-                ExtMachInst _machInst %(param_arg_dec)s);
+        %(class_name)s(ExtMachInst _machInst,
+                const char * instMnem,
+                bool isMicro, bool isDelayed,
+                bool isFirst, bool isLast
+                %(param_arg_dec)s);
 
-        %(class_name)s(ExtMachInst _machInst %(param_arg_dec)s);
+        %(class_name)s(ExtMachInst _machInst,
+                const char * instMnem
+                %(param_arg_dec)s);
 
         %(BasicExecDeclare)s
     };
@@ -155,19 +172,21 @@ def template MicroOpConstructor {{
     }
 
     inline %(class_name)s%(signature)s::%(class_name)s(
-            ExtMachInst machInst %(param_arg_dec)s) :
-        %(base_class)s(false, false, false, false,
-                "%(mnemonic)s", machInst, %(op_class)s)
+            ExtMachInst machInst, const char * instMnem
+            %(param_arg_dec)s) :
+        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+                false, false, false, false, %(op_class)s)
                 %(param_init)s
     {
         buildMe();
     }
 
     inline %(class_name)s%(signature)s::%(class_name)s(
-            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-            ExtMachInst machInst %(param_arg_dec)s)
-        : %(base_class)s(isMicro, isDelayed, isFirst, isLast,
-                "%(mnemonic)s", machInst, %(op_class)s)
+            ExtMachInst machInst, const char * instMnem,
+            bool isMicro, bool isDelayed, bool isFirst, bool isLast
+            %(param_arg_dec)s)
+        : %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+                isMicro, isDelayed, isFirst, isLast, %(op_class)s)
                 %(param_init)s
     {
         buildMe();
index 9cac09770f727d36bfdff013dabaf7b738a5baa1..ff92c3551692a0665ee79942e7c030ef190a79dd 100644 (file)
@@ -67,30 +67,18 @@ let {{
     # builder is called on the exploded contents of "vals" values to generate
     # whatever code should be used.
     def doSplitDecode(name, Name, builder, switchVal, vals, default = None):
-        header_output = ''
-        decoder_output = ''
-        decode_block = 'switch(%s) {\n' % switchVal
-        exec_output = ''
+        blocks = OutputBlocks()
+        blocks.decode_block += 'switch(%s) {\n' % switchVal
         for (val, todo) in vals.items():
-            (new_header_output,
-             new_decoder_output,
-             new_decode_block,
-             new_exec_output) = builder(name, Name, *todo)
-            header_output += new_header_output
-            decoder_output += new_decoder_output
-            decode_block += '\tcase %s: %s\n' % (val, new_decode_block)
-            exec_output += new_exec_output
+            built = builder(name, Name, *todo)
+            built.decode_block = '\tcase %s: %s\n' % (val, built.decode_block)
+            blocks.append(built)
         if default:
-            (new_header_output,
-             new_decoder_output,
-             new_decode_block,
-             new_exec_output) = builder(name, Name, *default)
-            header_output += new_header_output
-            decoder_output += new_decoder_output
-            decode_block += '\tdefault: %s\n' % new_decode_block
-            exec_output += new_exec_output
-        decode_block += '}\n'
-        return (header_output, decoder_output, decode_block, exec_output)
+            built = builder(name, Name, *default)
+            built.decode_block = '\tdefault: %s\n' % built.decode_block
+            blocks.append(built)
+        blocks.decode_block += '}\n'
+        return blocks
 }};
 
 let {{
@@ -143,6 +131,7 @@ let {{
                 # This needs to refer to memory, but we'll fill in the details
                 # later. It needs to take into account unaligned memory
                 # addresses.
+                code = "GenFault ${new UnimpInstFault}\n" + code
                 memCode = opRe.sub("%0", code)
                 memTypes = copy.copy(opTypes)
                 memTypes.pop(-1)
@@ -156,6 +145,7 @@ let {{
                 # This needs to refer to memory, but we'll fill in the details
                 # later. It needs to take into account unaligned memory
                 # addresses.
+                code = "GenFault ${new UnimpInstFault}\n" + code
                 code = opRe.sub("%0", code)
             elif opType.tag in ("PR", "R", "VR"):
                 # There should probably be a check here to verify that mod
@@ -168,5 +158,7 @@ let {{
         # At this point, we've built up "code" to have all the necessary extra
         # instructions needed to implement whatever types of operands were
         # specified. Now we'll assemble it it into a StaticInst.
-        return assembleMicro(name, Name, code)
+        blocks = OutputBlocks()
+        blocks.append(assembleMicro(name, Name, code))
+        return blocks
 }};