diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 58c6cbda16..f39c7516e3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -198,6 +198,7 @@ public: // Floating point loadStore void lfs(UGeckoInstruction _inst); + void lfsx(UGeckoInstruction _inst); void lfd(UGeckoInstruction _inst); void stfs(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index 2559c9f49e..e391e768fb 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -40,11 +40,8 @@ void JitArm::lfs(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - fpr.Flush(); - - LDR(rA, R9, PPCSTATE_OFF(Exceptions)); - CMP(rA, EXCEPTION_DSI); - FixupBranch DoNotLoad = B_CC(CC_EQ); + ARMReg v0 = fpr.R0(inst.FD); + ARMReg v1 = fpr.R1(inst.FD); if (inst.RA) { @@ -55,14 +52,15 @@ void JitArm::lfs(UGeckoInstruction inst) else MOVI2R(rB, (u32)inst.SIMM_16); - + LDR(rA, R9, PPCSTATE_OFF(Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); + MOVI2R(rA, (u32)&Memory::Read_F32); PUSH(4, R0, R1, R2, R3); MOV(R0, rB); BL(rA); - ARMReg v0 = fpr.R0(inst.FD); - ARMReg v1 = fpr.R1(inst.FD); #if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 VMOV(S0, R0); #endif @@ -75,6 +73,41 @@ void JitArm::lfs(UGeckoInstruction inst) SetJumpTarget(DoNotLoad); } +void JitArm::lfsx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreFloatingOff) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + + ARMReg RB = gpr.R(inst.RB); + ARMReg v0 = fpr.R0(inst.FD); + ARMReg v1 = fpr.R1(inst.FD); + + if (inst.RA) + ADD(rB, RB, gpr.R(inst.RA)); + else + MOV(rB, RB); + + LDR(rA, R9, PPCSTATE_OFF(Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); + + MOVI2R(rA, (u32)&Memory::Read_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + + VMOV(S0, R0); + VCVT(v0, S0, 0); + VCVT(v1, S0, 0); + POP(4, R0, R1, R2, R3); + + gpr.Unlock(rA, rB); + SetJumpTarget(DoNotLoad); +} + void JitArm::lfd(UGeckoInstruction inst) { INSTRUCTION_START @@ -83,11 +116,7 @@ void JitArm::lfd(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - fpr.Flush(); - - LDR(rA, R9, PPCSTATE_OFF(Exceptions)); - CMP(rA, EXCEPTION_DSI); - FixupBranch DoNotLoad = B_CC(CC_EQ); + ARMReg v0 = fpr.R0(inst.FD); if (inst.RA) { @@ -98,13 +127,15 @@ void JitArm::lfd(UGeckoInstruction inst) else MOVI2R(rB, (u32)inst.SIMM_16); + LDR(rA, R9, PPCSTATE_OFF(Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); MOVI2R(rA, (u32)&Memory::Read_F64); PUSH(4, R0, R1, R2, R3); MOV(R0, rB); BL(rA); - ARMReg v0 = fpr.R0(inst.FD); #if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1 VMOV(v0, R0); #else @@ -126,7 +157,6 @@ void JitArm::stfs(UGeckoInstruction inst) ARMReg rB = gpr.GetReg(); ARMReg v0 = fpr.R0(inst.FS); VCVT(S0, v0, 0); - fpr.Flush(); if (inst.RA) { diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 78e8e9d06b..fd2d53bd40 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -268,7 +268,7 @@ static GekkoOPTemplate table31[] = {725, &JitArm::Default}, //"stswi", OPTYPE_STORE, FL_EVIL}}, // fp load/store - {535, &JitArm::Default}, //"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, + {535, &JitArm::lfsx}, //"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, {567, &JitArm::Default}, //"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, {599, &JitArm::Default}, //"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, {631, &JitArm::Default}, //"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}},