diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 6bef59aa03..e5a07b3bac 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -189,6 +189,7 @@ public: // Floating point loadStore void lfs(UGeckoInstruction _inst); + void lfd(UGeckoInstruction _inst); }; #endif // _JIT64_H diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index dd36f145a9..708aff9022 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -53,20 +53,51 @@ void JitArm::lfs(UGeckoInstruction inst) else MOVI2R(rB, (u32)inst.SIMM_16); - MOVI2R(rA, (u32)&Memory::Read_U32); + ARMReg v0 = fpr.R0(inst.FD, false); + ARMReg v1 = fpr.R1(inst.FD, false); + + MOVI2R(rA, (u32)&Memory::Read_F32); PUSH(4, R0, R1, R2, R3); MOV(R0, rB); BL(rA); - MOV(rA, R0); + // XXX: Need to use VCVT here. + VMOV(v0, D0); + VMOV(v1, D0); POP(4, R0, R1, R2, R3); - ARMReg v0 = fpr.R0(inst.FD, false); - ARMReg v1 = fpr.R1(inst.FD, false); - - VMOV(v0, rA, false); - VMOV(v1, rA, false); - gpr.Unlock(rA, rB); SetJumpTarget(DoNotLoad); } +void JitArm::lfd(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStoreFloating) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + LDR(rA, R9, PPCSTATE_OFF(Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); + + if (inst.RA) + { + MOVI2R(rB, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(rB, rB, RA); + } + else + MOVI2R(rB, (u32)inst.SIMM_16); + + ARMReg v0 = fpr.R0(inst.FD, false); + + MOVI2R(rA, (u32)&Memory::Read_F64); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + VMOV(v0, D0); + 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 4308a6765b..3b97640ff2 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -99,7 +99,7 @@ static GekkoOPTemplate primarytable[] = {48, &JitArm::lfs}, //"lfs", OPTYPE_LOADFP, FL_IN_A}}, {49, &JitArm::Default}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, - {50, &JitArm::Default}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, + {50, &JitArm::lfd}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, {51, &JitArm::Default}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, {52, &JitArm::Default}, //"stfs", OPTYPE_STOREFP, FL_IN_A}}, diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp index 535f8446c7..cdc13c48e2 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp @@ -56,9 +56,9 @@ ARMReg *ArmFPRCache::GetPPCAllocationOrder(int &count) // the ppc side. static ARMReg allocationOrder[] = { - D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, - D11, D12, D13, D14, D15, D16, D17, D18, D19, - D20, D21, D22, D23, D24, D25, D26, D27 + D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, + D14, D15, D16, D17, D18, D19, D20, D21, D22, + D23, D24, D25, D26, D27, D28, D29, D30, D31 }; count = sizeof(allocationOrder) / sizeof(const int); return allocationOrder; @@ -69,7 +69,7 @@ ARMReg *ArmFPRCache::GetAllocationOrder(int &count) // the host side. static ARMReg allocationOrder[] = { - D31, D30, D29, D28 + D0, D1, D2, D3 }; count = sizeof(allocationOrder) / sizeof(const int); return allocationOrder;