[ARM] lfsux/lfdx/lfdux/stfsx/stfsux/stfdx/stfdux implementations.
This commit is contained in:
parent
823bb44ba7
commit
3fe8134f3b
|
@ -216,13 +216,20 @@ public:
|
||||||
// Floating point loadStore
|
// Floating point loadStore
|
||||||
void lfs(UGeckoInstruction _inst);
|
void lfs(UGeckoInstruction _inst);
|
||||||
void lfsu(UGeckoInstruction _inst);
|
void lfsu(UGeckoInstruction _inst);
|
||||||
|
void lfsux(UGeckoInstruction _inst);
|
||||||
void lfsx(UGeckoInstruction _inst);
|
void lfsx(UGeckoInstruction _inst);
|
||||||
void lfd(UGeckoInstruction _inst);
|
void lfd(UGeckoInstruction _inst);
|
||||||
|
void lfdx(UGeckoInstruction _inst);
|
||||||
void lfdu(UGeckoInstruction _inst);
|
void lfdu(UGeckoInstruction _inst);
|
||||||
|
void lfdux(UGeckoInstruction _inst);
|
||||||
void stfs(UGeckoInstruction _inst);
|
void stfs(UGeckoInstruction _inst);
|
||||||
|
void stfsx(UGeckoInstruction _inst);
|
||||||
void stfsu(UGeckoInstruction _inst);
|
void stfsu(UGeckoInstruction _inst);
|
||||||
|
void stfsux(UGeckoInstruction _inst);
|
||||||
void stfd(UGeckoInstruction _inst);
|
void stfd(UGeckoInstruction _inst);
|
||||||
|
void stfdx(UGeckoInstruction _inst);
|
||||||
void stfdu(UGeckoInstruction _inst);
|
void stfdu(UGeckoInstruction _inst);
|
||||||
|
void stfdux(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Paired Singles
|
// Paired Singles
|
||||||
void ps_add(UGeckoInstruction _inst);
|
void ps_add(UGeckoInstruction _inst);
|
||||||
|
|
|
@ -108,6 +108,44 @@ void JitArm::lfsu(UGeckoInstruction inst)
|
||||||
SetJumpTarget(DoNotLoad);
|
SetJumpTarget(DoNotLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::lfsux(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
|
ARMReg v0 = fpr.R0(inst.FD);
|
||||||
|
ARMReg v1 = fpr.R1(inst.FD);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::lfsx(UGeckoInstruction inst)
|
void JitArm::lfsx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -183,6 +221,47 @@ void JitArm::lfd(UGeckoInstruction inst)
|
||||||
SetJumpTarget(DoNotLoad);
|
SetJumpTarget(DoNotLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::lfdx(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
|
ARMReg v0 = fpr.R0(inst.FD);
|
||||||
|
|
||||||
|
if (inst.RA)
|
||||||
|
{
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ADD(rB, RB, 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_F64);
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
MOV(R0, rB);
|
||||||
|
BL(rA);
|
||||||
|
|
||||||
|
#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1
|
||||||
|
VMOV(v0, R0);
|
||||||
|
#else
|
||||||
|
VMOV(v0, D0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
|
||||||
|
gpr.Unlock(rA, rB);
|
||||||
|
SetJumpTarget(DoNotLoad);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::lfdu(UGeckoInstruction inst)
|
void JitArm::lfdu(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -220,6 +299,44 @@ void JitArm::lfdu(UGeckoInstruction inst)
|
||||||
SetJumpTarget(DoNotLoad);
|
SetJumpTarget(DoNotLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::lfdux(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
|
ARMReg v0 = fpr.R0(inst.FD);
|
||||||
|
|
||||||
|
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_F64);
|
||||||
|
MOV(RA, rB);
|
||||||
|
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
MOV(R0, rB);
|
||||||
|
BL(rA);
|
||||||
|
|
||||||
|
#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1
|
||||||
|
VMOV(v0, R0);
|
||||||
|
#else
|
||||||
|
VMOV(v0, D0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
|
||||||
|
gpr.Unlock(rA, rB);
|
||||||
|
SetJumpTarget(DoNotLoad);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::stfs(UGeckoInstruction inst)
|
void JitArm::stfs(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -252,6 +369,38 @@ void JitArm::stfs(UGeckoInstruction inst)
|
||||||
gpr.Unlock(rA, rB);
|
gpr.Unlock(rA, rB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::stfsx(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
ARMReg v0 = fpr.R0(inst.FS);
|
||||||
|
VCVT(S0, v0, 0);
|
||||||
|
|
||||||
|
if (inst.RA)
|
||||||
|
{
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ADD(rB, RB, RA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MOV(rB, RB);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void JitArm::stfsu(UGeckoInstruction inst)
|
void JitArm::stfsu(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -286,6 +435,40 @@ void JitArm::stfsu(UGeckoInstruction inst)
|
||||||
gpr.Unlock(rA, rB);
|
gpr.Unlock(rA, rB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::stfsux(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
ARMReg v0 = fpr.R0(inst.FS);
|
||||||
|
VCVT(S0, v0, 0);
|
||||||
|
|
||||||
|
ADD(rB, RB, RA);
|
||||||
|
|
||||||
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
|
CMP(rA, EXCEPTION_DSI);
|
||||||
|
|
||||||
|
SetCC(CC_NEQ);
|
||||||
|
MOV(RA, rB);
|
||||||
|
SetCC();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::stfd(UGeckoInstruction inst)
|
void JitArm::stfd(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -322,6 +505,43 @@ void JitArm::stfd(UGeckoInstruction inst)
|
||||||
gpr.Unlock(rA, rB);
|
gpr.Unlock(rA, rB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::stfdx(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
ARMReg v0 = fpr.R0(inst.FS);
|
||||||
|
|
||||||
|
if (inst.RA)
|
||||||
|
{
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ADD(rB, RB, RA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MOV(rB, RB);
|
||||||
|
|
||||||
|
|
||||||
|
MOVI2R(rA, (u32)&Memory::Write_F64);
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1
|
||||||
|
VMOV(R0, v0);
|
||||||
|
MOV(R2, rB);
|
||||||
|
#else
|
||||||
|
VMOV(D0, v0);
|
||||||
|
MOV(R0, rB);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BL(rA);
|
||||||
|
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
|
||||||
|
gpr.Unlock(rA, rB);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::stfdu(UGeckoInstruction inst)
|
void JitArm::stfdu(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -358,3 +578,40 @@ void JitArm::stfdu(UGeckoInstruction inst)
|
||||||
gpr.Unlock(rA, rB);
|
gpr.Unlock(rA, rB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::stfdux(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITLoadStoreFloatingOff)
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ARMReg RB = gpr.R(inst.RB);
|
||||||
|
|
||||||
|
ARMReg rA = gpr.GetReg();
|
||||||
|
ARMReg rB = gpr.GetReg();
|
||||||
|
ARMReg v0 = fpr.R0(inst.FS);
|
||||||
|
|
||||||
|
ADD(rB, RB, RA);
|
||||||
|
|
||||||
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
|
CMP(rA, EXCEPTION_DSI);
|
||||||
|
|
||||||
|
SetCC(CC_NEQ);
|
||||||
|
MOV(RA, rB);
|
||||||
|
SetCC();
|
||||||
|
|
||||||
|
MOVI2R(rA, (u32)&Memory::Write_F64);
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1
|
||||||
|
VMOV(R0, v0);
|
||||||
|
MOV(R2, rB);
|
||||||
|
#else
|
||||||
|
VMOV(D0, v0);
|
||||||
|
MOV(R0, rB);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BL(rA);
|
||||||
|
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
|
||||||
|
gpr.Unlock(rA, rB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,14 +269,14 @@ static GekkoOPTemplate table31[] =
|
||||||
|
|
||||||
// fp load/store
|
// fp load/store
|
||||||
{535, &JitArm::lfsx}, //"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}},
|
{567, &JitArm::lfsux}, //"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}},
|
||||||
{599, &JitArm::Default}, //"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}},
|
{599, &JitArm::lfdx}, //"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}},
|
||||||
{631, &JitArm::Default}, //"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}},
|
{631, &JitArm::lfdux}, //"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}},
|
||||||
|
|
||||||
{663, &JitArm::Default}, //"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
{663, &JitArm::stfsx}, //"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
||||||
{695, &JitArm::Default}, //"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
|
{695, &JitArm::stfsux}, //"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
|
||||||
{727, &JitArm::Default}, //"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
{727, &JitArm::stfdx}, //"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
||||||
{759, &JitArm::Default}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
|
{759, &JitArm::stfdux}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
|
||||||
{983, &JitArm::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
{983, &JitArm::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
||||||
|
|
||||||
{19, &JitArm::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
|
{19, &JitArm::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||||
|
|
Loading…
Reference in New Issue