From 1ea9d3faf8fec46422e345cc9c433d859413fe68 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Mar 2022 09:05:22 -0500 Subject: [PATCH] Introduce additional forms of IMUL. --- InstructionSets/x86/Decoder.cpp | 20 ++++++++++++++++---- InstructionSets/x86/Instruction.hpp | 10 ++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/InstructionSets/x86/Decoder.cpp b/InstructionSets/x86/Decoder.cpp index 10b6b9113..c1617a841 100644 --- a/InstructionSets/x86/Decoder.cpp +++ b/InstructionSets/x86/Decoder.cpp @@ -205,12 +205,21 @@ std::pair::InstructionT> Decoder::decode(con RequiresMin(i80286); Immediate(PUSH, data_size_); break; - // TODO: 0x69: IMUL GvEvIv + case 0x69: + RequiresMin(i80286); + MemRegReg(IMUL_3, Reg_MemReg, data_size_); + operand_size_ = data_size_; + break; case 0x6a: RequiresMin(i80286); Immediate(PUSH, DataSize::Byte); break; - // TODO: 0x6b: IMUL GvEvIv + case 0x6b: + RequiresMin(i80286); + MemRegReg(IMUL_3, Reg_MemReg, data_size_); + operand_size_ = DataSize::Byte; + sign_extend_ = true; + break; case 0x6c: // INSB RequiresMin(i80186); Complete(INS, None, None, DataSize::Byte); @@ -473,7 +482,10 @@ std::pair::InstructionT> Decoder::decode(con // TODO: 0xab: BTS Ev, Gv // TODO: 0xac: SHRD EvGvIb // TODO: 0xad: SHRD EvGvCL - // TODO: 0xaf: IMUL Gv, Ev + case 0xaf: + RequiresMin(i80386); + MemRegReg(IMUL_2, Reg_MemReg, data_size_); + break; case 0xb2: RequiresMin(i80386); MemRegReg(LSS, Reg_MemReg, data_size_); break; // TODO: 0xb3: BTR Ev, Gv @@ -578,7 +590,7 @@ std::pair::InstructionT> Decoder::decode(con case 2: operation_ = Operation::NOT; break; case 3: operation_ = Operation::NEG; break; case 4: operation_ = Operation::MUL; break; - case 5: operation_ = Operation::IMUL; break; + case 5: operation_ = Operation::IMUL_1; break; case 6: operation_ = Operation::DIV; break; case 7: operation_ = Operation::IDIV; break; } diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 85832be60..618545ab7 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -65,8 +65,8 @@ enum class Operation: uint8_t { SUB, /// Unsigned multiply; multiplies the source value by AX or AL, storing the result in DX:AX or AX. MUL, - /// Signed multiply; multiplies the source value by AX or AL, storing the result in DX:AX or AX. - IMUL, + /// Single operand signed multiply; multiplies the source value by AX or AL, storing the result in DX:AX or AX. + IMUL_1, /// Unsigned divide; divide the source value by AX or AL, storing the quotient in AL and the remainder in AH. DIV, /// Signed divide; divide the source value by AX or AL, storing the quotient in AL and the remainder in AH. @@ -265,6 +265,9 @@ enum class Operation: uint8_t { /// Stores the task register. STR, + /// Three-operand form of IMUL; multiply the immediate by the source and write to the destination. + IMUL_3, + /// Undocumented (but used); loads all registers, including internal ones. LOADALL, @@ -316,6 +319,9 @@ enum class Operation: uint8_t { /// Move with sign extension. MOVSX, + /// Two-operand form of IMUL; multiply the source by the destination and write to the destination. + IMUL_2, + IRETD, JECXZ, LODSD,