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/013direct_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/013direct_addressing.cc')
-rw-r--r-- | subx/013direct_addressing.cc | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc index 7b3997f6..d4dcd92a 100644 --- a/subx/013direct_addressing.cc +++ b/subx/013direct_addressing.cc @@ -27,9 +27,9 @@ case 0x01: { // add r32 to r/m32 trace(Callstack_depth+1, "run") << "add " << rname(arg2) << " to r/m32" << end(); int32_t* signed_arg1 = effective_address(modrm); int32_t signed_result = *signed_arg1 + Reg[arg2].i; - int64_t signed_full_result = static_cast<int64_t>(*signed_arg1) + Reg[arg2].i; SF = (signed_result < 0); ZF = (signed_result == 0); + int64_t signed_full_result = static_cast<int64_t>(*signed_arg1) + Reg[arg2].i; OF = (signed_result != signed_full_result); // set CF uint32_t unsigned_arg1 = static_cast<uint32_t>(*signed_arg1); @@ -176,9 +176,9 @@ case 0x29: { // subtract r32 from r/m32 trace(Callstack_depth+1, "run") << "subtract " << rname(arg2) << " from r/m32" << end(); int32_t* signed_arg1 = effective_address(modrm); int32_t signed_result = *signed_arg1 - Reg[arg2].i; - int64_t signed_full_result = static_cast<int64_t>(*signed_arg1) - Reg[arg2].i; SF = (signed_result < 0); ZF = (signed_result == 0); + int64_t signed_full_result = static_cast<int64_t>(*signed_arg1) - Reg[arg2].i; OF = (signed_result != signed_full_result); // set CF uint32_t unsigned_arg1 = static_cast<uint32_t>(*signed_arg1); @@ -275,7 +275,7 @@ case 0xf7: { switch (subop) { case 4: { // mul unsigned EAX by r/m32 trace(Callstack_depth+1, "run") << "subop: multiply EAX by r/m32" << end(); - const uint64_t result = Reg[EAX].u * static_cast<uint32_t>(*arg1); + const uint64_t result = static_cast<uint64_t>(Reg[EAX].u) * static_cast<uint32_t>(*arg1); Reg[EAX].u = result & 0xffffffff; Reg[EDX].u = result >> 32; OF = (Reg[EDX].u != 0); @@ -318,14 +318,15 @@ case 0xaf: { // multiply r32 by r/m32 const uint8_t arg1 = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "multiply " << rname(arg1) << " by r/m32" << end(); const int32_t* arg2 = effective_address(modrm); - int64_t full_result = Reg[arg1].i * (*arg2); - Reg[arg1].i *= (*arg2); - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[arg1].i << end(); + int32_t result = Reg[arg1].i * (*arg2); SF = (Reg[arg1].i < 0); ZF = (Reg[arg1].i == 0); + int64_t full_result = static_cast<int64_t>(Reg[arg1].i) * (*arg2); OF = (Reg[arg1].i != full_result); CF = OF; trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + Reg[arg1].i = result; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[arg1].i << end(); break; } |