[ARM] Implement CR1 setting for the few floating point instructions that I have setting the flags. For the rest, drop to interpreter if it sets CR1. At that point it'll spam a panic alert. I don't quite understand why Interpreter and JIT64/IL don't do this yet, it's a simple 4 bit copy.

This commit is contained in:
Ryan Houdek 2013-09-25 18:15:20 +00:00
parent 54843ad1e8
commit 691f76b826
2 changed files with 83 additions and 32 deletions

View File

@ -67,7 +67,7 @@ private:
void PrintDebug(UGeckoInstruction inst, u32 level);
void Helper_UpdateCR1(ARMReg value);
void Helper_UpdateCR1(ARMReg fpscr, ARMReg temp);
void SetFPException(ARMReg Reg, u32 Exception);
public:

View File

@ -32,10 +32,10 @@
#include "JitFPRCache.h"
#include "JitAsm.h"
void JitArm::Helper_UpdateCR1(ARMReg value)
void JitArm::Helper_UpdateCR1(ARMReg fpscr, ARMReg temp)
{
// Should just update exception flags, not do any compares.
PanicAlert("CR1");
UBFX(temp, fpscr, 28, 4);
STRB(temp, R9, PPCSTATE_OFF(cr_fast[1]));
}
void JitArm::fctiwx(UGeckoInstruction inst)
@ -134,7 +134,7 @@ void JitArm::fctiwx(UGeckoInstruction inst)
NEONXEmitter nemit(this);
nemit.VORR(vD, vD, V0);
if (inst.Rc) Helper_UpdateCR1(vD);
if (inst.Rc) Helper_UpdateCR1(fpscrReg, rA);
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
gpr.Unlock(rA);
@ -215,7 +215,7 @@ void JitArm::fctiwzx(UGeckoInstruction inst)
NEONXEmitter nemit(this);
nemit.VORR(vD, vD, V0);
if (inst.Rc) Helper_UpdateCR1(vD);
if (inst.Rc) Helper_UpdateCR1(fpscrReg, rA);
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
gpr.Unlock(rA);
@ -360,12 +360,15 @@ void JitArm::fabsx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD = fpr.R0(inst.FD, false);
VABS(vD, vB);
if (inst.Rc) Helper_UpdateCR1(vD);
}
void JitArm::fnabsx(UGeckoInstruction inst)
@ -373,13 +376,16 @@ void JitArm::fnabsx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD = fpr.R0(inst.FD, false);
VABS(vD, vB);
VNEG(vD, vD);
if (inst.Rc) Helper_UpdateCR1(vD);
}
void JitArm::fnegx(UGeckoInstruction inst)
@ -387,12 +393,15 @@ void JitArm::fnegx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD = fpr.R0(inst.FD, false);
VNEG(vD, vB);
if (inst.Rc) Helper_UpdateCR1(vD);
}
void JitArm::faddsx(UGeckoInstruction inst)
@ -400,6 +409,11 @@ void JitArm::faddsx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA = fpr.R0(inst.FA);
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD0 = fpr.R0(inst.FD, false);
@ -407,7 +421,6 @@ void JitArm::faddsx(UGeckoInstruction inst)
VADD(vD0, vA, vB);
VMOV(vD1, vD0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::faddx(UGeckoInstruction inst)
@ -415,19 +428,28 @@ void JitArm::faddx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA = fpr.R0(inst.FA);
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD = fpr.R0(inst.FD, false);
VADD(vD, vA, vB);
if (inst.Rc) Helper_UpdateCR1(vD);
}
void JitArm::fsubsx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA = fpr.R0(inst.FA);
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD0 = fpr.R0(inst.FD, false);
@ -435,7 +457,6 @@ void JitArm::fsubsx(UGeckoInstruction inst)
VSUB(vD0, vA, vB);
VMOV(vD1, vD0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fsubx(UGeckoInstruction inst)
@ -443,19 +464,28 @@ void JitArm::fsubx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA = fpr.R0(inst.FA);
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD = fpr.R0(inst.FD, false);
VSUB(vD, vA, vB);
if (inst.Rc) Helper_UpdateCR1(vD);
}
void JitArm::fmulsx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA = fpr.R0(inst.FA);
ARMReg vC = fpr.R0(inst.FC);
ARMReg vD0 = fpr.R0(inst.FD, false);
@ -463,31 +493,37 @@ void JitArm::fmulsx(UGeckoInstruction inst)
VMUL(vD0, vA, vC);
VMOV(vD1, vD0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fmulx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA = fpr.R0(inst.FA);
ARMReg vC = fpr.R0(inst.FC);
ARMReg vD0 = fpr.R0(inst.FD, false);
VMUL(vD0, vA, vC);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fmrx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vB = fpr.R0(inst.FB);
ARMReg vD = fpr.R0(inst.FD, false);
VMOV(vD, vB);
if (inst.Rc) Helper_UpdateCR1(vD);
}
void JitArm::fmaddsx(UGeckoInstruction inst)
@ -495,6 +531,11 @@ void JitArm::fmaddsx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
ARMReg vA0 = fpr.R0(a);
@ -513,8 +554,6 @@ void JitArm::fmaddsx(UGeckoInstruction inst)
VMOV(vD1, V0);
fpr.Unlock(V0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fmaddx(UGeckoInstruction inst)
@ -522,6 +561,11 @@ void JitArm::fmaddx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff)
if (inst.Rc) {
Default(inst);
return;
}
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
ARMReg vA0 = fpr.R0(a);
@ -538,8 +582,6 @@ void JitArm::fmaddx(UGeckoInstruction inst)
VMOV(vD0, V0);
fpr.Unlock(V0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fnmaddx(UGeckoInstruction inst)
@ -549,6 +591,11 @@ void JitArm::fnmaddx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA0 = fpr.R0(a);
ARMReg vB0 = fpr.R0(b);
ARMReg vC0 = fpr.R0(c);
@ -563,8 +610,6 @@ void JitArm::fnmaddx(UGeckoInstruction inst)
VNEG(vD0, V0);
fpr.Unlock(V0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fnmaddsx(UGeckoInstruction inst)
{
@ -573,6 +618,11 @@ void JitArm::fnmaddsx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
if (inst.Rc) {
Default(inst);
return;
}
ARMReg vA0 = fpr.R0(a);
ARMReg vB0 = fpr.R0(b);
ARMReg vC0 = fpr.R0(c);
@ -589,8 +639,6 @@ void JitArm::fnmaddsx(UGeckoInstruction inst)
VNEG(vD1, V0);
fpr.Unlock(V0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
// XXX: Messes up Super Mario Sunshine title screen
@ -601,6 +649,11 @@ void JitArm::fresx(UGeckoInstruction inst)
u32 b = inst.FB, d = inst.FD;
if (inst.Rc) {
Default(inst);
return;
}
Default(inst); return;
ARMReg vB0 = fpr.R0(b);
@ -613,8 +666,6 @@ void JitArm::fresx(UGeckoInstruction inst)
VDIV(vD1, V0, vB0);
VDIV(vD0, V0, vB0);
fpr.Unlock(V0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}
void JitArm::fselx(UGeckoInstruction inst)