mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-14 00:09:24 +01:00
[ARM] Fastmem is back. Still disabled for Android.
This commit is contained in:
parent
8b0a0daf10
commit
df7b4da13b
@ -197,6 +197,7 @@ public:
|
|||||||
void sthu(UGeckoInstruction _inst);
|
void sthu(UGeckoInstruction _inst);
|
||||||
void stw(UGeckoInstruction _inst);
|
void stw(UGeckoInstruction _inst);
|
||||||
void stwu(UGeckoInstruction _inst);
|
void stwu(UGeckoInstruction _inst);
|
||||||
|
void stwx(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Floating point
|
// Floating point
|
||||||
void fabsx(UGeckoInstruction _inst);
|
void fabsx(UGeckoInstruction _inst);
|
||||||
@ -211,6 +212,7 @@ public:
|
|||||||
// Floating point loadStore
|
// Floating point loadStore
|
||||||
void lfs(UGeckoInstruction _inst);
|
void lfs(UGeckoInstruction _inst);
|
||||||
void lfd(UGeckoInstruction _inst);
|
void lfd(UGeckoInstruction _inst);
|
||||||
|
void stfs(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Paired Singles
|
// Paired Singles
|
||||||
void ps_add(UGeckoInstruction _inst);
|
void ps_add(UGeckoInstruction _inst);
|
||||||
|
@ -107,14 +107,11 @@ void JitArm::fsubx(UGeckoInstruction inst)
|
|||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
if (inst.Rc) Helper_UpdateCR1(vD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Breaks Animal Crossing
|
|
||||||
void JitArm::fmulsx(UGeckoInstruction inst)
|
void JitArm::fmulsx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(FloatingPoint)
|
JITDISABLE(FloatingPoint)
|
||||||
|
|
||||||
Default(inst); return;
|
|
||||||
|
|
||||||
ARMReg vA = fpr.R0(inst.FA);
|
ARMReg vA = fpr.R0(inst.FA);
|
||||||
ARMReg vC = fpr.R0(inst.FC);
|
ARMReg vC = fpr.R0(inst.FC);
|
||||||
ARMReg vD0 = fpr.R0(inst.FD);
|
ARMReg vD0 = fpr.R0(inst.FD);
|
||||||
@ -122,6 +119,7 @@ void JitArm::fmulsx(UGeckoInstruction inst)
|
|||||||
|
|
||||||
VMUL(vD0, vA, vC);
|
VMUL(vD0, vA, vC);
|
||||||
VMOV(vD1, vD0);
|
VMOV(vD1, vD0);
|
||||||
|
fpr.Flush(); // Shouldn't be needed. Missing a flush somewhere
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
if (inst.Rc) Helper_UpdateCR1(vD0);
|
||||||
}
|
}
|
||||||
void JitArm::fmulx(UGeckoInstruction inst)
|
void JitArm::fmulx(UGeckoInstruction inst)
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
#define FASTMEM 0
|
#define FASTMEM 0
|
||||||
#else
|
#else
|
||||||
#define FASTMEM 0
|
#define FASTMEM 1
|
||||||
#endif
|
#endif
|
||||||
void JitArm::stb(UGeckoInstruction inst)
|
void JitArm::stb(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
@ -282,6 +282,40 @@ void JitArm::stwu(UGeckoInstruction inst)
|
|||||||
|
|
||||||
gpr.Unlock(ValueReg, Addr, Function);
|
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)
|
void JitArm::StoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset)
|
||||||
{
|
{
|
||||||
ARMReg rA = gpr.GetReg();
|
ARMReg rA = gpr.GetReg();
|
||||||
@ -417,7 +451,7 @@ void JitArm::lhz(UGeckoInstruction inst)
|
|||||||
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
CMP(rA, EXCEPTION_DSI);
|
CMP(rA, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
||||||
#if 0 // FASTMEM
|
#if FASTMEM
|
||||||
// Backpatch route
|
// Backpatch route
|
||||||
// Gets loaded in to RD
|
// Gets loaded in to RD
|
||||||
// Address is in R10
|
// Address is in R10
|
||||||
|
@ -39,6 +39,9 @@ void JitArm::lfs(UGeckoInstruction inst)
|
|||||||
|
|
||||||
ARMReg rA = gpr.GetReg();
|
ARMReg rA = gpr.GetReg();
|
||||||
ARMReg rB = gpr.GetReg();
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
|
fpr.Flush();
|
||||||
|
|
||||||
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
CMP(rA, EXCEPTION_DSI);
|
CMP(rA, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
||||||
@ -52,7 +55,6 @@ void JitArm::lfs(UGeckoInstruction inst)
|
|||||||
else
|
else
|
||||||
MOVI2R(rB, (u32)inst.SIMM_16);
|
MOVI2R(rB, (u32)inst.SIMM_16);
|
||||||
|
|
||||||
fpr.Flush();
|
|
||||||
|
|
||||||
MOVI2R(rA, (u32)&Memory::Read_F32);
|
MOVI2R(rA, (u32)&Memory::Read_F32);
|
||||||
PUSH(4, R0, R1, R2, R3);
|
PUSH(4, R0, R1, R2, R3);
|
||||||
@ -80,6 +82,9 @@ void JitArm::lfd(UGeckoInstruction inst)
|
|||||||
|
|
||||||
ARMReg rA = gpr.GetReg();
|
ARMReg rA = gpr.GetReg();
|
||||||
ARMReg rB = gpr.GetReg();
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
|
fpr.Flush();
|
||||||
|
|
||||||
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
CMP(rA, EXCEPTION_DSI);
|
CMP(rA, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
||||||
@ -93,7 +98,6 @@ void JitArm::lfd(UGeckoInstruction inst)
|
|||||||
else
|
else
|
||||||
MOVI2R(rB, (u32)inst.SIMM_16);
|
MOVI2R(rB, (u32)inst.SIMM_16);
|
||||||
|
|
||||||
fpr.Flush();
|
|
||||||
|
|
||||||
MOVI2R(rA, (u32)&Memory::Read_F64);
|
MOVI2R(rA, (u32)&Memory::Read_F64);
|
||||||
PUSH(4, R0, R1, R2, R3);
|
PUSH(4, R0, R1, R2, R3);
|
||||||
@ -112,3 +116,37 @@ void JitArm::lfd(UGeckoInstruction inst)
|
|||||||
gpr.Unlock(rA, rB);
|
gpr.Unlock(rA, rB);
|
||||||
SetJumpTarget(DoNotLoad);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ static GekkoOPTemplate primarytable[] =
|
|||||||
{50, &JitArm::lfd}, //"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}},
|
{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}},
|
{53, &JitArm::Default}, //"stfsu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}},
|
||||||
{54, &JitArm::Default}, //"stfd", OPTYPE_STOREFP, FL_IN_A}},
|
{54, &JitArm::Default}, //"stfd", OPTYPE_STOREFP, FL_IN_A}},
|
||||||
{55, &JitArm::Default}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | 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}},
|
{597, &JitArm::Default}, //"lswi", OPTYPE_LOAD, FL_EVIL | FL_IN_AB | FL_OUT_D}},
|
||||||
|
|
||||||
//store word
|
//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}},
|
{183, &JitArm::Default}, //"stwux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||||
|
|
||||||
//store halfword
|
//store halfword
|
||||||
@ -293,7 +293,7 @@ static GekkoOPTemplate table31[] =
|
|||||||
{659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
{659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||||
|
|
||||||
{4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
{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}},
|
{982, &JitArm::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},
|
||||||
|
|
||||||
// Unused instructions on GC
|
// Unused instructions on GC
|
||||||
|
Loading…
x
Reference in New Issue
Block a user