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 /subx/013direct_addressing.cc | |
parent | bfc997cfdae6a043bfd01ffd6dc3c0b2214d108f (diff) | |
download | mu-d27812594a85cbf6002cbe9e617b241eb00eedc1.tar.gz |
4715 - support one more negation instruction
Diffstat (limited to 'subx/013direct_addressing.cc')
-rw-r--r-- | subx/013direct_addressing.cc | 47 |
1 files changed, 47 insertions, 0 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; |