diff options
Diffstat (limited to 'subx/013direct_addressing.cc')
-rw-r--r-- | subx/013direct_addressing.cc | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc index 2914e0dd..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; } @@ -338,7 +340,7 @@ void test_negate_r32() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " f7 db \n" // negate EBX + " f7 db \n" // negate EBX // ModR/M in binary: 11 (direct mode) 011 (subop negate) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( @@ -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; } @@ -375,7 +380,7 @@ void test_negate_can_overflow() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " f7 db \n" // negate EBX + " f7 db \n" // negate EBX // ModR/M in binary: 11 (direct mode) 011 (subop negate) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( @@ -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; } |