mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
UserspaceEmulator: The generic_RM*_imm8 functions need to sign extend
We are supposed to sign-extend the 8-bit immediate here, "cmp eax, 0xff" is actually "cmp eax, 0xffffffff"
This commit is contained in:
parent
21837544bb
commit
6febad1ef3
1 changed files with 12 additions and 4 deletions
|
@ -32,6 +32,14 @@
|
|||
|
||||
namespace UserspaceEmulator {
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr T sign_extended_to(U value)
|
||||
{
|
||||
if (!(value & X86::TypeTrivia<U>::sign_bit))
|
||||
return value;
|
||||
return (X86::TypeTrivia<T>::mask & ~X86::TypeTrivia<U>::mask) | value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct TypeDoubler {
|
||||
};
|
||||
|
@ -443,7 +451,7 @@ template<bool update_dest, typename Op>
|
|||
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<u16>(insn.imm8());
|
||||
auto result = op(*this, dest, src);
|
||||
if (update_dest)
|
||||
insn.modrm().write16(*this, insn, result);
|
||||
|
@ -473,7 +481,7 @@ template<bool update_dest, typename Op>
|
|||
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<u32>(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<update_dest>(op<u16, u8>, insn); } \
|
||||
void SoftCPU::mnemonic##_RM32_imm8(const X86::Instruction& insn) { generic_RM32_imm8<update_dest>(op<u32, u8>, insn); } \
|
||||
void SoftCPU::mnemonic##_RM16_imm8(const X86::Instruction& insn) { generic_RM16_imm8<update_dest>(op<u16, u16>, insn); } \
|
||||
void SoftCPU::mnemonic##_RM32_imm8(const X86::Instruction& insn) { generic_RM32_imm8<update_dest>(op<u32, u32>, insn); } \
|
||||
void SoftCPU::mnemonic##_reg16_RM16(const X86::Instruction& insn) { generic_reg16_RM16<update_dest>(op<u16, u16>, insn); } \
|
||||
void SoftCPU::mnemonic##_reg32_RM32(const X86::Instruction& insn) { generic_reg32_RM32<update_dest>(op<u32, u32>, insn); } \
|
||||
void SoftCPU::mnemonic##_reg8_RM8(const X86::Instruction& insn) { generic_reg8_RM8<update_dest>(op<u8, u8>, insn); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue