diff --git a/src/core/cpu_recompiler_code_generator.h b/src/core/cpu_recompiler_code_generator.h index 941e1d1ab..5ddb6e09e 100644 --- a/src/core/cpu_recompiler_code_generator.h +++ b/src/core/cpu_recompiler_code_generator.h @@ -179,6 +179,7 @@ private: void ConvertValueSizeInPlace(Value* value, RegSize size, bool sign_extend); Value GetValueInHostRegister(const Value& value, bool allow_zero_register = true); + Value GetValueInHostOrScratchRegister(const Value& value, bool allow_zero_register = true); void SwitchToFarCode(); void SwitchToNearCode(); diff --git a/src/core/cpu_recompiler_code_generator_aarch64.cpp b/src/core/cpu_recompiler_code_generator_aarch64.cpp index 25bfe301b..6ada14a32 100644 --- a/src/core/cpu_recompiler_code_generator_aarch64.cpp +++ b/src/core/cpu_recompiler_code_generator_aarch64.cpp @@ -182,6 +182,19 @@ Value CodeGenerator::GetValueInHostRegister(const Value& value, bool allow_zero_ return new_value; } +Value CodeGenerator::GetValueInHostOrScratchRegister(const Value& value, bool allow_zero_register /* = true */) +{ + if (value.IsInHostRegister()) + return Value::FromHostReg(&m_register_cache, value.host_reg, value.size); + + if (value.HasConstantValue(0) && allow_zero_register) + return Value::FromHostReg(&m_register_cache, static_cast(31), value.size); + + Value new_value = Value::FromHostReg(&m_register_cache, RSCRATCH, value.size); + EmitCopyValue(new_value.host_reg, value); + return new_value; +} + void CodeGenerator::EmitBeginBlock() { m_emit->Sub(a64::sp, a64::sp, FUNCTION_STACK_SIZE); diff --git a/src/core/cpu_recompiler_code_generator_x64.cpp b/src/core/cpu_recompiler_code_generator_x64.cpp index c40f477a2..4cea1c964 100644 --- a/src/core/cpu_recompiler_code_generator_x64.cpp +++ b/src/core/cpu_recompiler_code_generator_x64.cpp @@ -196,6 +196,16 @@ Value CodeGenerator::GetValueInHostRegister(const Value& value, bool allow_zero_ return new_value; } +Value CodeGenerator::GetValueInHostOrScratchRegister(const Value& value, bool allow_zero_register /* = true */) +{ + if (value.IsInHostRegister()) + return Value(value.regcache, value.host_reg, value.size, ValueFlags::Valid | ValueFlags::InHostRegister); + + Value new_value = m_register_cache.AllocateScratch(value.size); + EmitCopyValue(new_value.host_reg, value); + return new_value; +} + void CodeGenerator::EmitBeginBlock() { m_register_cache.AssumeCalleeSavedRegistersAreSaved();