Consolidated the microcode assembler to help separate it from more x86-centric stuff.
authorGabe Black <gblack@eecs.umich.edu>
Fri, 6 Apr 2007 16:39:25 +0000 (16:39 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 6 Apr 2007 16:39:25 +0000 (16:39 +0000)
--HG--
extra : convert_revision : 5e7e8026e24ce44a3dac4a358e0c3e5560685958

src/arch/x86/isa/microasm.isa
src/arch/x86/isa/microops/base.isa

index 0d9c2bc4c8aace7c8aa48abc9ca233449c2607f9..d3ced71be0407263731fa656efe4bad989e8b26a 100644 (file)
 //  variety of operands
 //
 
-let {{
-    # This builds either a regular or macro op to implement the sequence of
-    # ops we give it.
-    def genInst(name, Name, ops):
-        # If we can implement this instruction with exactly one microop, just
-        # use that directly.
-        newStmnt = ''
-        if len(ops) == 1:
-            decode_block = "return %s;" % \
-                            ops[0].getAllocator()
-            return ('', '', decode_block, '')
-        else:
-            # Build a macroop to contain the sequence of microops we've
-            # been given.
-            return genMacroOp(name, Name, ops)
-}};
-
 let {{
     # This code builds up a decode block which decodes based on switchval.
     # vals is a dict which matches case values with what should be decoded to.
@@ -187,14 +170,8 @@ 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 microOp sequence.
-        ops = assembleMicro(code)
-
-        # Build a macroop to contain the sequence of microops we've
-        # constructed. The decode block will be used to fill in our
-        # inner decode structure, and the rest will be concatenated and
-        # passed back.
-        return genInst(name, Name, ops)
+        # specified. Now we'll assemble it it into a StaticInst.
+        return assembleMicro(name, Name, code)
 }};
 
 ////////////////////////////////////////////////////////////////////
@@ -202,6 +179,13 @@ let {{
 //  The microcode assembler
 //
 
+let {{
+    # These are used when setting up microops so that they can specialize their
+    # base class template properly.
+    RegOpType = "RegisterOperand"
+    ImmOpType = "ImmediateOperand"
+}};
+
 let {{
     class MicroOpStatement(object):
         def __init__(self):
@@ -242,19 +226,9 @@ let {{
             return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args)
 }};
 
-let {{
-    def buildLabelDict(ops):
-        labels = {}
-        micropc = 0
-        for op in ops:
-            if op.label:
-                labels[op.label] = count
-            micropc += 1
-        return labels
-}};
-
 let{{
-    def assembleMicro(code):
+    def assembleMicro(name, Name, code):
+
         # This function takes in a block of microcode assembly and returns
         # a python list of objects which describe it.
 
@@ -341,7 +315,13 @@ let{{
             lineMatch = lineRe.search(code)
 
         # Decode the labels into displacements
-        labels = buildLabelDict(statements)
+
+        labels = {}
+        micropc = 0
+        for statement in statements:
+            if statement.label:
+                labels[statement.label] = count
+            micropc += 1
         micropc = 0
         for statement in statements:
             for arg in statement.args:
@@ -353,5 +333,15 @@ let{{
                     # micropc + 1 + displacement.
                     arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1
             micropc += 1
-        return statements
+
+        # 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()
+            return ('', '', decode_block, '')
+        else:
+            # Build a macroop to contain the sequence of microops we've
+            # been given.
+            return genMacroOp(name, Name, statements)
 }};
index beaa44b97380156adb8010ab0047bf01e671efed..4254994f3a82290919a2ec7a97c89e9a6d23df52 100644 (file)
@@ -63,7 +63,7 @@ output header {{
     };
 }};
 
-//A class which is the base of all x86 micro ops it provides a function to
+//A class which is the base of all x86 micro ops. It provides a function to
 //set necessary flags appropriately.
 output header {{
     class X86MicroOpBase : public X86StaticInst
@@ -97,6 +97,7 @@ def template BaseMicroOpTemplateDeclare {{
 
 let {{
     def buildBaseMicroOpTemplate(Name, numParams):
+        assert(numParams > 0)
         signature = "<"
         signature += "int SignatureOperandTypeSpecifier0"
         for count in xrange(1,numParams):
@@ -105,10 +106,9 @@ let {{
         signature += ">"
         subs = {"signature" : signature, "class_name" : Name}
         return BaseMicroOpTemplateDeclare.subst(subs)
+}};
 
-    RegOpType = "RegisterOperand"
-    ImmOpType = "ImmediateOperand"
-
+let {{
     def buildMicroOpTemplateDict(*params):
         signature = "<"
         if len(params):