mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 17:17:42 +00:00
UserspaceEmulator+LibX86: Clean up some obnoxious template spam
Don't require clients to templatize modrm().read{8,16,32,64}() with the ValueWithShadow type when we can figure it out automatically. The main complication here is that ValueWithShadow is a UE concept while the MemoryOrRegisterReference inlines exist at the lower LibX86 layer and so doesn't have direct access to those types. But that's nothing we can't solve with some simple template trickery. :^)
This commit is contained in:
parent
993ceb66fd
commit
60c2fba9b9
3 changed files with 110 additions and 105 deletions
|
@ -766,7 +766,7 @@ ALWAYS_INLINE void SoftCPU::generic_EAX_imm32(Op op, const X86::Instruction& ins
|
||||||
template<bool update_dest, bool is_or, typename Op>
|
template<bool update_dest, bool is_or, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM16_imm16(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM16_imm16(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto dest = insn.modrm().read16(*this, insn);
|
||||||
auto src = shadow_wrap_as_initialized(insn.imm16());
|
auto src = shadow_wrap_as_initialized(insn.imm16());
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (is_or && insn.imm16() == 0xffff)
|
if (is_or && insn.imm16() == 0xffff)
|
||||||
|
@ -778,7 +778,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM16_imm16(Op op, const X86::Instruction& in
|
||||||
template<bool update_dest, bool is_or, typename Op>
|
template<bool update_dest, bool is_or, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM16_imm8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM16_imm8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto dest = insn.modrm().read16(*this, insn);
|
||||||
auto src = shadow_wrap_as_initialized<u16>(sign_extended_to<u16>(insn.imm8()));
|
auto src = shadow_wrap_as_initialized<u16>(sign_extended_to<u16>(insn.imm8()));
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (is_or && src.value() == 0xffff)
|
if (is_or && src.value() == 0xffff)
|
||||||
|
@ -790,7 +790,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM16_imm8(Op op, const X86::Instruction& ins
|
||||||
template<bool update_dest, typename Op>
|
template<bool update_dest, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM16_unsigned_imm8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM16_unsigned_imm8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto dest = insn.modrm().read16(*this, insn);
|
||||||
auto src = shadow_wrap_as_initialized(insn.imm8());
|
auto src = shadow_wrap_as_initialized(insn.imm8());
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (update_dest)
|
if (update_dest)
|
||||||
|
@ -800,7 +800,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM16_unsigned_imm8(Op op, const X86::Instruc
|
||||||
template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM16_reg16(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM16_reg16(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto dest = insn.modrm().read16(*this, insn);
|
||||||
auto src = const_gpr16(insn.reg16());
|
auto src = const_gpr16(insn.reg16());
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
||||||
|
@ -814,7 +814,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM16_reg16(Op op, const X86::Instruction& in
|
||||||
template<bool update_dest, bool is_or, typename Op>
|
template<bool update_dest, bool is_or, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM32_imm32(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM32_imm32(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto dest = insn.modrm().read32(*this, insn);
|
||||||
auto src = insn.imm32();
|
auto src = insn.imm32();
|
||||||
auto result = op(*this, dest, shadow_wrap_as_initialized(src));
|
auto result = op(*this, dest, shadow_wrap_as_initialized(src));
|
||||||
if (is_or && src == 0xffffffff)
|
if (is_or && src == 0xffffffff)
|
||||||
|
@ -826,7 +826,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM32_imm32(Op op, const X86::Instruction& in
|
||||||
template<bool update_dest, bool is_or, typename Op>
|
template<bool update_dest, bool is_or, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM32_imm8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM32_imm8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto dest = insn.modrm().read32(*this, insn);
|
||||||
auto src = sign_extended_to<u32>(insn.imm8());
|
auto src = sign_extended_to<u32>(insn.imm8());
|
||||||
auto result = op(*this, dest, shadow_wrap_as_initialized(src));
|
auto result = op(*this, dest, shadow_wrap_as_initialized(src));
|
||||||
if (is_or && src == 0xffffffff)
|
if (is_or && src == 0xffffffff)
|
||||||
|
@ -838,7 +838,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM32_imm8(Op op, const X86::Instruction& ins
|
||||||
template<bool update_dest, typename Op>
|
template<bool update_dest, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM32_unsigned_imm8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM32_unsigned_imm8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto dest = insn.modrm().read32(*this, insn);
|
||||||
auto src = shadow_wrap_as_initialized(insn.imm8());
|
auto src = shadow_wrap_as_initialized(insn.imm8());
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (update_dest)
|
if (update_dest)
|
||||||
|
@ -848,7 +848,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM32_unsigned_imm8(Op op, const X86::Instruc
|
||||||
template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM32_reg32(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM32_reg32(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto dest = insn.modrm().read32(*this, insn);
|
||||||
auto src = const_gpr32(insn.reg32());
|
auto src = const_gpr32(insn.reg32());
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
||||||
|
@ -862,7 +862,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM32_reg32(Op op, const X86::Instruction& in
|
||||||
template<bool update_dest, bool is_or, typename Op>
|
template<bool update_dest, bool is_or, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM8_imm8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM8_imm8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto dest = insn.modrm().read8(*this, insn);
|
||||||
auto src = insn.imm8();
|
auto src = insn.imm8();
|
||||||
auto result = op(*this, dest, shadow_wrap_as_initialized(src));
|
auto result = op(*this, dest, shadow_wrap_as_initialized(src));
|
||||||
if (is_or && src == 0xff)
|
if (is_or && src == 0xff)
|
||||||
|
@ -874,7 +874,7 @@ ALWAYS_INLINE void SoftCPU::generic_RM8_imm8(Op op, const X86::Instruction& insn
|
||||||
template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM8_reg8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM8_reg8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto dest = insn.modrm().read8(*this, insn);
|
||||||
auto src = const_gpr8(insn.reg8());
|
auto src = const_gpr8(insn.reg8());
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
||||||
|
@ -889,7 +889,7 @@ template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_reg16_RM16(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_reg16_RM16(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = const_gpr16(insn.reg16());
|
auto dest = const_gpr16(insn.reg16());
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
||||||
result.set_initialized();
|
result.set_initialized();
|
||||||
|
@ -903,7 +903,7 @@ template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_reg32_RM32(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_reg32_RM32(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = const_gpr32(insn.reg32());
|
auto dest = const_gpr32(insn.reg32());
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
||||||
result.set_initialized();
|
result.set_initialized();
|
||||||
|
@ -917,7 +917,7 @@ template<bool update_dest, bool dont_taint_for_same_operand, typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_reg8_RM8(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_reg8_RM8(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = const_gpr8(insn.reg8());
|
auto dest = const_gpr8(insn.reg8());
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
auto result = op(*this, dest, src);
|
auto result = op(*this, dest, src);
|
||||||
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
if (dont_taint_for_same_operand && insn.modrm().is_register() && insn.modrm().register_index() == insn.register_index()) {
|
||||||
result.set_initialized();
|
result.set_initialized();
|
||||||
|
@ -930,42 +930,42 @@ ALWAYS_INLINE void SoftCPU::generic_reg8_RM8(Op op, const X86::Instruction& insn
|
||||||
template<typename Op>
|
template<typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM8_1(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM8_1(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto data = insn.modrm().read8(*this, insn);
|
||||||
insn.modrm().write8(*this, insn, op(*this, data, shadow_wrap_as_initialized<u8>(1)));
|
insn.modrm().write8(*this, insn, op(*this, data, shadow_wrap_as_initialized<u8>(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Op>
|
template<typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM8_CL(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM8_CL(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto data = insn.modrm().read8(*this, insn);
|
||||||
insn.modrm().write8(*this, insn, op(*this, data, cl()));
|
insn.modrm().write8(*this, insn, op(*this, data, cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Op>
|
template<typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM16_1(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM16_1(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto data = insn.modrm().read16(*this, insn);
|
||||||
insn.modrm().write16(*this, insn, op(*this, data, shadow_wrap_as_initialized<u8>(1)));
|
insn.modrm().write16(*this, insn, op(*this, data, shadow_wrap_as_initialized<u8>(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Op>
|
template<typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM16_CL(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM16_CL(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto data = insn.modrm().read16(*this, insn);
|
||||||
insn.modrm().write16(*this, insn, op(*this, data, cl()));
|
insn.modrm().write16(*this, insn, op(*this, data, cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Op>
|
template<typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM32_1(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM32_1(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto data = insn.modrm().read32(*this, insn);
|
||||||
insn.modrm().write32(*this, insn, op(*this, data, shadow_wrap_as_initialized<u8>(1)));
|
insn.modrm().write32(*this, insn, op(*this, data, shadow_wrap_as_initialized<u8>(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Op>
|
template<typename Op>
|
||||||
ALWAYS_INLINE void SoftCPU::generic_RM32_CL(Op op, const X86::Instruction& insn)
|
ALWAYS_INLINE void SoftCPU::generic_RM32_CL(Op op, const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto data = insn.modrm().read32(*this, insn);
|
||||||
insn.modrm().write32(*this, insn, op(*this, data, cl()));
|
insn.modrm().write32(*this, insn, op(*this, data, cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1001,7 @@ ALWAYS_INLINE static T op_bsr(SoftCPU&, T value)
|
||||||
|
|
||||||
void SoftCPU::BSF_reg16_RM16(const X86::Instruction& insn)
|
void SoftCPU::BSF_reg16_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
set_zf(!src.value());
|
set_zf(!src.value());
|
||||||
if (src.value())
|
if (src.value())
|
||||||
gpr16(insn.reg16()) = op_bsf(*this, src);
|
gpr16(insn.reg16()) = op_bsf(*this, src);
|
||||||
|
@ -1010,7 +1010,7 @@ void SoftCPU::BSF_reg16_RM16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::BSF_reg32_RM32(const X86::Instruction& insn)
|
void SoftCPU::BSF_reg32_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
set_zf(!src.value());
|
set_zf(!src.value());
|
||||||
if (src.value()) {
|
if (src.value()) {
|
||||||
gpr32(insn.reg32()) = op_bsf(*this, src);
|
gpr32(insn.reg32()) = op_bsf(*this, src);
|
||||||
|
@ -1020,7 +1020,7 @@ void SoftCPU::BSF_reg32_RM32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::BSR_reg16_RM16(const X86::Instruction& insn)
|
void SoftCPU::BSR_reg16_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
set_zf(!src.value());
|
set_zf(!src.value());
|
||||||
if (src.value()) {
|
if (src.value()) {
|
||||||
gpr16(insn.reg16()) = op_bsr(*this, src);
|
gpr16(insn.reg16()) = op_bsr(*this, src);
|
||||||
|
@ -1030,7 +1030,7 @@ void SoftCPU::BSR_reg16_RM16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::BSR_reg32_RM32(const X86::Instruction& insn)
|
void SoftCPU::BSR_reg32_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
set_zf(!src.value());
|
set_zf(!src.value());
|
||||||
if (src.value()) {
|
if (src.value()) {
|
||||||
gpr32(insn.reg32()) = op_bsr(*this, src);
|
gpr32(insn.reg32()) = op_bsr(*this, src);
|
||||||
|
@ -1072,7 +1072,7 @@ ALWAYS_INLINE void BTx_RM16_reg16(SoftCPU& cpu, const X86::Instruction& insn, Op
|
||||||
{
|
{
|
||||||
if (insn.modrm().is_register()) {
|
if (insn.modrm().is_register()) {
|
||||||
unsigned bit_index = cpu.const_gpr16(insn.reg16()).value() & (X86::TypeTrivia<u16>::bits - 1);
|
unsigned bit_index = cpu.const_gpr16(insn.reg16()).value() & (X86::TypeTrivia<u16>::bits - 1);
|
||||||
auto original = insn.modrm().read16<ValueWithShadow<u16>>(cpu, insn);
|
auto original = insn.modrm().read16(cpu, insn);
|
||||||
u16 bit_mask = 1 << bit_index;
|
u16 bit_mask = 1 << bit_index;
|
||||||
u16 result = op(original.value(), bit_mask);
|
u16 result = op(original.value(), bit_mask);
|
||||||
cpu.set_cf((original.value() & bit_mask) != 0);
|
cpu.set_cf((original.value() & bit_mask) != 0);
|
||||||
|
@ -1100,7 +1100,7 @@ ALWAYS_INLINE void BTx_RM32_reg32(SoftCPU& cpu, const X86::Instruction& insn, Op
|
||||||
{
|
{
|
||||||
if (insn.modrm().is_register()) {
|
if (insn.modrm().is_register()) {
|
||||||
unsigned bit_index = cpu.const_gpr32(insn.reg32()).value() & (X86::TypeTrivia<u32>::bits - 1);
|
unsigned bit_index = cpu.const_gpr32(insn.reg32()).value() & (X86::TypeTrivia<u32>::bits - 1);
|
||||||
auto original = insn.modrm().read32<ValueWithShadow<u32>>(cpu, insn);
|
auto original = insn.modrm().read32(cpu, insn);
|
||||||
u32 bit_mask = 1 << bit_index;
|
u32 bit_mask = 1 << bit_index;
|
||||||
u32 result = op(original.value(), bit_mask);
|
u32 result = op(original.value(), bit_mask);
|
||||||
cpu.set_cf((original.value() & bit_mask) != 0);
|
cpu.set_cf((original.value() & bit_mask) != 0);
|
||||||
|
@ -1131,7 +1131,7 @@ ALWAYS_INLINE void BTx_RM16_imm8(SoftCPU& cpu, const X86::Instruction& insn, Op
|
||||||
// FIXME: Support higher bit indices
|
// FIXME: Support higher bit indices
|
||||||
ASSERT(bit_index < 16);
|
ASSERT(bit_index < 16);
|
||||||
|
|
||||||
auto original = insn.modrm().read16<ValueWithShadow<u16>>(cpu, insn);
|
auto original = insn.modrm().read16(cpu, insn);
|
||||||
u16 bit_mask = 1 << bit_index;
|
u16 bit_mask = 1 << bit_index;
|
||||||
auto result = op(original.value(), bit_mask);
|
auto result = op(original.value(), bit_mask);
|
||||||
cpu.set_cf((original.value() & bit_mask) != 0);
|
cpu.set_cf((original.value() & bit_mask) != 0);
|
||||||
|
@ -1148,7 +1148,7 @@ ALWAYS_INLINE void BTx_RM32_imm8(SoftCPU& cpu, const X86::Instruction& insn, Op
|
||||||
// FIXME: Support higher bit indices
|
// FIXME: Support higher bit indices
|
||||||
ASSERT(bit_index < 32);
|
ASSERT(bit_index < 32);
|
||||||
|
|
||||||
auto original = insn.modrm().read32<ValueWithShadow<u32>>(cpu, insn);
|
auto original = insn.modrm().read32(cpu, insn);
|
||||||
u32 bit_mask = 1 << bit_index;
|
u32 bit_mask = 1 << bit_index;
|
||||||
auto result = op(original.value(), bit_mask);
|
auto result = op(original.value(), bit_mask);
|
||||||
cpu.set_cf((original.value() & bit_mask) != 0);
|
cpu.set_cf((original.value() & bit_mask) != 0);
|
||||||
|
@ -1178,7 +1178,7 @@ void SoftCPU::CALL_RM16(const X86::Instruction&) { TODO_INSN(); }
|
||||||
void SoftCPU::CALL_RM32(const X86::Instruction& insn)
|
void SoftCPU::CALL_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
push32(shadow_wrap_as_initialized(eip()));
|
push32(shadow_wrap_as_initialized(eip()));
|
||||||
auto address = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto address = insn.modrm().read32(*this, insn);
|
||||||
warn_if_uninitialized(address, "call rm32");
|
warn_if_uninitialized(address, "call rm32");
|
||||||
set_eip(address.value());
|
set_eip(address.value());
|
||||||
}
|
}
|
||||||
|
@ -1224,14 +1224,14 @@ void SoftCPU::CMOVcc_reg16_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
warn_if_flags_tainted("cmovcc reg16, rm16");
|
warn_if_flags_tainted("cmovcc reg16, rm16");
|
||||||
if (evaluate_condition(insn.cc()))
|
if (evaluate_condition(insn.cc()))
|
||||||
gpr16(insn.reg16()) = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
gpr16(insn.reg16()) = insn.modrm().read16(*this, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::CMOVcc_reg32_RM32(const X86::Instruction& insn)
|
void SoftCPU::CMOVcc_reg32_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
warn_if_flags_tainted("cmovcc reg32, rm32");
|
warn_if_flags_tainted("cmovcc reg32, rm32");
|
||||||
if (evaluate_condition(insn.cc()))
|
if (evaluate_condition(insn.cc()))
|
||||||
gpr32(insn.reg32()) = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
gpr32(insn.reg32()) = insn.modrm().read32(*this, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1264,7 +1264,7 @@ void SoftCPU::CMPSW(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction& insn)
|
void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto current = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto current = insn.modrm().read16(*this, insn);
|
||||||
taint_flags_from(current, ax());
|
taint_flags_from(current, ax());
|
||||||
if (current.value() == ax().value()) {
|
if (current.value() == ax().value()) {
|
||||||
set_zf(true);
|
set_zf(true);
|
||||||
|
@ -1277,7 +1277,7 @@ void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::CMPXCHG_RM32_reg32(const X86::Instruction& insn)
|
void SoftCPU::CMPXCHG_RM32_reg32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto current = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto current = insn.modrm().read32(*this, insn);
|
||||||
taint_flags_from(current, eax());
|
taint_flags_from(current, eax());
|
||||||
if (current.value() == eax().value()) {
|
if (current.value() == eax().value()) {
|
||||||
set_zf(true);
|
set_zf(true);
|
||||||
|
@ -1290,7 +1290,7 @@ void SoftCPU::CMPXCHG_RM32_reg32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::CMPXCHG_RM8_reg8(const X86::Instruction& insn)
|
void SoftCPU::CMPXCHG_RM8_reg8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto current = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto current = insn.modrm().read8(*this, insn);
|
||||||
taint_flags_from(current, al());
|
taint_flags_from(current, al());
|
||||||
if (current.value() == al().value()) {
|
if (current.value() == al().value()) {
|
||||||
set_zf(true);
|
set_zf(true);
|
||||||
|
@ -1318,17 +1318,17 @@ void SoftCPU::DAS(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::DEC_RM16(const X86::Instruction& insn)
|
void SoftCPU::DEC_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_dec(*this, insn.modrm().read16<ValueWithShadow<u16>>(*this, insn)));
|
insn.modrm().write16(*this, insn, op_dec(*this, insn.modrm().read16(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::DEC_RM32(const X86::Instruction& insn)
|
void SoftCPU::DEC_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_dec(*this, insn.modrm().read32<ValueWithShadow<u32>>(*this, insn)));
|
insn.modrm().write32(*this, insn, op_dec(*this, insn.modrm().read32(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::DEC_RM8(const X86::Instruction& insn)
|
void SoftCPU::DEC_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write8(*this, insn, op_dec(*this, insn.modrm().read8<ValueWithShadow<u8>>(*this, insn)));
|
insn.modrm().write8(*this, insn, op_dec(*this, insn.modrm().read8(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::DEC_reg16(const X86::Instruction& insn)
|
void SoftCPU::DEC_reg16(const X86::Instruction& insn)
|
||||||
|
@ -1343,7 +1343,7 @@ void SoftCPU::DEC_reg32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::DIV_RM16(const X86::Instruction& insn)
|
void SoftCPU::DIV_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto divisor = insn.modrm().read16(*this, insn);
|
||||||
if (divisor.value() == 0) {
|
if (divisor.value() == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
TODO();
|
TODO();
|
||||||
|
@ -1364,7 +1364,7 @@ void SoftCPU::DIV_RM16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::DIV_RM32(const X86::Instruction& insn)
|
void SoftCPU::DIV_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto divisor = insn.modrm().read32(*this, insn);
|
||||||
if (divisor.value() == 0) {
|
if (divisor.value() == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
TODO();
|
TODO();
|
||||||
|
@ -1385,7 +1385,7 @@ void SoftCPU::DIV_RM32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::DIV_RM8(const X86::Instruction& insn)
|
void SoftCPU::DIV_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto divisor = insn.modrm().read8(*this, insn);
|
||||||
if (divisor.value() == 0) {
|
if (divisor.value() == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
TODO();
|
TODO();
|
||||||
|
@ -1434,7 +1434,7 @@ void SoftCPU::FXAM(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::FLDCW(const X86::Instruction& insn)
|
void SoftCPU::FLDCW(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
m_fpu_cw = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
m_fpu_cw = insn.modrm().read16(*this, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::FLD1(const X86::Instruction&) { TODO_INSN(); }
|
void SoftCPU::FLD1(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
@ -1546,7 +1546,7 @@ void SoftCPU::HLT(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::IDIV_RM16(const X86::Instruction& insn)
|
void SoftCPU::IDIV_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor_with_shadow = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto divisor_with_shadow = insn.modrm().read16(*this, insn);
|
||||||
auto divisor = (i16)divisor_with_shadow.value();
|
auto divisor = (i16)divisor_with_shadow.value();
|
||||||
if (divisor == 0) {
|
if (divisor == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
|
@ -1566,7 +1566,7 @@ void SoftCPU::IDIV_RM16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::IDIV_RM32(const X86::Instruction& insn)
|
void SoftCPU::IDIV_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor_with_shadow = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto divisor_with_shadow = insn.modrm().read32(*this, insn);
|
||||||
auto divisor = (i32)divisor_with_shadow.value();
|
auto divisor = (i32)divisor_with_shadow.value();
|
||||||
if (divisor == 0) {
|
if (divisor == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
|
@ -1586,7 +1586,7 @@ void SoftCPU::IDIV_RM32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::IDIV_RM8(const X86::Instruction& insn)
|
void SoftCPU::IDIV_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor_with_shadow = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto divisor_with_shadow = insn.modrm().read8(*this, insn);
|
||||||
auto divisor = (i8)divisor_with_shadow.value();
|
auto divisor = (i8)divisor_with_shadow.value();
|
||||||
if (divisor == 0) {
|
if (divisor == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
|
@ -1608,7 +1608,7 @@ void SoftCPU::IMUL_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i16 result_high;
|
i16 result_high;
|
||||||
i16 result_low;
|
i16 result_low;
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
op_imul<i16>(*this, src.value(), ax().value(), result_high, result_low);
|
op_imul<i16>(*this, src.value(), ax().value(), result_high, result_low);
|
||||||
gpr16(X86::RegisterDX) = shadow_wrap_with_taint_from<u16>(result_high, src, ax());
|
gpr16(X86::RegisterDX) = shadow_wrap_with_taint_from<u16>(result_high, src, ax());
|
||||||
gpr16(X86::RegisterAX) = shadow_wrap_with_taint_from<u16>(result_low, src, ax());
|
gpr16(X86::RegisterAX) = shadow_wrap_with_taint_from<u16>(result_low, src, ax());
|
||||||
|
@ -1618,7 +1618,7 @@ void SoftCPU::IMUL_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i32 result_high;
|
i32 result_high;
|
||||||
i32 result_low;
|
i32 result_low;
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
op_imul<i32>(*this, src.value(), eax().value(), result_high, result_low);
|
op_imul<i32>(*this, src.value(), eax().value(), result_high, result_low);
|
||||||
gpr32(X86::RegisterEDX) = shadow_wrap_with_taint_from<u32>(result_high, src, eax());
|
gpr32(X86::RegisterEDX) = shadow_wrap_with_taint_from<u32>(result_high, src, eax());
|
||||||
gpr32(X86::RegisterEAX) = shadow_wrap_with_taint_from<u32>(result_low, src, eax());
|
gpr32(X86::RegisterEAX) = shadow_wrap_with_taint_from<u32>(result_low, src, eax());
|
||||||
|
@ -1628,7 +1628,7 @@ void SoftCPU::IMUL_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i8 result_high;
|
i8 result_high;
|
||||||
i8 result_low;
|
i8 result_low;
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
op_imul<i8>(*this, src.value(), al().value(), result_high, result_low);
|
op_imul<i8>(*this, src.value(), al().value(), result_high, result_low);
|
||||||
gpr8(X86::RegisterAH) = shadow_wrap_with_taint_from<u8>(result_high, src, al());
|
gpr8(X86::RegisterAH) = shadow_wrap_with_taint_from<u8>(result_high, src, al());
|
||||||
gpr8(X86::RegisterAL) = shadow_wrap_with_taint_from<u8>(result_low, src, al());
|
gpr8(X86::RegisterAL) = shadow_wrap_with_taint_from<u8>(result_low, src, al());
|
||||||
|
@ -1638,7 +1638,7 @@ void SoftCPU::IMUL_reg16_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i16 result_high;
|
i16 result_high;
|
||||||
i16 result_low;
|
i16 result_low;
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
op_imul<i16>(*this, gpr16(insn.reg16()).value(), src.value(), result_high, result_low);
|
op_imul<i16>(*this, gpr16(insn.reg16()).value(), src.value(), result_high, result_low);
|
||||||
gpr16(insn.reg16()) = shadow_wrap_with_taint_from<u16>(result_low, src, gpr16(insn.reg16()));
|
gpr16(insn.reg16()) = shadow_wrap_with_taint_from<u16>(result_low, src, gpr16(insn.reg16()));
|
||||||
}
|
}
|
||||||
|
@ -1647,7 +1647,7 @@ void SoftCPU::IMUL_reg16_RM16_imm16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i16 result_high;
|
i16 result_high;
|
||||||
i16 result_low;
|
i16 result_low;
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
op_imul<i16>(*this, src.value(), insn.imm16(), result_high, result_low);
|
op_imul<i16>(*this, src.value(), insn.imm16(), result_high, result_low);
|
||||||
gpr16(insn.reg16()) = shadow_wrap_with_taint_from<u16>(result_low, src);
|
gpr16(insn.reg16()) = shadow_wrap_with_taint_from<u16>(result_low, src);
|
||||||
}
|
}
|
||||||
|
@ -1656,7 +1656,7 @@ void SoftCPU::IMUL_reg16_RM16_imm8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i16 result_high;
|
i16 result_high;
|
||||||
i16 result_low;
|
i16 result_low;
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
op_imul<i16>(*this, src.value(), sign_extended_to<i16>(insn.imm8()), result_high, result_low);
|
op_imul<i16>(*this, src.value(), sign_extended_to<i16>(insn.imm8()), result_high, result_low);
|
||||||
gpr16(insn.reg16()) = shadow_wrap_with_taint_from<u16>(result_low, src);
|
gpr16(insn.reg16()) = shadow_wrap_with_taint_from<u16>(result_low, src);
|
||||||
}
|
}
|
||||||
|
@ -1665,7 +1665,7 @@ void SoftCPU::IMUL_reg32_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i32 result_high;
|
i32 result_high;
|
||||||
i32 result_low;
|
i32 result_low;
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
op_imul<i32>(*this, gpr32(insn.reg32()).value(), src.value(), result_high, result_low);
|
op_imul<i32>(*this, gpr32(insn.reg32()).value(), src.value(), result_high, result_low);
|
||||||
gpr32(insn.reg32()) = shadow_wrap_with_taint_from<u32>(result_low, src, gpr32(insn.reg32()));
|
gpr32(insn.reg32()) = shadow_wrap_with_taint_from<u32>(result_low, src, gpr32(insn.reg32()));
|
||||||
}
|
}
|
||||||
|
@ -1674,7 +1674,7 @@ void SoftCPU::IMUL_reg32_RM32_imm32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i32 result_high;
|
i32 result_high;
|
||||||
i32 result_low;
|
i32 result_low;
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
op_imul<i32>(*this, src.value(), insn.imm32(), result_high, result_low);
|
op_imul<i32>(*this, src.value(), insn.imm32(), result_high, result_low);
|
||||||
gpr32(insn.reg32()) = shadow_wrap_with_taint_from<u32>(result_low, src);
|
gpr32(insn.reg32()) = shadow_wrap_with_taint_from<u32>(result_low, src);
|
||||||
}
|
}
|
||||||
|
@ -1683,24 +1683,24 @@ void SoftCPU::IMUL_reg32_RM32_imm8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
i32 result_high;
|
i32 result_high;
|
||||||
i32 result_low;
|
i32 result_low;
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
op_imul<i32>(*this, src.value(), sign_extended_to<i32>(insn.imm8()), result_high, result_low);
|
op_imul<i32>(*this, src.value(), sign_extended_to<i32>(insn.imm8()), result_high, result_low);
|
||||||
gpr32(insn.reg32()) = shadow_wrap_with_taint_from<u32>(result_low, src);
|
gpr32(insn.reg32()) = shadow_wrap_with_taint_from<u32>(result_low, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::INC_RM16(const X86::Instruction& insn)
|
void SoftCPU::INC_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_inc(*this, insn.modrm().read16<ValueWithShadow<u16>>(*this, insn)));
|
insn.modrm().write16(*this, insn, op_inc(*this, insn.modrm().read16(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::INC_RM32(const X86::Instruction& insn)
|
void SoftCPU::INC_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_inc(*this, insn.modrm().read32<ValueWithShadow<u32>>(*this, insn)));
|
insn.modrm().write32(*this, insn, op_inc(*this, insn.modrm().read32(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::INC_RM8(const X86::Instruction& insn)
|
void SoftCPU::INC_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write8(*this, insn, op_inc(*this, insn.modrm().read8<ValueWithShadow<u8>>(*this, insn)));
|
insn.modrm().write8(*this, insn, op_inc(*this, insn.modrm().read8(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::INC_reg16(const X86::Instruction& insn)
|
void SoftCPU::INC_reg16(const X86::Instruction& insn)
|
||||||
|
@ -1754,7 +1754,7 @@ void SoftCPU::JMP_RM16(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::JMP_RM32(const X86::Instruction& insn)
|
void SoftCPU::JMP_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
set_eip(insn.modrm().read32<ValueWithShadow<u32>>(*this, insn).value());
|
set_eip(insn.modrm().read32(*this, insn).value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::JMP_imm16(const X86::Instruction& insn)
|
void SoftCPU::JMP_imm16(const X86::Instruction& insn)
|
||||||
|
@ -1927,37 +1927,37 @@ void SoftCPU::MOVSW(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::MOVSX_reg16_RM8(const X86::Instruction& insn)
|
void SoftCPU::MOVSX_reg16_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
gpr16(insn.reg16()) = ValueWithShadow<u16>(sign_extended_to<u16>(src.value()), 0x0100 | (src.shadow()));
|
gpr16(insn.reg16()) = ValueWithShadow<u16>(sign_extended_to<u16>(src.value()), 0x0100 | (src.shadow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOVSX_reg32_RM16(const X86::Instruction& insn)
|
void SoftCPU::MOVSX_reg32_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
gpr32(insn.reg32()) = ValueWithShadow<u32>(sign_extended_to<u32>(src.value()), 0x01010000 | (src.shadow()));
|
gpr32(insn.reg32()) = ValueWithShadow<u32>(sign_extended_to<u32>(src.value()), 0x01010000 | (src.shadow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOVSX_reg32_RM8(const X86::Instruction& insn)
|
void SoftCPU::MOVSX_reg32_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
gpr32(insn.reg32()) = ValueWithShadow<u32>(sign_extended_to<u32>(src.value()), 0x01010100 | (src.shadow()));
|
gpr32(insn.reg32()) = ValueWithShadow<u32>(sign_extended_to<u32>(src.value()), 0x01010100 | (src.shadow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOVZX_reg16_RM8(const X86::Instruction& insn)
|
void SoftCPU::MOVZX_reg16_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
gpr16(insn.reg16()) = ValueWithShadow<u16>(src.value(), 0x0100 | (src.shadow() & 0xff));
|
gpr16(insn.reg16()) = ValueWithShadow<u16>(src.value(), 0x0100 | (src.shadow() & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOVZX_reg32_RM16(const X86::Instruction& insn)
|
void SoftCPU::MOVZX_reg32_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
gpr32(insn.reg32()) = ValueWithShadow<u32>(src.value(), 0x01010000 | (src.shadow() & 0xffff));
|
gpr32(insn.reg32()) = ValueWithShadow<u32>(src.value(), 0x01010000 | (src.shadow() & 0xffff));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOVZX_reg32_RM8(const X86::Instruction& insn)
|
void SoftCPU::MOVZX_reg32_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
gpr32(insn.reg32()) = ValueWithShadow<u32>(src.value(), 0x01010100 | (src.shadow() & 0xff));
|
gpr32(insn.reg32()) = ValueWithShadow<u32>(src.value(), 0x01010100 | (src.shadow() & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2028,7 +2028,7 @@ void SoftCPU::MOV_moff8_AL(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::MOV_reg16_RM16(const X86::Instruction& insn)
|
void SoftCPU::MOV_reg16_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
gpr16(insn.reg16()) = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
gpr16(insn.reg16()) = insn.modrm().read16(*this, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOV_reg16_imm16(const X86::Instruction& insn)
|
void SoftCPU::MOV_reg16_imm16(const X86::Instruction& insn)
|
||||||
|
@ -2041,7 +2041,7 @@ void SoftCPU::MOV_reg32_DR(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::MOV_reg32_RM32(const X86::Instruction& insn)
|
void SoftCPU::MOV_reg32_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
gpr32(insn.reg32()) = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
gpr32(insn.reg32()) = insn.modrm().read32(*this, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOV_reg32_imm32(const X86::Instruction& insn)
|
void SoftCPU::MOV_reg32_imm32(const X86::Instruction& insn)
|
||||||
|
@ -2051,7 +2051,7 @@ void SoftCPU::MOV_reg32_imm32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::MOV_reg8_RM8(const X86::Instruction& insn)
|
void SoftCPU::MOV_reg8_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
gpr8(insn.reg8()) = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
gpr8(insn.reg8()) = insn.modrm().read8(*this, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::MOV_reg8_imm8(const X86::Instruction& insn)
|
void SoftCPU::MOV_reg8_imm8(const X86::Instruction& insn)
|
||||||
|
@ -2064,7 +2064,7 @@ void SoftCPU::MOV_seg_RM32(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::MUL_RM16(const X86::Instruction& insn)
|
void SoftCPU::MUL_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto src = insn.modrm().read16(*this, insn);
|
||||||
u32 result = (u32)ax().value() * (u32)src.value();
|
u32 result = (u32)ax().value() * (u32)src.value();
|
||||||
auto original_ax = ax();
|
auto original_ax = ax();
|
||||||
set_ax(shadow_wrap_with_taint_from<u16>(result & 0xffff, src, original_ax));
|
set_ax(shadow_wrap_with_taint_from<u16>(result & 0xffff, src, original_ax));
|
||||||
|
@ -2077,7 +2077,7 @@ void SoftCPU::MUL_RM16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::MUL_RM32(const X86::Instruction& insn)
|
void SoftCPU::MUL_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto src = insn.modrm().read32(*this, insn);
|
||||||
u64 result = (u64)eax().value() * (u64)src.value();
|
u64 result = (u64)eax().value() * (u64)src.value();
|
||||||
auto original_eax = eax();
|
auto original_eax = eax();
|
||||||
set_eax(shadow_wrap_with_taint_from<u32>(result, src, original_eax));
|
set_eax(shadow_wrap_with_taint_from<u32>(result, src, original_eax));
|
||||||
|
@ -2090,7 +2090,7 @@ void SoftCPU::MUL_RM32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::MUL_RM8(const X86::Instruction& insn)
|
void SoftCPU::MUL_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto src = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto src = insn.modrm().read8(*this, insn);
|
||||||
u16 result = (u16)al().value() * src.value();
|
u16 result = (u16)al().value() * src.value();
|
||||||
auto original_al = al();
|
auto original_al = al();
|
||||||
set_ax(shadow_wrap_with_taint_from(result, src, original_al));
|
set_ax(shadow_wrap_with_taint_from(result, src, original_al));
|
||||||
|
@ -2102,17 +2102,17 @@ void SoftCPU::MUL_RM8(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::NEG_RM16(const X86::Instruction& insn)
|
void SoftCPU::NEG_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_sub<ValueWithShadow<u16>>(*this, shadow_wrap_as_initialized<u16>(0), insn.modrm().read16<ValueWithShadow<u16>>(*this, insn)));
|
insn.modrm().write16(*this, insn, op_sub<ValueWithShadow<u16>>(*this, shadow_wrap_as_initialized<u16>(0), insn.modrm().read16(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::NEG_RM32(const X86::Instruction& insn)
|
void SoftCPU::NEG_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_sub<ValueWithShadow<u32>>(*this, shadow_wrap_as_initialized<u32>(0), insn.modrm().read32<ValueWithShadow<u32>>(*this, insn)));
|
insn.modrm().write32(*this, insn, op_sub<ValueWithShadow<u32>>(*this, shadow_wrap_as_initialized<u32>(0), insn.modrm().read32(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::NEG_RM8(const X86::Instruction& insn)
|
void SoftCPU::NEG_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write8(*this, insn, op_sub<ValueWithShadow<u8>>(*this, shadow_wrap_as_initialized<u8>(0), insn.modrm().read8<ValueWithShadow<u8>>(*this, insn)));
|
insn.modrm().write8(*this, insn, op_sub<ValueWithShadow<u8>>(*this, shadow_wrap_as_initialized<u8>(0), insn.modrm().read8(*this, insn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::NOP(const X86::Instruction&)
|
void SoftCPU::NOP(const X86::Instruction&)
|
||||||
|
@ -2121,19 +2121,19 @@ void SoftCPU::NOP(const X86::Instruction&)
|
||||||
|
|
||||||
void SoftCPU::NOT_RM16(const X86::Instruction& insn)
|
void SoftCPU::NOT_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto data = insn.modrm().read16(*this, insn);
|
||||||
insn.modrm().write16(*this, insn, ValueWithShadow<u16>(~data.value(), data.shadow()));
|
insn.modrm().write16(*this, insn, ValueWithShadow<u16>(~data.value(), data.shadow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::NOT_RM32(const X86::Instruction& insn)
|
void SoftCPU::NOT_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto data = insn.modrm().read32(*this, insn);
|
||||||
insn.modrm().write32(*this, insn, ValueWithShadow<u32>(~data.value(), data.shadow()));
|
insn.modrm().write32(*this, insn, ValueWithShadow<u32>(~data.value(), data.shadow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::NOT_RM8(const X86::Instruction& insn)
|
void SoftCPU::NOT_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto data = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto data = insn.modrm().read8(*this, insn);
|
||||||
insn.modrm().write8(*this, insn, ValueWithShadow<u8>(~data.value(), data.shadow()));
|
insn.modrm().write8(*this, insn, ValueWithShadow<u8>(~data.value(), data.shadow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2207,7 +2207,7 @@ void SoftCPU::PUSH_RM16(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::PUSH_RM32(const X86::Instruction& insn)
|
void SoftCPU::PUSH_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
push32(insn.modrm().read32<ValueWithShadow<u32>>(*this, insn));
|
push32(insn.modrm().read32(*this, insn));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::PUSH_SP_8086_80186(const X86::Instruction&) { TODO_INSN(); }
|
void SoftCPU::PUSH_SP_8086_80186(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
@ -2521,44 +2521,44 @@ void SoftCPU::SGDT(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::SHLD_RM16_reg16_CL(const X86::Instruction& insn)
|
void SoftCPU::SHLD_RM16_reg16_CL(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_shld(*this, insn.modrm().read16<ValueWithShadow<u16>>(*this, insn), const_gpr16(insn.reg16()), cl()));
|
insn.modrm().write16(*this, insn, op_shld(*this, insn.modrm().read16(*this, insn), const_gpr16(insn.reg16()), cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::SHLD_RM16_reg16_imm8(const X86::Instruction& insn)
|
void SoftCPU::SHLD_RM16_reg16_imm8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_shld(*this, insn.modrm().read16<ValueWithShadow<u16>>(*this, insn), const_gpr16(insn.reg16()), shadow_wrap_as_initialized(insn.imm8())));
|
insn.modrm().write16(*this, insn, op_shld(*this, insn.modrm().read16(*this, insn), const_gpr16(insn.reg16()), shadow_wrap_as_initialized(insn.imm8())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::SHLD_RM32_reg32_CL(const X86::Instruction& insn)
|
void SoftCPU::SHLD_RM32_reg32_CL(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_shld(*this, insn.modrm().read32<ValueWithShadow<u32>>(*this, insn), const_gpr32(insn.reg32()), cl()));
|
insn.modrm().write32(*this, insn, op_shld(*this, insn.modrm().read32(*this, insn), const_gpr32(insn.reg32()), cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::SHLD_RM32_reg32_imm8(const X86::Instruction& insn)
|
void SoftCPU::SHLD_RM32_reg32_imm8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_shld(*this, insn.modrm().read32<ValueWithShadow<u32>>(*this, insn), const_gpr32(insn.reg32()), shadow_wrap_as_initialized(insn.imm8())));
|
insn.modrm().write32(*this, insn, op_shld(*this, insn.modrm().read32(*this, insn), const_gpr32(insn.reg32()), shadow_wrap_as_initialized(insn.imm8())));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_GENERIC_SHIFT_ROTATE_INSN_HANDLERS(SHL, op_shl)
|
DEFINE_GENERIC_SHIFT_ROTATE_INSN_HANDLERS(SHL, op_shl)
|
||||||
|
|
||||||
void SoftCPU::SHRD_RM16_reg16_CL(const X86::Instruction& insn)
|
void SoftCPU::SHRD_RM16_reg16_CL(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_shrd(*this, insn.modrm().read16<ValueWithShadow<u16>>(*this, insn), const_gpr16(insn.reg16()), cl()));
|
insn.modrm().write16(*this, insn, op_shrd(*this, insn.modrm().read16(*this, insn), const_gpr16(insn.reg16()), cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::SHRD_RM16_reg16_imm8(const X86::Instruction& insn)
|
void SoftCPU::SHRD_RM16_reg16_imm8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write16(*this, insn, op_shrd(*this, insn.modrm().read16<ValueWithShadow<u16>>(*this, insn), const_gpr16(insn.reg16()), shadow_wrap_as_initialized(insn.imm8())));
|
insn.modrm().write16(*this, insn, op_shrd(*this, insn.modrm().read16(*this, insn), const_gpr16(insn.reg16()), shadow_wrap_as_initialized(insn.imm8())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::SHRD_RM32_reg32_CL(const X86::Instruction& insn)
|
void SoftCPU::SHRD_RM32_reg32_CL(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_shrd(*this, insn.modrm().read32<ValueWithShadow<u32>>(*this, insn), const_gpr32(insn.reg32()), cl()));
|
insn.modrm().write32(*this, insn, op_shrd(*this, insn.modrm().read32(*this, insn), const_gpr32(insn.reg32()), cl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::SHRD_RM32_reg32_imm8(const X86::Instruction& insn)
|
void SoftCPU::SHRD_RM32_reg32_imm8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
insn.modrm().write32(*this, insn, op_shrd(*this, insn.modrm().read32<ValueWithShadow<u32>>(*this, insn), const_gpr32(insn.reg32()), shadow_wrap_as_initialized(insn.imm8())));
|
insn.modrm().write32(*this, insn, op_shrd(*this, insn.modrm().read32(*this, insn), const_gpr32(insn.reg32()), shadow_wrap_as_initialized(insn.imm8())));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_GENERIC_SHIFT_ROTATE_INSN_HANDLERS(SHR, op_shr)
|
DEFINE_GENERIC_SHIFT_ROTATE_INSN_HANDLERS(SHR, op_shr)
|
||||||
|
@ -2614,7 +2614,7 @@ void SoftCPU::WBINVD(const X86::Instruction&) { TODO_INSN(); }
|
||||||
|
|
||||||
void SoftCPU::XADD_RM16_reg16(const X86::Instruction& insn)
|
void SoftCPU::XADD_RM16_reg16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto dest = insn.modrm().read16(*this, insn);
|
||||||
auto src = const_gpr16(insn.reg16());
|
auto src = const_gpr16(insn.reg16());
|
||||||
auto result = op_add(*this, dest, src);
|
auto result = op_add(*this, dest, src);
|
||||||
gpr16(insn.reg16()) = dest;
|
gpr16(insn.reg16()) = dest;
|
||||||
|
@ -2623,7 +2623,7 @@ void SoftCPU::XADD_RM16_reg16(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::XADD_RM32_reg32(const X86::Instruction& insn)
|
void SoftCPU::XADD_RM32_reg32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto dest = insn.modrm().read32(*this, insn);
|
||||||
auto src = const_gpr32(insn.reg32());
|
auto src = const_gpr32(insn.reg32());
|
||||||
auto result = op_add(*this, dest, src);
|
auto result = op_add(*this, dest, src);
|
||||||
gpr32(insn.reg32()) = dest;
|
gpr32(insn.reg32()) = dest;
|
||||||
|
@ -2632,7 +2632,7 @@ void SoftCPU::XADD_RM32_reg32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::XADD_RM8_reg8(const X86::Instruction& insn)
|
void SoftCPU::XADD_RM8_reg8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto dest = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto dest = insn.modrm().read8(*this, insn);
|
||||||
auto src = const_gpr8(insn.reg8());
|
auto src = const_gpr8(insn.reg8());
|
||||||
auto result = op_add(*this, dest, src);
|
auto result = op_add(*this, dest, src);
|
||||||
gpr8(insn.reg8()) = dest;
|
gpr8(insn.reg8()) = dest;
|
||||||
|
@ -2655,21 +2655,21 @@ void SoftCPU::XCHG_EAX_reg32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::XCHG_reg16_RM16(const X86::Instruction& insn)
|
void SoftCPU::XCHG_reg16_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto temp = insn.modrm().read16<ValueWithShadow<u16>>(*this, insn);
|
auto temp = insn.modrm().read16(*this, insn);
|
||||||
insn.modrm().write16(*this, insn, const_gpr16(insn.reg16()));
|
insn.modrm().write16(*this, insn, const_gpr16(insn.reg16()));
|
||||||
gpr16(insn.reg16()) = temp;
|
gpr16(insn.reg16()) = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::XCHG_reg32_RM32(const X86::Instruction& insn)
|
void SoftCPU::XCHG_reg32_RM32(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto temp = insn.modrm().read32<ValueWithShadow<u32>>(*this, insn);
|
auto temp = insn.modrm().read32(*this, insn);
|
||||||
insn.modrm().write32(*this, insn, const_gpr32(insn.reg32()));
|
insn.modrm().write32(*this, insn, const_gpr32(insn.reg32()));
|
||||||
gpr32(insn.reg32()) = temp;
|
gpr32(insn.reg32()) = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::XCHG_reg8_RM8(const X86::Instruction& insn)
|
void SoftCPU::XCHG_reg8_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto temp = insn.modrm().read8<ValueWithShadow<u8>>(*this, insn);
|
auto temp = insn.modrm().read8(*this, insn);
|
||||||
insn.modrm().write8(*this, insn, const_gpr8(insn.reg8()));
|
insn.modrm().write8(*this, insn, const_gpr8(insn.reg8()));
|
||||||
gpr8(insn.reg8()) = temp;
|
gpr8(insn.reg8()) = temp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,11 @@ class SoftCPU final
|
||||||
: public X86::Interpreter
|
: public X86::Interpreter
|
||||||
, public X86::InstructionStream {
|
, public X86::InstructionStream {
|
||||||
public:
|
public:
|
||||||
|
using ValueWithShadowType8 = ValueWithShadow<u8>;
|
||||||
|
using ValueWithShadowType16 = ValueWithShadow<u16>;
|
||||||
|
using ValueWithShadowType32 = ValueWithShadow<u32>;
|
||||||
|
using ValueWithShadowType64 = ValueWithShadow<u64>;
|
||||||
|
|
||||||
explicit SoftCPU(Emulator&);
|
explicit SoftCPU(Emulator&);
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
|
|
|
@ -395,14 +395,14 @@ public:
|
||||||
template<typename CPU, typename T>
|
template<typename CPU, typename T>
|
||||||
void write64(CPU&, const Instruction&, T);
|
void write64(CPU&, const Instruction&, T);
|
||||||
|
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
T read8(CPU&, const Instruction&);
|
typename CPU::ValueWithShadowType8 read8(CPU&, const Instruction&);
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
T read16(CPU&, const Instruction&);
|
typename CPU::ValueWithShadowType16 read16(CPU&, const Instruction&);
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
T read32(CPU&, const Instruction&);
|
typename CPU::ValueWithShadowType32 read32(CPU&, const Instruction&);
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
T read64(CPU&, const Instruction&);
|
typename CPU::ValueWithShadowType64 read64(CPU&, const Instruction&);
|
||||||
|
|
||||||
template<typename CPU>
|
template<typename CPU>
|
||||||
LogicalAddress resolve(const CPU&, const Instruction&);
|
LogicalAddress resolve(const CPU&, const Instruction&);
|
||||||
|
@ -771,8 +771,8 @@ ALWAYS_INLINE void MemoryOrRegisterReference::write64(CPU& cpu, const Instructio
|
||||||
cpu.write_memory64(address, value);
|
cpu.write_memory64(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
ALWAYS_INLINE T MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& insn)
|
ALWAYS_INLINE typename CPU::ValueWithShadowType8 MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& insn)
|
||||||
{
|
{
|
||||||
if (is_register())
|
if (is_register())
|
||||||
return cpu.const_gpr8(reg8());
|
return cpu.const_gpr8(reg8());
|
||||||
|
@ -781,8 +781,8 @@ ALWAYS_INLINE T MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& in
|
||||||
return cpu.read_memory8(address);
|
return cpu.read_memory8(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
ALWAYS_INLINE T MemoryOrRegisterReference::read16(CPU& cpu, const Instruction& insn)
|
ALWAYS_INLINE typename CPU::ValueWithShadowType16 MemoryOrRegisterReference::read16(CPU& cpu, const Instruction& insn)
|
||||||
{
|
{
|
||||||
if (is_register())
|
if (is_register())
|
||||||
return cpu.const_gpr16(reg16());
|
return cpu.const_gpr16(reg16());
|
||||||
|
@ -791,8 +791,8 @@ ALWAYS_INLINE T MemoryOrRegisterReference::read16(CPU& cpu, const Instruction& i
|
||||||
return cpu.read_memory16(address);
|
return cpu.read_memory16(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
ALWAYS_INLINE T MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& insn)
|
ALWAYS_INLINE typename CPU::ValueWithShadowType32 MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& insn)
|
||||||
{
|
{
|
||||||
if (is_register())
|
if (is_register())
|
||||||
return cpu.const_gpr32(reg32());
|
return cpu.const_gpr32(reg32());
|
||||||
|
@ -801,8 +801,8 @@ ALWAYS_INLINE T MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& i
|
||||||
return cpu.read_memory32(address);
|
return cpu.read_memory32(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename CPU>
|
template<typename CPU>
|
||||||
ALWAYS_INLINE T MemoryOrRegisterReference::read64(CPU& cpu, const Instruction& insn)
|
ALWAYS_INLINE typename CPU::ValueWithShadowType64 MemoryOrRegisterReference::read64(CPU& cpu, const Instruction& insn)
|
||||||
{
|
{
|
||||||
ASSERT(!is_register());
|
ASSERT(!is_register());
|
||||||
auto address = resolve(cpu, insn);
|
auto address = resolve(cpu, insn);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue