diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index f39c7516e3..6fd886ea0c 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 lfsu(UGeckoInstruction _inst); void lfsx(UGeckoInstruction _inst); void lfd(UGeckoInstruction _inst); void stfs(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index 054b8d3790..9873c0d479 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -27,7 +27,6 @@ #include "JitRegCache.h" #include "JitAsm.h" extern u32 Helper_Mask(u8 mb, u8 me); -// ADDI and RLWINMX broken for now // Assumes that Sign and Zero flags were set by the last operation. Preserves all flags and registers. // Jit64 ComputerRC is signed @@ -204,9 +203,9 @@ void JitArm::arith(UGeckoInstruction inst) isImm[1] = true; Imm[1] = inst.UIMM << (shiftedImm ? 16 : 0); break; - case 29: // addis_rc + case 29: // andis_rc shiftedImm = true; - case 28: // addi_rc + case 28: // andi_rc if (gpr.IsImm(s)) { isImm[0] = true; diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index e391e768fb..723430cc95 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -56,19 +56,54 @@ void JitArm::lfs(UGeckoInstruction inst) CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); - MOVI2R(rA, (u32)&Memory::Read_F32); + MOVI2R(rA, (u32)&Memory::Read_U32); PUSH(4, R0, R1, R2, R3); MOV(R0, rB); BL(rA); -#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 VMOV(S0, R0); -#endif VCVT(v0, S0, 0); VCVT(v1, S0, 0); POP(4, R0, R1, R2, R3); + gpr.Unlock(rA, rB); + SetJumpTarget(DoNotLoad); +} +void JitArm::lfsu(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreFloatingOff) + + ARMReg RA = gpr.R(inst.RA); + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + + ARMReg v0 = fpr.R0(inst.FD); + ARMReg v1 = fpr.R1(inst.FD); + + MOVI2R(rB, inst.SIMM_16); + ADD(rB, rB, RA); + + LDR(rA, R9, PPCSTATE_OFF(Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); + + MOVI2R(rA, (u32)&Memory::Read_U32); + + MOV(RA, rB); + 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); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index fd2d53bd40..6f649f2890 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -98,7 +98,7 @@ static GekkoOPTemplate primarytable[] = {47, &JitArm::Default}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, {48, &JitArm::lfs}, //"lfs", OPTYPE_LOADFP, FL_IN_A}}, - {49, &JitArm::Default}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + {49, &JitArm::lfsu}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, {50, &JitArm::lfd}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, {51, &JitArm::Default}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}},