X86: Fix condition code setting for signed multiplies with negative results.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 5 Aug 2009 10:07:01 +0000 (03:07 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 5 Aug 2009 10:07:01 +0000 (03:07 -0700)
src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
src/arch/x86/isa/microops/regop.isa

index edb5645529904f39be715e808bc5eaa1b35b4225..dbc803350b4a0bce6a25a5609f0264652e3c30b6 100644 (file)
@@ -61,26 +61,26 @@ microcode = '''
 
 def macroop MUL_B_R
 {
-    mul1u rax, reg
+    mul1u rax, reg, flags=(OF,CF)
     mulel rax
-    muleh ah, flags=(OF,CF)
+    muleh ah
 };
 
 def macroop MUL_B_M
 {
     ld t1, seg, sib, disp
-    mul1u rax, t1
+    mul1u rax, t1, flags=(OF,CF)
     mulel rax
-    muleh ah, flags=(OF,CF)
+    muleh ah
 };
 
 def macroop MUL_B_P
 {
     rdip t7
     ld t1, seg, riprel, disp
-    mul1u rax, t1
+    mul1u rax, t1, flags=(OF,CF)
     mulel rax
-    muleh ah, flags=(OF,CF)
+    muleh ah
 };
 
 #
@@ -89,26 +89,26 @@ def macroop MUL_B_P
 
 def macroop MUL_R
 {
-    mul1u rax, reg
+    mul1u rax, reg, flags=(OF,CF)
     mulel rax
-    muleh rdx, flags=(OF,CF)
+    muleh rdx
 };
 
 def macroop MUL_M
 {
     ld t1, seg, sib, disp
-    mul1u rax, t1
+    mul1u rax, t1, flags=(OF,CF)
     mulel rax
-    muleh rdx, flags=(OF,CF)
+    muleh rdx
 };
 
 def macroop MUL_P
 {
     rdip t7
     ld t1, seg, riprel, disp
-    mul1u rax, t1
+    mul1u rax, t1, flags=(OF,CF)
     mulel rax
-    muleh rdx, flags=(OF,CF)
+    muleh rdx
 };
 
 #
@@ -117,26 +117,26 @@ def macroop MUL_P
 
 def macroop IMUL_B_R
 {
-    mul1s rax, reg
+    mul1s rax, reg, flags=(OF,CF)
     mulel rax
-    muleh ah, flags=(OF,CF)
+    muleh ah
 };
 
 def macroop IMUL_B_M
 {
     ld t1, seg, sib, disp
-    mul1s rax, t1
+    mul1s rax, t1, flags=(OF,CF)
     mulel rax
-    muleh ah, flags=(OF,CF)
+    muleh ah
 };
 
 def macroop IMUL_B_P
 {
     rdip t7
     ld t1, seg, riprel, disp
-    mul1s rax, t1
+    mul1s rax, t1, flags=(OF,CF)
     mulel rax
-    muleh ah, flags=(OF,CF)
+    muleh ah
 };
 
 #
@@ -145,50 +145,50 @@ def macroop IMUL_B_P
 
 def macroop IMUL_R
 {
-    mul1s rax, reg
+    mul1s rax, reg, flags=(OF,CF)
     mulel rax
-    muleh rdx, flags=(OF,CF)
+    muleh rdx
 };
 
 def macroop IMUL_M
 {
     ld t1, seg, sib, disp
-    mul1s rax, t1
+    mul1s rax, t1, flags=(OF,CF)
     mulel rax
-    muleh rdx, flags=(OF,CF)
+    muleh rdx
 };
 
 def macroop IMUL_P
 {
     rdip t7
     ld t1, seg, riprel, disp
-    mul1s rax, t1
+    mul1s rax, t1, flags=(OF,CF)
     mulel rax
-    muleh rdx, flags=(OF,CF)
+    muleh rdx
 };
 
 def macroop IMUL_R_R
 {
-    mul1s reg, regm
+    mul1s reg, regm, flags=(OF,CF)
     mulel reg
-    muleh t0, flags=(CF,OF)
+    muleh t0
 };
 
 def macroop IMUL_R_M
 {
     ld t1, seg, sib, disp
-    mul1s reg, t1
+    mul1s reg, t1, flags=(CF,OF)
     mulel reg
-    muleh t0, flags=(CF,OF)
+    muleh t0
 };
 
 def macroop IMUL_R_P
 {
     rdip t7
     ld t1, seg, riprel, disp
-    mul1s reg, t1
+    mul1s reg, t1, flags=(CF,OF)
     mulel reg
-    muleh t0, flags=(CF,OF)
+    muleh t0
 };
 
 #
@@ -198,18 +198,18 @@ def macroop IMUL_R_P
 def macroop IMUL_R_R_I
 {
     limm t1, imm
-    mul1s regm, t1
+    mul1s regm, t1, flags=(OF,CF)
     mulel reg
-    muleh t0, flags=(OF,CF)
+    muleh t0
 };
 
 def macroop IMUL_R_M_I
 {
     limm t1, imm
     ld t2, seg, sib, disp
-    mul1s t2, t1
+    mul1s t2, t1, flags=(OF,CF)
     mulel reg
-    muleh t0, flags=(OF,CF)
+    muleh t0
 };
 
 def macroop IMUL_R_P_I
@@ -217,9 +217,9 @@ def macroop IMUL_R_P_I
     rdip t7
     limm t1, imm
     ld t2, seg, riprel
-    mul1s t2, t1
+    mul1s t2, t1, flags=(OF,CF)
     mulel reg
-    muleh t0, flags=(OF,CF)
+    muleh t0
 };
 
 #
index f2e16a515a09e16de330609b0400d884b6cb892b..6921684a43f1a2cfb31a63897bc0072a85c0b744 100644 (file)
@@ -536,6 +536,14 @@ let {{
                 hiResult -= psrc1;
             ProdHi = hiResult;
             '''
+        flag_code = '''
+            if ((-ProdHi & mask(dataSize * 8)) !=
+                    bits(ProdLow, dataSize * 8 - 1)) {
+                ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit));
+            } else {
+                ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit));
+            }
+        '''
 
     class Mul1u(WrRegOp):
         code = '''
@@ -550,6 +558,13 @@ let {{
                       ((psrc1_l * psrc2_l) / shifter)) / shifter) +
                      psrc1_h * psrc2_h;
             '''
+        flag_code = '''
+            if (ProdHi) {
+                ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit));
+            } else {
+                ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit));
+            }
+        '''
 
     class Mulel(RdRegOp):
         code = 'DestReg = merge(SrcReg1, ProdLow, dataSize);'
@@ -561,12 +576,6 @@ let {{
             super(RdRegOp, self).__init__(dest, src1, \
                     "InstRegIndex(NUM_INTREGS)", flags, dataSize)
         code = 'DestReg = merge(SrcReg1, ProdHi, dataSize);'
-        flag_code = '''
-            if (ProdHi)
-                ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit));
-            else
-                ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit));
-        '''
 
     # One or two bit divide
     class Div1(WrRegOp):