JitArm64: Factor out single/double conversion code to functions
Preparation for following commits. This commit intentionally doesn't touch paired stores, since paired stores are supposed to flush to zero. (Consistent with Jit64.)
This commit is contained in:
parent
fdf7744a53
commit
949686bbe7
|
@ -152,6 +152,11 @@ public:
|
|||
void psq_l(UGeckoInstruction inst);
|
||||
void psq_st(UGeckoInstruction inst);
|
||||
|
||||
void ConvertDoubleToSingleLower(Arm64Gen::ARM64Reg dest_reg, Arm64Gen::ARM64Reg src_reg);
|
||||
void ConvertDoubleToSinglePair(Arm64Gen::ARM64Reg dest_reg, Arm64Gen::ARM64Reg src_reg);
|
||||
void ConvertSingleToDoubleLower(Arm64Gen::ARM64Reg dest_reg, Arm64Gen::ARM64Reg src_reg);
|
||||
void ConvertSingleToDoublePair(Arm64Gen::ARM64Reg dest_reg, Arm64Gen::ARM64Reg src_reg);
|
||||
|
||||
private:
|
||||
struct SlowmemHandler
|
||||
{
|
||||
|
|
|
@ -386,3 +386,23 @@ void JitArm64::fctiwzx(UGeckoInstruction inst)
|
|||
ASSERT_MSG(DYNA_REC, b == d || single == fpr.IsSingle(b, true),
|
||||
"Register allocation turned singles into doubles in the middle of fctiwzx");
|
||||
}
|
||||
|
||||
void JitArm64::ConvertDoubleToSingleLower(ARM64Reg dest_reg, ARM64Reg src_reg)
|
||||
{
|
||||
m_float_emit.FCVT(32, 64, EncodeRegToDouble(dest_reg), EncodeRegToDouble(src_reg));
|
||||
}
|
||||
|
||||
void JitArm64::ConvertDoubleToSinglePair(ARM64Reg dest_reg, ARM64Reg src_reg)
|
||||
{
|
||||
m_float_emit.FCVTN(32, EncodeRegToDouble(dest_reg), EncodeRegToDouble(src_reg));
|
||||
}
|
||||
|
||||
void JitArm64::ConvertSingleToDoubleLower(ARM64Reg dest_reg, ARM64Reg src_reg)
|
||||
{
|
||||
m_float_emit.FCVT(64, 32, EncodeRegToDouble(dest_reg), EncodeRegToDouble(src_reg));
|
||||
}
|
||||
|
||||
void JitArm64::ConvertSingleToDoublePair(ARM64Reg dest_reg, ARM64Reg src_reg)
|
||||
{
|
||||
m_float_emit.FCVTL(64, EncodeRegToDouble(dest_reg), EncodeRegToDouble(src_reg));
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
|||
if (want_single && !have_single)
|
||||
{
|
||||
const ARM64Reg single_reg = fpr.GetReg();
|
||||
m_float_emit.FCVT(32, 64, EncodeRegToDouble(single_reg), EncodeRegToDouble(V0));
|
||||
ConvertDoubleToSingleLower(single_reg, V0);
|
||||
V0 = single_reg;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
using namespace Arm64Gen;
|
||||
|
||||
void Arm64RegCache::Init(ARM64XEmitter* emitter)
|
||||
void Arm64RegCache::Init(JitArm64* jit)
|
||||
{
|
||||
m_emit = emitter;
|
||||
m_jit = jit;
|
||||
m_emit = jit;
|
||||
m_float_emit.reset(new ARM64FloatEmitter(m_emit));
|
||||
GetAllocationOrder();
|
||||
}
|
||||
|
@ -467,7 +468,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
|
|||
return host_reg;
|
||||
|
||||
// Else convert this register back to doubles.
|
||||
m_float_emit->FCVTL(64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoublePair(host_reg, host_reg);
|
||||
reg.Load(host_reg, RegType::Register);
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
@ -482,7 +483,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
|
|||
return host_reg;
|
||||
|
||||
// Else convert this register back to a double.
|
||||
m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoubleLower(host_reg, host_reg);
|
||||
reg.Load(host_reg, RegType::LowerPair);
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
@ -516,7 +517,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
|
|||
return host_reg;
|
||||
}
|
||||
|
||||
m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoubleLower(host_reg, host_reg);
|
||||
reg.Load(host_reg, RegType::Duplicated);
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
@ -593,7 +594,7 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type)
|
|||
{
|
||||
case RegType::Single:
|
||||
flush_reg = GetReg();
|
||||
m_float_emit->FCVTL(64, EncodeRegToDouble(flush_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoublePair(flush_reg, host_reg);
|
||||
[[fallthrough]];
|
||||
case RegType::Register:
|
||||
// We are doing a full 128bit store because it takes 2 cycles on a Cortex-A57 to do a 128bit
|
||||
|
@ -604,7 +605,7 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type)
|
|||
break;
|
||||
case RegType::DuplicatedSingle:
|
||||
flush_reg = GetReg();
|
||||
m_float_emit->FCVT(64, 32, EncodeRegToDouble(flush_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoubleLower(flush_reg, host_reg);
|
||||
[[fallthrough]];
|
||||
case RegType::Duplicated:
|
||||
// Store PSR1 (which is equal to PSR0) in memory.
|
||||
|
@ -712,13 +713,13 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state)
|
|||
if (type == RegType::Single)
|
||||
{
|
||||
if (dirty)
|
||||
m_float_emit->FCVTL(64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoublePair(host_reg, host_reg);
|
||||
type = RegType::Register;
|
||||
}
|
||||
if (type == RegType::DuplicatedSingle || type == RegType::LowerPairSingle)
|
||||
{
|
||||
if (dirty)
|
||||
m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
|
||||
m_jit->ConvertSingleToDoubleLower(host_reg, host_reg);
|
||||
|
||||
if (type == RegType::DuplicatedSingle)
|
||||
type = RegType::Duplicated;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
class JitArm64;
|
||||
|
||||
// Dedicated host registers
|
||||
|
||||
// memory base register
|
||||
|
@ -150,7 +152,7 @@ public:
|
|||
explicit Arm64RegCache(size_t guest_reg_count) : m_guest_registers(guest_reg_count) {}
|
||||
virtual ~Arm64RegCache() = default;
|
||||
|
||||
void Init(Arm64Gen::ARM64XEmitter* emitter);
|
||||
void Init(JitArm64* jit);
|
||||
|
||||
virtual void Start(PPCAnalyst::BlockRegStats& stats) {}
|
||||
void DiscardRegisters(BitSet32 regs);
|
||||
|
@ -218,6 +220,8 @@ protected:
|
|||
reg.IncrementLastUsed();
|
||||
}
|
||||
|
||||
JitArm64* m_jit = nullptr;
|
||||
|
||||
// Code emitter
|
||||
Arm64Gen::ARM64XEmitter* m_emit = nullptr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue