From b2d87c49b6c5f722308a71926b5150e37bc38153 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 12 Jul 2021 16:26:03 +0200 Subject: [PATCH] JitArm64: Implement mtfsb0x Part 3 of implementing the FPSCR system register instructions. --- Source/Core/Core/PowerPC/JitArm64/Jit.h | 4 ++- .../JitArm64/JitArm64_SystemRegisters.cpp | 33 +++++++++++++++++++ .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 2 +- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index ddab950334..f4ca4c0485 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -119,6 +119,7 @@ public: void mtcrf(UGeckoInstruction inst); void mcrfs(UGeckoInstruction inst); void mffsx(UGeckoInstruction inst); + void mtfsb0x(UGeckoInstruction inst); // LoadStore void lXX(UGeckoInstruction inst); @@ -261,8 +262,9 @@ protected: void FakeLKExit(u32 exit_address_after_return); void WriteBLRExit(Arm64Gen::ARM64Reg dest); - void FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg); Arm64Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set); + void FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg); + void UpdateRoundingMode(); void ComputeRC0(Arm64Gen::ARM64Reg reg); void ComputeRC0(u64 imm); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp index 3b3dff85d1..02c9e7a2e0 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp @@ -48,6 +48,19 @@ void JitArm64::FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg) gpr.Unlock(WA); } +void JitArm64::UpdateRoundingMode() +{ + const BitSet32 gprs_to_save = gpr.GetCallerSavedUsed(); + const BitSet32 fprs_to_save = fpr.GetCallerSavedUsed(); + + ABI_PushRegisters(gprs_to_save); + m_float_emit.ABI_PushRegisters(fprs_to_save, ARM64Reg::X8); + MOVP2R(ARM64Reg::X8, &PowerPC::RoundingModeUpdated); + BLR(ARM64Reg::X8); + m_float_emit.ABI_PopRegisters(fprs_to_save, ARM64Reg::X8); + ABI_PopRegisters(gprs_to_save); +} + void JitArm64::mtmsr(UGeckoInstruction inst) { INSTRUCTION_START @@ -754,3 +767,23 @@ void JitArm64::mffsx(UGeckoInstruction inst) gpr.Unlock(WA); gpr.Unlock(WB); } + +void JitArm64::mtfsb0x(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITSystemRegistersOff); + FALLBACK_IF(inst.Rc); + + u32 mask = ~(0x80000000 >> inst.CRBD); + + ARM64Reg WA = gpr.GetReg(); + + LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr)); + AND(WA, WA, LogicalImm(mask, 32)); + STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr)); + + gpr.Unlock(WA); + + if (inst.CRBD >= 29) + UpdateRoundingMode(); +} diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index 5f9af44d9b..00a563ad5c 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -316,7 +316,7 @@ constexpr std::array table63{{ {64, &JitArm64::mcrfs}, // mcrfs {583, &JitArm64::mffsx}, // mffsx - {70, &JitArm64::FallBackToInterpreter}, // mtfsb0x + {70, &JitArm64::mtfsb0x}, // mtfsb0x {38, &JitArm64::FallBackToInterpreter}, // mtfsb1x {134, &JitArm64::FallBackToInterpreter}, // mtfsfix {711, &JitArm64::FallBackToInterpreter}, // mtfsfx