diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index aa5d389827..4f8ea466f4 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -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 { diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp index b6a99f1c0b..482095d251 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp @@ -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)); +} diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp index 5056c3b1ca..3509df1936 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp @@ -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; } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index e41ffdbfa8..4b2ecd81e7 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -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; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index edee9f2a85..465e8fef67 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -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;