diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 46c6f69466..1928f56917 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -32,6 +32,14 @@ namespace UserspaceEmulator { +template +inline constexpr T sign_extended_to(U value) +{ + if (!(value & X86::TypeTrivia::sign_bit)) + return value; + return (X86::TypeTrivia::mask & ~X86::TypeTrivia::mask) | value; +} + template struct TypeDoubler { }; @@ -443,7 +451,7 @@ template void SoftCPU::generic_RM16_imm8(Op op, const X86::Instruction& insn) { auto dest = insn.modrm().read16(*this, insn); - auto src = insn.imm8(); + auto src = sign_extended_to(insn.imm8()); auto result = op(*this, dest, src); if (update_dest) insn.modrm().write16(*this, insn, result); @@ -473,7 +481,7 @@ template void SoftCPU::generic_RM32_imm8(Op op, const X86::Instruction& insn) { auto dest = insn.modrm().read32(*this, insn); - auto src = insn.imm8(); + auto src = sign_extended_to(insn.imm8()); auto result = op(*this, dest, src); if (update_dest) insn.modrm().write32(*this, insn, result); @@ -1307,8 +1315,8 @@ void SoftCPU::XLAT(const X86::Instruction&) { TODO(); } #define DEFINE_GENERIC_INSN_HANDLERS(mnemonic, op, update_dest) \ DEFINE_GENERIC_INSN_HANDLERS_PARTIAL(mnemonic, op, update_dest) \ - void SoftCPU::mnemonic##_RM16_imm8(const X86::Instruction& insn) { generic_RM16_imm8(op, insn); } \ - void SoftCPU::mnemonic##_RM32_imm8(const X86::Instruction& insn) { generic_RM32_imm8(op, insn); } \ + void SoftCPU::mnemonic##_RM16_imm8(const X86::Instruction& insn) { generic_RM16_imm8(op, insn); } \ + void SoftCPU::mnemonic##_RM32_imm8(const X86::Instruction& insn) { generic_RM32_imm8(op, insn); } \ void SoftCPU::mnemonic##_reg16_RM16(const X86::Instruction& insn) { generic_reg16_RM16(op, insn); } \ void SoftCPU::mnemonic##_reg32_RM32(const X86::Instruction& insn) { generic_reg32_RM32(op, insn); } \ void SoftCPU::mnemonic##_reg8_RM8(const X86::Instruction& insn) { generic_reg8_RM8(op, insn); }