diff options
Diffstat (limited to 'subx')
-rw-r--r-- | subx/031check_operands.cc | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/subx/031check_operands.cc b/subx/031check_operands.cc index 5eaeeaf5..de78b4b1 100644 --- a/subx/031check_operands.cc +++ b/subx/031check_operands.cc @@ -374,8 +374,22 @@ void compare_bitvector_modrm(const line& inst, uint8_t expected, const word& op) for (int i = 0; i < NUM_OPERAND_TYPES; ++i, bitvector >>= 1, expected >>= 1) { //? cerr << "comparing for modrm " << HEXBYTE << NUM(bitvector) << " with " << NUM(expected) << '\n'; if ((bitvector & 0x1) == (expected & 0x1)) continue; // all good with this operand - if (i == DISP8 || i == DISP32) continue; // exception 2 const string& optype = Operand_type_name.at(i); + if (i == DISP8) { + int32_t mod = parse_int(metadata(inst, "mod").data); + if (mod != 1) + raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": unexpected " << optype << " operand\n" << end(); + continue; // exception 2 + } + if (i == DISP32) { + int32_t mod = parse_int(metadata(inst, "mod").data); + int32_t rm32 = parse_int(metadata(inst, "rm32").data); + if (mod == 0 && rm32 == 5) + ; // ok: special-case for loading address from disp32 + else if (mod != 2) + raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": unexpected " << optype << " operand\n" << end(); + continue; // exception 2 + } if ((bitvector & 0x1) > (expected & 0x1)) raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": unexpected " << optype << " operand\n" << end(); else @@ -446,6 +460,12 @@ $error: 0 81 0/add/subop 0/mod/indirect 4/rm32/use-sib 2/index 3/scale 1/imm32 +error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 2/index 3/scale 1/imm32' (combine rm32 with imm32 based on subop): missing base operand +:(scenario check_extra_displacement) +% Hide_errors = true; +== 0x1 +89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 4/disp8 ++error: '89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 4/disp8' (copy r32 to rm32): unexpected disp8 operand + :(scenario check_base_operand_not_needed_in_direct_mode) == 0x1 81 0/add/subop 3/mod/indirect 4/rm32/use-sib 1/imm32 |