diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-05-13 10:54:42 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-05-13 10:54:42 -0700 |
commit | 40f4f1b454a3510c35dfa41db1dff323793ec895 (patch) | |
tree | 27543d94ec167d626bcc071671d6e95fe063abb3 /subx/015immediate_addressing.cc | |
parent | 97ef7c4362b40609ec1c4881d2dedc58a9f12c41 (diff) | |
download | mu-40f4f1b454a3510c35dfa41db1dff323793ec895.tar.gz |
.
Standardize layout of some code fragments, and fix several bugs in computing the overflow flag in the process. a64 = b32 + c32 doesn't benefit from `a` being 64-bit without casting `b`.
Diffstat (limited to 'subx/015immediate_addressing.cc')
-rw-r--r-- | subx/015immediate_addressing.cc | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index f4762c2b..7abf7951 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -7,19 +7,19 @@ put_new(Name, "05", "add imm32 to EAX (add)"); case 0x05: { // add imm32 to EAX int32_t signed_arg2 = next32(); trace(Callstack_depth+1, "run") << "add imm32 0x" << HEXWORD << signed_arg2 << " to reg EAX" << end(); - int64_t signed_full_result = Reg[EAX].i + signed_arg2; - Reg[EAX].i += signed_arg2; - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[EAX].i << end(); - SF = (Reg[EAX].i < 0); - ZF = (Reg[EAX].i == 0); - OF = (Reg[EAX].i != signed_full_result); + int32_t signed_result = Reg[EAX].i + signed_arg2; + SF = (signed_result < 0); + ZF = (signed_result == 0); + int64_t signed_full_result = static_cast<int64_t>(Reg[EAX].i) + signed_arg2; + OF = (signed_result != signed_full_result); // set CF - uint32_t unsigned_arg1 = static_cast<uint32_t>(Reg[EAX].i); uint32_t unsigned_arg2 = static_cast<uint32_t>(signed_arg2); - uint32_t unsigned_result = unsigned_arg1 + unsigned_arg2; - uint64_t unsigned_full_result = unsigned_arg1 + unsigned_arg2; + uint32_t unsigned_result = Reg[EAX].u + unsigned_arg2; + uint64_t unsigned_full_result = static_cast<uint64_t>(Reg[EAX].u) + unsigned_arg2; CF = (unsigned_result != unsigned_full_result); trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + Reg[EAX].i = signed_result; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[EAX].i << end(); break; } @@ -55,19 +55,20 @@ case 0x81: { // combine imm32 with r/m32 switch (subop) { case 0: { trace(Callstack_depth+1, "run") << "subop add" << end(); - int64_t signed_full_result = *signed_arg1 + signed_arg2; - *signed_arg1 += signed_arg2; - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *signed_arg1 << end(); - SF = (*signed_arg1 < 0); - ZF = (*signed_arg1 == 0); - OF = (*signed_arg1 != signed_full_result); + int32_t signed_result = *signed_arg1 + signed_arg2; + SF = (signed_result < 0); + ZF = (signed_result == 0); + int64_t signed_full_result = static_cast<int64_t>(*signed_arg1) + signed_arg2; + OF = (signed_result != signed_full_result); // set CF uint32_t unsigned_arg1 = static_cast<uint32_t>(*signed_arg1); uint32_t unsigned_arg2 = static_cast<uint32_t>(signed_arg2); uint32_t unsigned_result = unsigned_arg1 + unsigned_arg2; - uint64_t unsigned_full_result = unsigned_arg1 + unsigned_arg2; + uint64_t unsigned_full_result = static_cast<uint64_t>(unsigned_arg1) + unsigned_arg2; CF = (unsigned_result != unsigned_full_result); trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *signed_arg1 = signed_result; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *signed_arg1 << end(); break; } // End Op 81 Subops @@ -163,19 +164,20 @@ void test_subtract_imm32_from_mem_at_r32() { :(before "End Op 81 Subops") case 5: { trace(Callstack_depth+1, "run") << "subop subtract" << end(); - int64_t signed_full_result = *signed_arg1 - signed_arg2; - *signed_arg1 -= signed_arg2; - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *signed_arg1 << end(); - SF = (*signed_arg1 < 0); - ZF = (*signed_arg1 == 0); - OF = (*signed_arg1 != signed_full_result); + int32_t signed_result = *signed_arg1 - signed_arg2; + SF = (signed_result < 0); + ZF = (signed_result == 0); + int64_t signed_full_result = static_cast<int64_t>(*signed_arg1) - signed_arg2; + OF = (signed_result != signed_full_result); // set CF uint32_t unsigned_arg1 = static_cast<uint32_t>(*signed_arg1); uint32_t unsigned_arg2 = static_cast<uint32_t>(signed_arg2); uint32_t unsigned_result = unsigned_arg1 - unsigned_arg2; - uint64_t unsigned_full_result = unsigned_arg1 - unsigned_arg2; + uint64_t unsigned_full_result = static_cast<uint64_t>(unsigned_arg1) - unsigned_arg2; CF = (unsigned_result != unsigned_full_result); trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *signed_arg1 = signed_result; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *signed_arg1 << end(); break; } @@ -674,10 +676,10 @@ void test_compare_imm32_with_eax_greater() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 3d 07 0b 0c 0d \n" // compare 0x0d0c0b07 with EAX + " 3d 07 0b 0c 0d \n" // compare EAX with 0x0d0c0b07 ); CHECK_TRACE_CONTENTS( - "run: compare EAX and imm32 0x0d0c0b07\n" + "run: compare EAX with imm32 0x0d0c0b07\n" "run: SF=0; ZF=0; CF=0; OF=0\n" ); } @@ -686,36 +688,35 @@ void test_compare_imm32_with_eax_greater() { case 0x3d: { // compare EAX with imm32 const int32_t signed_arg1 = Reg[EAX].i; const int32_t signed_arg2 = next32(); - trace(Callstack_depth+1, "run") << "compare EAX and imm32 0x" << HEXWORD << signed_arg2 << end(); + trace(Callstack_depth+1, "run") << "compare EAX with imm32 0x" << HEXWORD << signed_arg2 << end(); const int32_t signed_difference = signed_arg1 - signed_arg2; SF = (signed_difference < 0); ZF = (signed_difference == 0); - const int64_t full_signed_difference = signed_arg1 - signed_arg2; + const int64_t full_signed_difference = static_cast<int64_t>(signed_arg1) - signed_arg2; OF = (signed_difference != full_signed_difference); const uint32_t unsigned_arg1 = static_cast<uint32_t>(signed_arg1); const uint32_t unsigned_arg2 = static_cast<uint32_t>(signed_arg2); const uint32_t unsigned_difference = unsigned_arg1 - unsigned_arg2; - const uint64_t full_unsigned_difference = unsigned_arg1 - unsigned_arg2; + const uint64_t full_unsigned_difference = static_cast<uint64_t>(unsigned_arg1) - unsigned_arg2; CF = (unsigned_difference != full_unsigned_difference); trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); break; } :(code) -void test_compare_imm32_with_eax_lesser() { +void test_compare_eax_with_imm32_lesser() { Reg[EAX].i = 0x0d0c0b07; run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 3d 0a 0b 0c 0d \n" // compare 0x0d0c0b0a with EAX + " 3d 0a 0b 0c 0d \n" // compare EAX with 0x0d0c0b0a ); CHECK_TRACE_CONTENTS( - "run: compare EAX and imm32 0x0d0c0b0a\n" - "run: SF=1; ZF=0; CF=0; OF=0\n" + "run: compare EAX with imm32 0x0d0c0b0a\n" + "run: SF=1; ZF=0; CF=1; OF=0\n" ); } -:(code) void test_compare_imm32_with_eax_equal() { Reg[EAX].i = 0x0d0c0b0a; run( @@ -724,14 +725,13 @@ void test_compare_imm32_with_eax_equal() { " 3d 0a 0b 0c 0d \n" // compare 0x0d0c0b0a with EAX ); CHECK_TRACE_CONTENTS( - "run: compare EAX and imm32 0x0d0c0b0a\n" + "run: compare EAX with imm32 0x0d0c0b0a\n" "run: SF=0; ZF=1; CF=0; OF=0\n" ); } //: -:(code) void test_compare_imm32_with_r32_greater() { Reg[EBX].i = 0x0d0c0b0a; run( @@ -754,7 +754,7 @@ case 7: { const int32_t tmp1 = *signed_arg1 - signed_arg2; SF = (tmp1 < 0); ZF = (tmp1 == 0); - const int64_t tmp2 = *signed_arg1 - signed_arg2; + const int64_t tmp2 = static_cast<int64_t>(*signed_arg1) - signed_arg2; OF = (tmp1 != tmp2); trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); break; |