diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-10-23 23:19:55 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-10-23 23:19:55 -0700 |
commit | d27812594a85cbf6002cbe9e617b241eb00eedc1 (patch) | |
tree | 7acc6ae3d29428d2f7a7beb7c83be7c7275a33c4 | |
parent | bfc997cfdae6a043bfd01ffd6dc3c0b2214d108f (diff) | |
download | mu-d27812594a85cbf6002cbe9e617b241eb00eedc1.tar.gz |
4715 - support one more negation instruction
-rw-r--r-- | subx/013direct_addressing.cc | 47 | ||||
-rw-r--r-- | subx/014indirect_addressing.cc | 2 |
2 files changed, 48 insertions, 1 deletions
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc index bf736e01..8cf033bd 100644 --- a/subx/013direct_addressing.cc +++ b/subx/013direct_addressing.cc @@ -166,6 +166,49 @@ case 0xaf: { // multiply r32 into r/m32 break; } +//:: negate + +:(scenario negate_r32) +% Reg[EBX].i = 1; +== 0x1 +# op ModR/M SIB displacement immediate + f7 db # negate EBX +# ModR/M in binary: 11 (direct mode) 011 (subop negate) 011 (dest EBX) ++run: operate on r/m32 ++run: r/m32 is EBX ++run: subop: negate ++run: storing 0xffffffff + +:(before "End Op f7 Subops") +case 3: { // negate r/m32 + trace(90, "run") << "subop: negate" << end(); + // one case that can overflow + if (static_cast<uint32_t>(*arg1) == 0x80000000) { + trace(90, "run") << "overflow" << end(); + SF = true; + ZF = false; + OF = true; + break; + } + *arg1 = -(*arg1); + trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); + SF = (*arg1 >> 31); + ZF = (*arg1 == 0); + OF = false; + break; +} + +:(scenario negate_can_overflow) // in exactly one situation +% Reg[EBX].i = 0x80000000; // INT_MIN +== 0x1 +# op ModR/M SIB displacement immediate + f7 db # negate EBX +# ModR/M in binary: 11 (direct mode) 011 (subop negate) 011 (dest EBX) ++run: operate on r/m32 ++run: r/m32 is EBX ++run: subop: negate ++run: overflow + //:: and :(before "End Initialize Op Names") @@ -440,6 +483,10 @@ case 0xff: { trace(90, "run") << "storing value 0x" << HEXWORD << *arg << end(); break; } + default: + cerr << "unrecognized subop for ff: " << HEXBYTE << NUM(subop) << '\n'; + DUMP(""); + exit(1); // End Op ff Subops } break; diff --git a/subx/014indirect_addressing.cc b/subx/014indirect_addressing.cc index b3e23fe1..c415c96c 100644 --- a/subx/014indirect_addressing.cc +++ b/subx/014indirect_addressing.cc @@ -231,7 +231,7 @@ case 0x33: { // xor r/m32 with r32 % Reg[EBX].i = 0x2000; == 0x1 # code segment # op ModR/M SIB displacement immediate - f7 13 # negate *EBX + f7 13 # not *EBX # ModR/M in binary: 00 (indirect mode) 010 (subop not) 011 (dest EBX) == 0x2000 # data segment ff 00 0f 0f # 0x0f0f00ff |