Make instructions that conditionally set registers set them to their old value if...
authorGabe Black <gblack@eecs.umich.edu>
Thu, 19 Jul 2007 00:46:38 +0000 (17:46 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 19 Jul 2007 00:46:38 +0000 (17:46 -0700)
--HG--
extra : convert_revision : 36e63dd0c6ac1a3e1133c7985cf5507b83e9ee45

src/arch/x86/isa/microops/regop.isa

index d36fcb773dc4311239718d37a3b967c7d85f19e4..37cbaa8c66fbf6fbccb065c567f563ff0b5915b6 100644 (file)
@@ -73,6 +73,10 @@ def template MicroRegOpExecute {{
                 %(code)s;
                 %(flag_code)s;
             }
+            else
+            {
+                %(else_code)s;
+            }
 
             //Write the resulting state to the execution context
             if(fault == NoFault)
@@ -97,6 +101,10 @@ def template MicroRegOpImmExecute {{
                 %(code)s;
                 %(flag_code)s;
             }
+            else
+            {
+                %(else_code)s;
+            }
 
             //Write the resulting state to the execution context
             if(fault == NoFault)
@@ -301,7 +309,7 @@ let {{
     exec_output = ""
 
     # A function which builds the C++ classes that implement the microops
-    def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck):
+    def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck, elseCode):
         global header_output
         global decoder_output
         global exec_output
@@ -310,7 +318,8 @@ let {{
         iop = InstObjParams(name, Name, base,
                 {"code" : code,
                  "flag_code" : flagCode,
-                 "cond_check" : condCheck})
+                 "cond_check" : condCheck,
+                 "else_code" : elseCode})
         header_output += MicroRegOpDeclare.subst(iop)
         decoder_output += MicroRegOpConstructor.subst(iop)
         exec_output += MicroRegOpExecute.subst(iop)
@@ -322,7 +331,7 @@ let {{
 
     # This creates a python representations of a microop which are a cross
     # product of reg/immediate and flag/no flag versions.
-    def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False):
+    def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False, elseCode=";"):
         Name = mnemonic
         name = mnemonic.lower()
 
@@ -351,8 +360,8 @@ let {{
 
         microopClasses[name] = RegOpChild
 
-        setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true");
-        setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode);
+        setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true", elseCode);
+        setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode, elseCode);
 
         class RegOpChildImm(RegOpImm):
             mnemonic = name + 'i'
@@ -362,8 +371,8 @@ let {{
 
         microopClasses[name + 'i'] = RegOpChildImm
 
-        setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true");
-        setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode);
+        setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true", elseCode);
+        setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode, elseCode);
 
     defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
     defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
@@ -373,10 +382,11 @@ let {{
     defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2')
     defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
     defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', '-op2')
-    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', cc=True)
+    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
+            elseCode='DestReg=DestReg;', cc=True)
 
     # This has it's own function because Wr ops have implicit destinations
-    def defineMicroRegOpWr(mnemonic, code):
+    def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
         Name = mnemonic
         name = mnemonic.lower()
 
@@ -395,21 +405,21 @@ let {{
 
         microopClasses[name] = RegOpChild
 
-        setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true");
-        setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits);
+        setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true", elseCode);
+        setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits, elseCode);
 
         class RegOpChildImm(RegOpImm):
-            mnemonic = name
-            className = Name
+            mnemonic = name + 'i'
+            className = Name + 'Imm'
             def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
                 super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
 
         microopClasses[name + 'i'] = RegOpChildImm
 
-        setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true");
-        setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits);
+        setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true", elseCode);
+        setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits, elseCode);
 
-    defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
+    defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
 
     # This has it's own function because Rd ops don't always have two parameters
     def defineMicroRegOpRd(mnemonic, code):
@@ -424,7 +434,7 @@ let {{
 
         microopClasses[name] = RegOpChild
 
-        setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true");
+        setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true", ";");
 
     defineMicroRegOpRd('Rdip', 'DestReg = RIP')
 
@@ -440,7 +450,7 @@ let {{
 
         microopClasses[name] = RegOpChild
 
-        setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true");
+        setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true", ";");
 
     defineMicroRegOpImm('Sext', '''
             IntReg val = SrcReg1;