X86: Make logic instructions flag setting work.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 29 Jul 2007 20:51:40 +0000 (13:51 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 29 Jul 2007 20:51:40 +0000 (13:51 -0700)
The instructions now ask for the appropriate flags to be set, and the microops do the "right thing" with the CF and OF flags, namely zero them.

--HG--
extra : convert_revision : 85138a832f44c879bf8a11bd3a35b58be6272ef3

src/arch/x86/isa/insts/logical.py
src/arch/x86/isa/microops/regop.isa

index bbc15f8faf51d043a8d6160bae0ad50b030444e1..81a4730def474424b36d8b01da75ae80efb339ac 100644 (file)
 microcode = '''
 def macroop OR_R_R
 {
-    or reg, reg, regm
+    or reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop OR_M_I
 {
     limm t2, imm
     ld t1, ds, [scale, index, base], disp
-    or t1, t1, t2
+    or t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
@@ -72,14 +72,14 @@ def macroop OR_P_I
     limm t2, imm
     rdip t7
     ld t1, ds, [0, t0, t7], disp
-    or t1, t1, t2
+    or t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [0, t0, t7], disp
 };
 
 def macroop OR_M_R
 {
     ld t1, ds, [scale, index, base], disp
-    or t1, t1, reg
+    or t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
@@ -87,45 +87,45 @@ def macroop OR_P_R
 {
     rdip t7
     ld t1, ds, [0, t0, t7], disp
-    or t1, t1, reg
+    or t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [0, t0, t7], disp
 };
 
 def macroop OR_R_M
 {
     ld t1, ds, [scale, index, base], disp
-    or reg, reg, t1
+    or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop OR_R_P
 {
     rdip t7
     ld t1, ds, [0, t0, t7], disp
-    or reg, reg, t1
+    or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop OR_R_I
 {
     limm t1, imm
-    or reg, reg, t1
+    or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop XOR_R_R
 {
-    xor reg, reg, regm
+    xor reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop XOR_R_I
 {
     limm t1, imm
-    xor reg, reg, t1
+    xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop XOR_M_I
 {
     limm t2, imm
     ld t1, ds, [scale, index, base], disp
-    xor t1, t1, t2
+    xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
@@ -134,14 +134,14 @@ def macroop XOR_P_I
     limm t2, imm
     rdip t7
     ld t1, ds, [scale, index, base], disp
-    xor t1, t1, t2
+    xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
 def macroop XOR_M_R
 {
     ld t1, ds, [scale, index, base], disp
-    xor t1, t1, reg
+    xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
@@ -149,52 +149,52 @@ def macroop XOR_P_R
 {
     rdip t7
     ld t1, ds, [scale, index, base], disp
-    xor t1, t1, reg
+    xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
 def macroop XOR_R_M
 {
     ld t1, ds, [scale, index, base], disp
-    xor reg, reg, t1
+    xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop XOR_R_P
 {
     rdip t7
     ld t1, ds, [scale, index, base], disp
-    xor reg, reg, t1
+    xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop AND_R_R
 {
-    and reg, reg, regm
+    and reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop AND_R_M
 {
     ld t1, ds, [scale, index, base], disp
-    and reg, reg, t1
+    and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop AND_R_P
 {
     rdip t7
     ld t1, ds, [scale, index, base], disp
-    and reg, reg, t1
+    and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop AND_R_I
 {
     limm t1, imm
-    and reg, reg, t1
+    and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
 def macroop AND_M_I
 {
     ld t2, ds, [scale, index, base], disp
     limm t1, imm
-    and t2, t2, t1
+    and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
     st t2, ds, [scale, index, base], disp
 };
 
@@ -203,14 +203,14 @@ def macroop AND_P_I
     rdip t7
     ld t2, ds, [scale, index, base], disp
     limm t1, imm
-    and t2, t2, t1
+    and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
     st t2, ds, [scale, index, base], disp
 };
 
 def macroop AND_M_R
 {
     ld t1, ds, [scale, index, base], disp
-    and t1, t1, reg
+    and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
@@ -218,7 +218,7 @@ def macroop AND_P_R
 {
     rdip t7
     ld t1, ds, [scale, index, base], disp
-    and t1, t1, reg
+    and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
 
index bb34df7dfffb0fbdc60635955b5f018ecc36c287..af3ee869ba11346ed5ce939cd0fd894e89db5f1a 100644 (file)
@@ -326,12 +326,24 @@ let {{
 
 
     checkCCFlagBits = "checkCondition(ccFlagBits)"
-    genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
+    genCCFlagBits = \
+        "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, op2);"
+    genCCFlagBitsSub = \
+        "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, ~op2, true);"
+    genCCFlagBitsLogic = '''
+        //Don't have genFlags handle the OF or CF bits
+        uint64_t mask = CFBit | OFBit;
+        ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, SrcReg1, op2);
+        //If a logic microop wants to set these, it wants to set them to 0.
+        ccFlagBits &= ~(CFBit & ext);
+        ccFlagBits &= ~(OFBit & ext);
+    '''
 
 
     # 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, subtract = False, cc=False, elseCode=";"):
+    def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
+            cc=False, elseCode=";"):
         Name = mnemonic
         name = mnemonic.lower()
 
@@ -342,13 +354,7 @@ let {{
         regCode = matcher.sub("SrcReg2", code)
         immCode = matcher.sub("imm8", code)
 
-        if subtract:
-            secondSrc = "~op2, true"
-        else:
-            secondSrc = "op2"
-
         if not cc:
-            flagCode = genCCFlagBits % secondSrc
             condCode = "true"
         else:
             flagCode = ""
@@ -360,26 +366,30 @@ let {{
         class RegOpChild(RegOp):
             mnemonic = name
             className = Name
-            def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
-                super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize)
+            def __init__(self, dest, src1, src2, \
+                    flags=None, dataSize="env.dataSize"):
+                super(RegOpChild, self).__init__(dest, src1, src2, \
+                        flags, dataSize)
 
         microopClasses[name] = RegOpChild
 
         setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
         setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
-                flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
+                flagCode=regFlagCode, condCheck=condCode, elseCode=elseCode);
 
         class RegOpChildImm(RegOpImm):
             mnemonic = name + 'i'
             className = Name + 'Imm'
-            def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
-                super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize)
+            def __init__(self, dest, src1, src2, \
+                    flags=None, dataSize="env.dataSize"):
+                super(RegOpChildImm, self).__init__(dest, src1, src2, \
+                        flags, dataSize)
 
         microopClasses[name + 'i'] = RegOpChildImm
 
         setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
         setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
-                flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
+                flagCode=immFlagCode, condCheck=condCode, elseCode=elseCode);
 
     # This has it's own function because Wr ops have implicit destinations
     def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
@@ -447,7 +457,8 @@ let {{
         setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
 
     defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
-    defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
+    defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)',
+            flagCode = genCCFlagBitsLogic)
     defineMicroRegOp('Adc', '''
             CCFlagBits flags = ccFlagBits;
             DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
@@ -455,12 +466,18 @@ let {{
     defineMicroRegOp('Sbb', '''
             CCFlagBits flags = ccFlagBits;
             DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
-            ''', True)
-    defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
-    defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
-    defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
-    # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
-    defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
+            ''', flagCode = genCCFlagBitsSub)
+    defineMicroRegOp('And', \
+            'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', \
+            flagCode = genCCFlagBitsLogic)
+    defineMicroRegOp('Sub', \
+            'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', \
+            flagCode = genCCFlagBitsSub)
+    defineMicroRegOp('Xor', \
+            'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', \
+            flagCode = genCCFlagBitsLogic)
+    defineMicroRegOp('Mul1s', \
+            'DestReg = merge(DestReg, DestReg * op2, dataSize)')
     defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
             elseCode='DestReg=DestReg;', cc=True)