Made the MultiOp format do a little more. It now sets up single microop instructions...
authorGabe Black <gblack@eecs.umich.edu>
Thu, 29 Mar 2007 17:57:19 +0000 (17:57 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 29 Mar 2007 17:57:19 +0000 (17:57 +0000)
--HG--
extra : convert_revision : 1a0a4b36afce8255e23e3cdd7a85c1392dda5f72

src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/formats/multi.isa

index 0f030299a6b557414f9ebe5aba5c27d04bb7090d..b4aeece07220c82cde1c85b851a024769c8489e2 100644 (file)
@@ -64,7 +64,7 @@
             0x6: push_ES();
             0x7: pop_ES();
             default: MultiOp::add(
-                {{Add op0, op0, op1}},
+                {{Add %0 %0 %1}},
                 OPCODE_OP_BOTTOM3,
                 [[Eb,Gb],[Ev,Gv],
                  [Gb,Eb],[Gv,Ev],
index 3e80f9cfb6c11d5599a0af0a13cff4c14958c0f9..c14e80095bb929469b2a938023228fb12d18303e 100644 (file)
@@ -74,33 +74,81 @@ let {{
 }};
 
 def format MultiOp(code, switchVal, opTags, *opt_flags) {{
-    # Loads and stores that bring in and write out values from the
-    # instructions. These are determined by the input and output tags,
-    # and the resulting instruction will have the right number of micro ops,
-    # or could be implemented as an atomic macro op.
-    instNames = []
+    # These are C++ statements to create each type of static int. Since we
+    # don't know what will be microcoded and what won't, we can't assume a
+    # particular set of arguments for the constructor.
+    instNew = []
+    orig_code = code
+    opRe = re.compile(r"%(?P<operandNum>[0-9]*)")
+    # Get all the labels out of the code and make a dict for them. We'll do
+    # this once since the position of labels shouldn't need to change at all.
+    ops = assembleMicro(code)
+    labels = buildLabelDict(ops)
     for tagSet in opTags:
-        loads = []
-        stores = []
+        # A list of strings which either have the register number to use, or
+        # a piece of code for calculating it.
+        regNums = []
+        code = orig_code
+        # Build up a name for this instructions class using the argument
+        # types. Each variation will get its own name this way.
         postfix = ''
         for tag in tagSet:
             postfix += '_' + tag
-        gather_inputs = ''
-        if len(loads) + len(stores) == 0:
-            # If there are no loads or stores, make this a single instruction.
-            iop = InstObjParams(name, Name + postfix, 'X86StaticInst',
-                    {"code": code, "gather_inputs": gather_inputs},
-                    opt_flags)
+
+        # Figure out what register indexes to use for each operand. This
+        # is where loads/stores could be set up. I need to distinguish
+        # between inputs and outputs.
+        # For right now, the indexes are just an increasing sequence
+        counter = 0
+        for tag in tagSet:
+            regNums.append("%d" % counter)
+            counter += 1
+
+        # Replace the placeholders %0, %1, etc., with the right register
+        # indexes.
+        opMatch = opRe.search(code)
+        while opMatch:
+            opNum = opMatch.group("operandNum")
+            opNum = int(opNum)
+            if opNum > len(regNums):
+                print "No operand type specified for operand %d!" % opNum
+                print "I should bail out here too!"
+            regNum = regNums[opNum]
+            code = opRe.sub(regNum, code, 1)
+            opMatch = opRe.search(code)
+
+        # All the loads which feed this instruction
+        loads = []
+        # All the ops that make up the instruction proper.
+        ops = assembleMicro(code)
+        # Get all the labels out and make a dict for them
+        # All the stores for this instruction's results
+        stores = []
+
+        # Various counts
+        numLoads = len(loads)
+        numOps = len(ops)
+        numStores = len(stores)
+        totalOps = numLoads + numOps + numStores
+        print "There are %d total ops" % totalOps
+
+        # If we can implement this instruction with exactly one microop, just
+        # use that directly.
+        newStmnt = ''
+        if totalOps == 1:
+            newStmnt = ops[0].getAllocator(labels)
         else:
             # Build up a macro op. We'll punt on this for now
             pass
 
+        instNew.append(newStmnt)
+
     decodeBlob = 'switch(%s) {\n' % switchVal
     counter = 0
-    for inst in instNames:
-        decodeBlob += '%d: return (X86StaticInst *)(new %s(machInst));\n' % \
-                      (counter, inst)
+    for newStmnt in instNew:
+        decodeBlob += 'case %d: return (X86StaticInst *)(%s);\n' % \
+                      (counter, newStmnt)
         counter += 1
     decodeBlob += '}\n'
-    # decode_block = BasicDecodeWithMnemonic.subst(iop)
+    decode_block = decodeBlob
 }};