From df7b4da13b9fd33ef2c9ae18cdfbf1d16fa981b4 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 31 Aug 2013 02:32:57 +0000 Subject: [PATCH] [ARM] Fastmem is back. Still disabled for Android. --- Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 2 + .../PowerPC/JitArm32/JitArm_FloatingPoint.cpp | 4 +- .../Src/PowerPC/JitArm32/JitArm_LoadStore.cpp | 38 ++++++++++++++++- .../JitArm32/JitArm_LoadStoreFloating.cpp | 42 ++++++++++++++++++- .../Src/PowerPC/JitArm32/JitArm_Tables.cpp | 6 +-- 5 files changed, 82 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index b8a7fdbfc8..fc1b08905e 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -197,6 +197,7 @@ public: void sthu(UGeckoInstruction _inst); void stw(UGeckoInstruction _inst); void stwu(UGeckoInstruction _inst); + void stwx(UGeckoInstruction _inst); // Floating point void fabsx(UGeckoInstruction _inst); @@ -211,6 +212,7 @@ public: // Floating point loadStore void lfs(UGeckoInstruction _inst); void lfd(UGeckoInstruction _inst); + void stfs(UGeckoInstruction _inst); // Paired Singles void ps_add(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp index 85ab5f3cae..c553397708 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp @@ -107,14 +107,11 @@ void JitArm::fsubx(UGeckoInstruction inst) if (inst.Rc) Helper_UpdateCR1(vD); } -// Breaks Animal Crossing void JitArm::fmulsx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(FloatingPoint) - Default(inst); return; - ARMReg vA = fpr.R0(inst.FA); ARMReg vC = fpr.R0(inst.FC); ARMReg vD0 = fpr.R0(inst.FD); @@ -122,6 +119,7 @@ void JitArm::fmulsx(UGeckoInstruction inst) VMUL(vD0, vA, vC); VMOV(vD1, vD0); + fpr.Flush(); // Shouldn't be needed. Missing a flush somewhere if (inst.Rc) Helper_UpdateCR1(vD0); } void JitArm::fmulx(UGeckoInstruction inst) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp index e019d3e353..c9d6394873 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -34,7 +34,7 @@ #ifdef ANDROID #define FASTMEM 0 #else -#define FASTMEM 0 +#define FASTMEM 1 #endif void JitArm::stb(UGeckoInstruction inst) { @@ -282,6 +282,40 @@ void JitArm::stwu(UGeckoInstruction inst) gpr.Unlock(ValueReg, Addr, Function); } +void JitArm::stwx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + u32 a = inst.RA, b = inst.RB, s = inst.RB; + + if (a) { + // Doesn't work + Default(inst); return; + } + + ARMReg RB = gpr.R(b); + ARMReg RS = gpr.R(s); + ARMReg ValueReg = gpr.GetReg(); + ARMReg Addr = gpr.GetReg(); + ARMReg Function = gpr.GetReg(); + + if (a) + ADD(Addr, gpr.R(a), RB); + else + MOV(Addr, RB); + + MOV(ValueReg, RS); + fpr.Flush(); + MOVI2R(Function, (u32)&Memory::Write_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, ValueReg); + MOV(R1, Addr); + BL(Function); + POP(4, R0, R1, R2, R3); + + gpr.Unlock(ValueReg, Addr, Function); +} + void JitArm::StoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset) { ARMReg rA = gpr.GetReg(); @@ -417,7 +451,7 @@ void JitArm::lhz(UGeckoInstruction inst) LDR(rA, R9, PPCSTATE_OFF(Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); -#if 0 // FASTMEM +#if FASTMEM // Backpatch route // Gets loaded in to RD // Address is in R10 diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index 178007f5b3..66a0912a18 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -39,6 +39,9 @@ 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); @@ -52,7 +55,6 @@ void JitArm::lfs(UGeckoInstruction inst) else MOVI2R(rB, (u32)inst.SIMM_16); - fpr.Flush(); MOVI2R(rA, (u32)&Memory::Read_F32); PUSH(4, R0, R1, R2, R3); @@ -80,6 +82,9 @@ 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); @@ -93,7 +98,6 @@ void JitArm::lfd(UGeckoInstruction inst) else MOVI2R(rB, (u32)inst.SIMM_16); - fpr.Flush(); MOVI2R(rA, (u32)&Memory::Read_F64); PUSH(4, R0, R1, R2, R3); @@ -112,3 +116,37 @@ void JitArm::lfd(UGeckoInstruction inst) gpr.Unlock(rA, rB); SetJumpTarget(DoNotLoad); } + +void JitArm::stfs(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStoreFloating) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + ARMReg v0 = fpr.R0(inst.FS); + VCVT(S0, v0, 0); + fpr.Flush(); + + 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); + + + MOVI2R(rA, (u32)&Memory::Write_U32); + PUSH(4, R0, R1, R2, R3); + VMOV(R0, S0); + MOV(R1, rB); + + BL(rA); + + POP(4, R0, R1, R2, R3); + + gpr.Unlock(rA, rB); +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index fe822179ed..3d52bf8d16 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -102,7 +102,7 @@ static GekkoOPTemplate primarytable[] = {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}}, + {52, &JitArm::stfs}, //"stfs", OPTYPE_STOREFP, FL_IN_A}}, {53, &JitArm::Default}, //"stfsu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, {54, &JitArm::Default}, //"stfd", OPTYPE_STOREFP, FL_IN_A}}, {55, &JitArm::Default}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, @@ -249,7 +249,7 @@ static GekkoOPTemplate table31[] = {597, &JitArm::Default}, //"lswi", OPTYPE_LOAD, FL_EVIL | FL_IN_AB | FL_OUT_D}}, //store word - {151, &JitArm::Default}, //"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {151, &JitArm::stwx}, //"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, {183, &JitArm::Default}, //"stwux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, //store halfword @@ -293,7 +293,7 @@ static GekkoOPTemplate table31[] = {659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, - {598, &JitArm::Default}, //"sync", OPTYPE_SYSTEM, 0, 2}}, + {598, &JitArm::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}}, {982, &JitArm::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}}, // Unused instructions on GC