about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--subx/013direct_addressing.cc28
-rw-r--r--subx/015immediate_addressing.cc10
2 files changed, 27 insertions, 11 deletions
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc
index 3f7d40d6..9c314b02 100644
--- a/subx/013direct_addressing.cc
+++ b/subx/013direct_addressing.cc
@@ -279,6 +279,8 @@ case 0xf7: {
     Reg[EAX].u = result & 0xffffffff;
     Reg[EDX].u = result >> 32;
     OF = (Reg[EDX].u != 0);
+    CF = OF;
+    trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end();
     trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[EAX].u << end();
     break;
   }
@@ -360,11 +362,14 @@ case 3: {  // negate r/m32
     OF = true;
     break;
   }
-  *arg1 = -(*arg1);
-  trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
-  SF = (*arg1 >> 31);
-  ZF = (*arg1 == 0);
+  int32_t result = -(*arg1);
+  SF = (result >> 31);
+  ZF = (result == 0);
   OF = false;
+  CF = (*arg1 != 0);
+  trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end();
+  *arg1 = result;
+  trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
   break;
 }
 
@@ -518,9 +523,12 @@ case 0xd3: {
       bool pnsb = (*arg1 & 0x40000000);
       OF = (msb != pnsb);
     }
-    *arg1 = (*arg1 << count);
-    ZF = (*arg1 == 0);
-    SF = (*arg1 < 0);
+    int32_t result = (*arg1 << count);
+    ZF = (result == 0);
+    SF = (result < 0);
+    CF = (*arg1 << (count-1)) & 0x80000000;
+    trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end();
+    *arg1 = result;
     trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
     break;
   }
@@ -561,6 +569,7 @@ case 7: {  // shift right r/m32 by CL, preserving sign
   SF = (*arg1 < 0);
   // OF is only defined if count is 1
   if (count == 1) OF = false;
+  // CF undefined
   trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
   break;
 }
@@ -638,6 +647,7 @@ case 5: {  // shift right r/m32 by CL, padding zeroes
   ZF = (*uarg1 == 0);
   // result is always positive by definition
   SF = false;
+  // CF undefined
   trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
   break;
 }
@@ -822,9 +832,7 @@ case 2: {  // not r/m32
   trace(Callstack_depth+1, "run") << "subop: not" << end();
   *arg1 = ~(*arg1);
   trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
-  SF = (*arg1 >> 31);
-  ZF = (*arg1 == 0);
-  OF = false;
+  // no flags affected
   break;
 }
 
diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc
index bfedac21..478e3592 100644
--- a/subx/015immediate_addressing.cc
+++ b/subx/015immediate_addressing.cc
@@ -449,6 +449,8 @@ case 0xc1: {
     *arg1 = (*arg1 << count);
     ZF = (*arg1 == 0);
     SF = (*arg1 < 0);
+    // CF undefined
+    trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end();
     trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
     break;
   }
@@ -483,11 +485,15 @@ void test_shift_right_arithmetic_r32_with_imm8() {
 case 7: {  // shift right r/m32 by CL, preserving sign
   trace(Callstack_depth+1, "run") << "subop: shift right by CL bits, while preserving sign" << end();
   uint8_t count = next() & 0x1f;
-  *arg1 = (*arg1 >> count);
+  int32_t result = (*arg1 >> count);
   ZF = (*arg1 == 0);
   SF = (*arg1 < 0);
   // OF is only defined if count is 1
   if (count == 1) OF = false;
+  // CF
+  CF = ((*arg1 >> (count-1)) & 0x1);
+  trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end();
+  *arg1 = result;
   trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
   break;
 }
@@ -562,6 +568,8 @@ case 5: {  // shift right r/m32 by CL, preserving sign
   ZF = (*uarg1 == 0);
   // result is always positive by definition
   SF = false;
+  // CF undefined
+  trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end();
   trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end();
   break;
 }