diff --git a/src/core/cpu_recompiler_code_generator.cpp b/src/core/cpu_recompiler_code_generator.cpp index 08c94bfa8..d31386526 100644 --- a/src/core/cpu_recompiler_code_generator.cpp +++ b/src/core/cpu_recompiler_code_generator.cpp @@ -329,8 +329,15 @@ Value CodeGenerator::AddValues(const Value& lhs, const Value& rhs, bool set_flag } else { - EmitCopyValue(res.host_reg, lhs); - EmitAdd(res.host_reg, rhs, set_flags); + if (lhs.IsInHostRegister()) + { + EmitAdd(res.host_reg, lhs.host_reg, rhs, set_flags); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitAdd(res.host_reg, res.host_reg, rhs, set_flags); + } return res; } } @@ -369,8 +376,16 @@ Value CodeGenerator::SubValues(const Value& lhs, const Value& rhs, bool set_flag } else { - EmitCopyValue(res.host_reg, lhs); - EmitSub(res.host_reg, rhs, set_flags); + if (lhs.IsInHostRegister()) + { + EmitSub(res.host_reg, lhs.host_reg, rhs, set_flags); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitSub(res.host_reg, res.host_reg, rhs, set_flags); + } + return res; } } @@ -469,9 +484,22 @@ Value CodeGenerator::ShlValues(const Value& lhs, const Value& rhs) } Value res = m_register_cache.AllocateScratch(lhs.size); - EmitCopyValue(res.host_reg, lhs); - if (!rhs.HasConstantValue(0)) - EmitShl(res.host_reg, res.size, rhs); + if (rhs.HasConstantValue(0)) + { + EmitCopyValue(res.host_reg, lhs); + } + else + { + if (lhs.IsInHostRegister()) + { + EmitShl(res.host_reg, lhs.host_reg, res.size, rhs); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitShl(res.host_reg, res.host_reg, res.size, rhs); + } + } return res; } @@ -502,9 +530,22 @@ Value CodeGenerator::ShrValues(const Value& lhs, const Value& rhs) } Value res = m_register_cache.AllocateScratch(lhs.size); - EmitCopyValue(res.host_reg, lhs); - if (!rhs.HasConstantValue(0)) - EmitShr(res.host_reg, res.size, rhs); + if (rhs.HasConstantValue(0)) + { + EmitCopyValue(res.host_reg, lhs); + } + else + { + if (lhs.IsInHostRegister()) + { + EmitShr(res.host_reg, lhs.host_reg, res.size, rhs); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitShr(res.host_reg, res.host_reg, res.size, rhs); + } + } return res; } @@ -538,9 +579,22 @@ Value CodeGenerator::SarValues(const Value& lhs, const Value& rhs) } Value res = m_register_cache.AllocateScratch(lhs.size); - EmitCopyValue(res.host_reg, lhs); - if (!rhs.HasConstantValue(0)) - EmitSar(res.host_reg, res.size, rhs); + if (rhs.HasConstantValue(0)) + { + EmitCopyValue(res.host_reg, lhs); + } + else + { + if (lhs.IsInHostRegister()) + { + EmitSar(res.host_reg, lhs.host_reg, res.size, rhs); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitSar(res.host_reg, res.host_reg, res.size, rhs); + } + } return res; } @@ -582,8 +636,15 @@ Value CodeGenerator::OrValues(const Value& lhs, const Value& rhs) return res; } - EmitCopyValue(res.host_reg, lhs); - EmitOr(res.host_reg, rhs); + if (lhs.IsInHostRegister()) + { + EmitOr(res.host_reg, lhs.host_reg, rhs); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitOr(res.host_reg, res.host_reg, rhs); + } return res; } @@ -617,12 +678,19 @@ Value CodeGenerator::AndValues(const Value& lhs, const Value& rhs) Value res = m_register_cache.AllocateScratch(lhs.size); if (lhs.HasConstantValue(0) || rhs.HasConstantValue(0)) { - EmitXor(res.host_reg, res); + EmitXor(res.host_reg, res.host_reg, res); return res; } - EmitCopyValue(res.host_reg, lhs); - EmitAnd(res.host_reg, rhs); + if (lhs.IsInHostRegister()) + { + EmitAnd(res.host_reg, lhs.host_reg, rhs); + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitAnd(res.host_reg, res.host_reg, rhs); + } return res; } @@ -665,8 +733,17 @@ Value CodeGenerator::XorValues(const Value& lhs, const Value& rhs) return res; } - EmitCopyValue(res.host_reg, lhs); - EmitXor(res.host_reg, rhs); + if (lhs.IsInHostRegister()) + { + EmitXor(res.host_reg, lhs.host_reg, rhs); + + } + else + { + EmitCopyValue(res.host_reg, lhs); + EmitXor(res.host_reg, res.host_reg, rhs); + } + return res; } @@ -942,7 +1019,7 @@ bool CodeGenerator::Compile_Shift(const CodeBlockInstruction& cbi) // rd <- rt op (rs & 0x1F) shamt = m_register_cache.ReadGuestRegister(cbi.instruction.r.rs); if constexpr (!SHIFTS_ARE_IMPLICITLY_MASKED) - EmitAnd(shamt.host_reg, Value::FromConstantU32(0x1F)); + EmitAnd(shamt.host_reg, shamt.host_reg, Value::FromConstantU32(0x1F)); } Value result; @@ -1414,10 +1491,7 @@ bool CodeGenerator::Compile_cop0(const CodeBlockInstruction& cbi) if (write_mask != UINT32_C(0xFFFFFFFF)) { // need to adjust the mask - Value scratch = m_register_cache.AllocateScratch(RegSize_32); - EmitCopyValue(scratch.host_reg, value); - EmitAnd(scratch.host_reg, Value::FromConstantU32(write_mask)); - value = std::move(scratch); + value = AndValues(value, Value::FromConstantU32(write_mask)); } EmitStoreCPUStructField(offset, value); @@ -1447,11 +1521,10 @@ bool CodeGenerator::Compile_cop0(const CodeBlockInstruction& cbi) EmitLoadCPUStructField(sr.host_reg, RegSize_32, offsetof(Core, m_cop0_regs.sr.bits)); { Value new_mode_bits = m_register_cache.AllocateScratch(RegSize_32); - EmitCopyValue(new_mode_bits.host_reg, sr); - EmitShr(new_mode_bits.host_reg, new_mode_bits.size, Value::FromConstantU32(2)); - EmitAnd(new_mode_bits.host_reg, Value::FromConstantU32(mode_bits_mask)); - EmitAnd(sr.host_reg, Value::FromConstantU32(~mode_bits_mask)); - EmitOr(sr.host_reg, new_mode_bits); + EmitShr(new_mode_bits.host_reg, sr.host_reg, new_mode_bits.size, Value::FromConstantU32(2)); + EmitAnd(new_mode_bits.host_reg, new_mode_bits.host_reg, Value::FromConstantU32(mode_bits_mask)); + EmitAnd(sr.host_reg, sr.host_reg, Value::FromConstantU32(~mode_bits_mask)); + EmitOr(sr.host_reg, sr.host_reg, new_mode_bits); } EmitStoreCPUStructField(offsetof(Core, m_cop0_regs.sr.bits), sr); diff --git a/src/core/cpu_recompiler_code_generator.h b/src/core/cpu_recompiler_code_generator.h index c401d7e07..123da732e 100644 --- a/src/core/cpu_recompiler_code_generator.h +++ b/src/core/cpu_recompiler_code_generator.h @@ -48,18 +48,18 @@ public: void EmitSignExtend(HostReg to_reg, RegSize to_size, HostReg from_reg, RegSize from_size); void EmitZeroExtend(HostReg to_reg, RegSize to_size, HostReg from_reg, RegSize from_size); void EmitCopyValue(HostReg to_reg, const Value& value); - void EmitAdd(HostReg to_reg, const Value& value, bool set_flags); - void EmitSub(HostReg to_reg, const Value& value, bool set_flags); + void EmitAdd(HostReg to_reg, HostReg from_reg, const Value& value, bool set_flags); + void EmitSub(HostReg to_reg, HostReg from_reg, const Value& value, bool set_flags); void EmitCmp(HostReg to_reg, const Value& value); void EmitMul(HostReg to_reg_hi, HostReg to_reg_lo, const Value& lhs, const Value& rhs, bool signed_multiply); void EmitInc(HostReg to_reg, RegSize size); void EmitDec(HostReg to_reg, RegSize size); - void EmitShl(HostReg to_reg, RegSize size, const Value& amount_value); - void EmitShr(HostReg to_reg, RegSize size, const Value& amount_value); - void EmitSar(HostReg to_reg, RegSize size, const Value& amount_value); - void EmitAnd(HostReg to_reg, const Value& value); - void EmitOr(HostReg to_reg, const Value& value); - void EmitXor(HostReg to_reg, const Value& value); + void EmitShl(HostReg to_reg, HostReg from_reg, RegSize size, const Value& amount_value); + void EmitShr(HostReg to_reg, HostReg from_reg, RegSize size, const Value& amount_value); + void EmitSar(HostReg to_reg, HostReg from_reg, RegSize size, const Value& amount_value); + void EmitAnd(HostReg to_reg, HostReg from_reg, const Value& value); + void EmitOr(HostReg to_reg, HostReg from_reg, const Value& value); + void EmitXor(HostReg to_reg, HostReg from_reg, const Value& value); void EmitTest(HostReg to_reg, const Value& value); void EmitNot(HostReg to_reg, RegSize size); void EmitSetConditionResult(HostReg to_reg, RegSize to_size, Condition condition); diff --git a/src/core/cpu_recompiler_code_generator_x64.cpp b/src/core/cpu_recompiler_code_generator_x64.cpp index f4bdaabf9..4c73d465a 100644 --- a/src/core/cpu_recompiler_code_generator_x64.cpp +++ b/src/core/cpu_recompiler_code_generator_x64.cpp @@ -366,7 +366,7 @@ void CodeGenerator::EmitCopyValue(HostReg to_reg, const Value& value) } } -void CodeGenerator::EmitAdd(HostReg to_reg, const Value& value, bool set_flags) +void CodeGenerator::EmitAdd(HostReg to_reg, HostReg from_reg, const Value& value, bool set_flags) { DebugAssert(value.IsConstant() || value.IsInHostRegister()); @@ -374,6 +374,9 @@ void CodeGenerator::EmitAdd(HostReg to_reg, const Value& value, bool set_flags) { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (value.IsConstant()) m_emit->add(GetHostReg8(to_reg), SignExtend32(Truncate8(value.constant_value))); else @@ -383,6 +386,9 @@ void CodeGenerator::EmitAdd(HostReg to_reg, const Value& value, bool set_flags) case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (value.IsConstant()) m_emit->add(GetHostReg16(to_reg), SignExtend32(Truncate16(value.constant_value))); else @@ -392,6 +398,9 @@ void CodeGenerator::EmitAdd(HostReg to_reg, const Value& value, bool set_flags) case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (value.IsConstant()) m_emit->add(GetHostReg32(to_reg), Truncate32(value.constant_value)); else @@ -401,6 +410,9 @@ void CodeGenerator::EmitAdd(HostReg to_reg, const Value& value, bool set_flags) case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (value.IsConstant()) { if (!Xbyak::inner::IsInInt32(value.constant_value)) @@ -423,7 +435,7 @@ void CodeGenerator::EmitAdd(HostReg to_reg, const Value& value, bool set_flags) } } -void CodeGenerator::EmitSub(HostReg to_reg, const Value& value, bool set_flags) +void CodeGenerator::EmitSub(HostReg to_reg, HostReg from_reg, const Value& value, bool set_flags) { DebugAssert(value.IsConstant() || value.IsInHostRegister()); @@ -431,6 +443,9 @@ void CodeGenerator::EmitSub(HostReg to_reg, const Value& value, bool set_flags) { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (value.IsConstant()) m_emit->sub(GetHostReg8(to_reg), SignExtend32(Truncate8(value.constant_value))); else @@ -440,6 +455,9 @@ void CodeGenerator::EmitSub(HostReg to_reg, const Value& value, bool set_flags) case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (value.IsConstant()) m_emit->sub(GetHostReg16(to_reg), SignExtend32(Truncate16(value.constant_value))); else @@ -449,6 +467,9 @@ void CodeGenerator::EmitSub(HostReg to_reg, const Value& value, bool set_flags) case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (value.IsConstant()) m_emit->sub(GetHostReg32(to_reg), Truncate32(value.constant_value)); else @@ -458,6 +479,9 @@ void CodeGenerator::EmitSub(HostReg to_reg, const Value& value, bool set_flags) case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (value.IsConstant()) { if (!Xbyak::inner::IsInInt32(value.constant_value)) @@ -691,7 +715,7 @@ void CodeGenerator::EmitDec(HostReg to_reg, RegSize size) } } -void CodeGenerator::EmitShl(HostReg to_reg, RegSize size, const Value& amount_value) +void CodeGenerator::EmitShl(HostReg to_reg, HostReg from_reg, RegSize size, const Value& amount_value) { DebugAssert(amount_value.IsConstant() || amount_value.IsInHostRegister()); @@ -708,6 +732,9 @@ void CodeGenerator::EmitShl(HostReg to_reg, RegSize size, const Value& amount_va { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (amount_value.IsConstant()) m_emit->shl(GetHostReg8(to_reg), Truncate8(amount_value.constant_value)); else @@ -717,6 +744,9 @@ void CodeGenerator::EmitShl(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (amount_value.IsConstant()) m_emit->shl(GetHostReg16(to_reg), Truncate8(amount_value.constant_value)); else @@ -726,6 +756,9 @@ void CodeGenerator::EmitShl(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (amount_value.IsConstant()) m_emit->shl(GetHostReg32(to_reg), Truncate32(amount_value.constant_value)); else @@ -735,6 +768,9 @@ void CodeGenerator::EmitShl(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (amount_value.IsConstant()) m_emit->shl(GetHostReg64(to_reg), Truncate32(amount_value.constant_value)); else @@ -747,7 +783,7 @@ void CodeGenerator::EmitShl(HostReg to_reg, RegSize size, const Value& amount_va m_emit->pop(m_emit->rcx); } -void CodeGenerator::EmitShr(HostReg to_reg, RegSize size, const Value& amount_value) +void CodeGenerator::EmitShr(HostReg to_reg, HostReg from_reg, RegSize size, const Value& amount_value) { DebugAssert(amount_value.IsConstant() || amount_value.IsInHostRegister()); @@ -764,6 +800,9 @@ void CodeGenerator::EmitShr(HostReg to_reg, RegSize size, const Value& amount_va { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (amount_value.IsConstant()) m_emit->shr(GetHostReg8(to_reg), Truncate8(amount_value.constant_value)); else @@ -773,6 +812,9 @@ void CodeGenerator::EmitShr(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (amount_value.IsConstant()) m_emit->shr(GetHostReg16(to_reg), Truncate8(amount_value.constant_value)); else @@ -782,6 +824,9 @@ void CodeGenerator::EmitShr(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (amount_value.IsConstant()) m_emit->shr(GetHostReg32(to_reg), Truncate32(amount_value.constant_value)); else @@ -791,6 +836,9 @@ void CodeGenerator::EmitShr(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (amount_value.IsConstant()) m_emit->shr(GetHostReg64(to_reg), Truncate32(amount_value.constant_value)); else @@ -803,7 +851,7 @@ void CodeGenerator::EmitShr(HostReg to_reg, RegSize size, const Value& amount_va m_emit->pop(m_emit->rcx); } -void CodeGenerator::EmitSar(HostReg to_reg, RegSize size, const Value& amount_value) +void CodeGenerator::EmitSar(HostReg to_reg, HostReg from_reg, RegSize size, const Value& amount_value) { DebugAssert(amount_value.IsConstant() || amount_value.IsInHostRegister()); @@ -820,6 +868,9 @@ void CodeGenerator::EmitSar(HostReg to_reg, RegSize size, const Value& amount_va { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (amount_value.IsConstant()) m_emit->sar(GetHostReg8(to_reg), Truncate8(amount_value.constant_value)); else @@ -829,6 +880,9 @@ void CodeGenerator::EmitSar(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (amount_value.IsConstant()) m_emit->sar(GetHostReg16(to_reg), Truncate8(amount_value.constant_value)); else @@ -838,6 +892,9 @@ void CodeGenerator::EmitSar(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (amount_value.IsConstant()) m_emit->sar(GetHostReg32(to_reg), Truncate32(amount_value.constant_value)); else @@ -847,6 +904,9 @@ void CodeGenerator::EmitSar(HostReg to_reg, RegSize size, const Value& amount_va case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (amount_value.IsConstant()) m_emit->sar(GetHostReg64(to_reg), Truncate32(amount_value.constant_value)); else @@ -859,13 +919,16 @@ void CodeGenerator::EmitSar(HostReg to_reg, RegSize size, const Value& amount_va m_emit->pop(m_emit->rcx); } -void CodeGenerator::EmitAnd(HostReg to_reg, const Value& value) +void CodeGenerator::EmitAnd(HostReg to_reg, HostReg from_reg, const Value& value) { DebugAssert(value.IsConstant() || value.IsInHostRegister()); switch (value.size) { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (value.IsConstant()) m_emit->and_(GetHostReg8(to_reg), Truncate32(value.constant_value & UINT32_C(0xFF))); else @@ -875,6 +938,9 @@ void CodeGenerator::EmitAnd(HostReg to_reg, const Value& value) case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (value.IsConstant()) m_emit->and_(GetHostReg16(to_reg), Truncate32(value.constant_value & UINT32_C(0xFFFF))); else @@ -884,6 +950,9 @@ void CodeGenerator::EmitAnd(HostReg to_reg, const Value& value) case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (value.IsConstant()) m_emit->and_(GetHostReg32(to_reg), Truncate32(value.constant_value)); else @@ -893,6 +962,9 @@ void CodeGenerator::EmitAnd(HostReg to_reg, const Value& value) case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (value.IsConstant()) { if (!Xbyak::inner::IsInInt32(value.constant_value)) @@ -915,13 +987,16 @@ void CodeGenerator::EmitAnd(HostReg to_reg, const Value& value) } } -void CodeGenerator::EmitOr(HostReg to_reg, const Value& value) +void CodeGenerator::EmitOr(HostReg to_reg, HostReg from_reg, const Value& value) { DebugAssert(value.IsConstant() || value.IsInHostRegister()); switch (value.size) { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (value.IsConstant()) m_emit->or_(GetHostReg8(to_reg), Truncate32(value.constant_value & UINT32_C(0xFF))); else @@ -931,6 +1006,9 @@ void CodeGenerator::EmitOr(HostReg to_reg, const Value& value) case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (value.IsConstant()) m_emit->or_(GetHostReg16(to_reg), Truncate32(value.constant_value & UINT32_C(0xFFFF))); else @@ -940,6 +1018,9 @@ void CodeGenerator::EmitOr(HostReg to_reg, const Value& value) case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (value.IsConstant()) m_emit->or_(GetHostReg32(to_reg), Truncate32(value.constant_value)); else @@ -949,6 +1030,9 @@ void CodeGenerator::EmitOr(HostReg to_reg, const Value& value) case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (value.IsConstant()) { if (!Xbyak::inner::IsInInt32(value.constant_value)) @@ -971,13 +1055,16 @@ void CodeGenerator::EmitOr(HostReg to_reg, const Value& value) } } -void CodeGenerator::EmitXor(HostReg to_reg, const Value& value) +void CodeGenerator::EmitXor(HostReg to_reg, HostReg from_reg, const Value& value) { DebugAssert(value.IsConstant() || value.IsInHostRegister()); switch (value.size) { case RegSize_8: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg8(to_reg), GetHostReg8(from_reg)); + if (value.IsConstant()) m_emit->xor_(GetHostReg8(to_reg), Truncate32(value.constant_value & UINT32_C(0xFF))); else @@ -987,6 +1074,9 @@ void CodeGenerator::EmitXor(HostReg to_reg, const Value& value) case RegSize_16: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg16(to_reg), GetHostReg16(from_reg)); + if (value.IsConstant()) m_emit->xor_(GetHostReg16(to_reg), Truncate32(value.constant_value & UINT32_C(0xFFFF))); else @@ -996,6 +1086,9 @@ void CodeGenerator::EmitXor(HostReg to_reg, const Value& value) case RegSize_32: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg32(to_reg), GetHostReg32(from_reg)); + if (value.IsConstant()) m_emit->xor_(GetHostReg32(to_reg), Truncate32(value.constant_value)); else @@ -1005,6 +1098,9 @@ void CodeGenerator::EmitXor(HostReg to_reg, const Value& value) case RegSize_64: { + if (to_reg != from_reg) + m_emit->mov(GetHostReg64(to_reg), GetHostReg64(from_reg)); + if (value.IsConstant()) { if (!Xbyak::inner::IsInInt32(value.constant_value)) diff --git a/src/core/cpu_recompiler_register_cache.cpp b/src/core/cpu_recompiler_register_cache.cpp index 3306ef8ff..c8670a831 100644 --- a/src/core/cpu_recompiler_register_cache.cpp +++ b/src/core/cpu_recompiler_register_cache.cpp @@ -394,7 +394,7 @@ Value RegisterCache::ReadGuestRegister(Reg guest_reg, bool cache /* = true */, b if (force_host_register) { Value temp = AllocateScratch(RegSize_32, forced_host_reg); - m_code_generator.EmitXor(temp.host_reg, temp); + m_code_generator.EmitXor(temp.host_reg, temp.host_reg, temp); return temp; }