[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:
parent
54843ad1e8
commit
691f76b826
|
@ -67,7 +67,7 @@ private:
|
||||||
|
|
||||||
void PrintDebug(UGeckoInstruction inst, u32 level);
|
void PrintDebug(UGeckoInstruction inst, u32 level);
|
||||||
|
|
||||||
void Helper_UpdateCR1(ARMReg value);
|
void Helper_UpdateCR1(ARMReg fpscr, ARMReg temp);
|
||||||
|
|
||||||
void SetFPException(ARMReg Reg, u32 Exception);
|
void SetFPException(ARMReg Reg, u32 Exception);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#include "JitFPRCache.h"
|
#include "JitFPRCache.h"
|
||||||
#include "JitAsm.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.
|
UBFX(temp, fpscr, 28, 4);
|
||||||
PanicAlert("CR1");
|
STRB(temp, R9, PPCSTATE_OFF(cr_fast[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fctiwx(UGeckoInstruction inst)
|
void JitArm::fctiwx(UGeckoInstruction inst)
|
||||||
|
@ -134,7 +134,7 @@ void JitArm::fctiwx(UGeckoInstruction inst)
|
||||||
NEONXEmitter nemit(this);
|
NEONXEmitter nemit(this);
|
||||||
nemit.VORR(vD, vD, V0);
|
nemit.VORR(vD, vD, V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
if (inst.Rc) Helper_UpdateCR1(fpscrReg, rA);
|
||||||
|
|
||||||
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
||||||
gpr.Unlock(rA);
|
gpr.Unlock(rA);
|
||||||
|
@ -215,7 +215,7 @@ void JitArm::fctiwzx(UGeckoInstruction inst)
|
||||||
NEONXEmitter nemit(this);
|
NEONXEmitter nemit(this);
|
||||||
nemit.VORR(vD, vD, V0);
|
nemit.VORR(vD, vD, V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
if (inst.Rc) Helper_UpdateCR1(fpscrReg, rA);
|
||||||
|
|
||||||
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
||||||
gpr.Unlock(rA);
|
gpr.Unlock(rA);
|
||||||
|
@ -360,12 +360,15 @@ void JitArm::fabsx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD = fpr.R0(inst.FD, false);
|
ARMReg vD = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VABS(vD, vB);
|
VABS(vD, vB);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fnabsx(UGeckoInstruction inst)
|
void JitArm::fnabsx(UGeckoInstruction inst)
|
||||||
|
@ -373,13 +376,16 @@ void JitArm::fnabsx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD = fpr.R0(inst.FD, false);
|
ARMReg vD = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VABS(vD, vB);
|
VABS(vD, vB);
|
||||||
VNEG(vD, vD);
|
VNEG(vD, vD);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fnegx(UGeckoInstruction inst)
|
void JitArm::fnegx(UGeckoInstruction inst)
|
||||||
|
@ -387,12 +393,15 @@ void JitArm::fnegx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD = fpr.R0(inst.FD, false);
|
ARMReg vD = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VNEG(vD, vB);
|
VNEG(vD, vB);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::faddsx(UGeckoInstruction inst)
|
void JitArm::faddsx(UGeckoInstruction inst)
|
||||||
|
@ -400,6 +409,11 @@ void JitArm::faddsx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vA = fpr.R0(inst.FA);
|
ARMReg vA = fpr.R0(inst.FA);
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD0 = fpr.R0(inst.FD, false);
|
ARMReg vD0 = fpr.R0(inst.FD, false);
|
||||||
|
@ -407,7 +421,6 @@ void JitArm::faddsx(UGeckoInstruction inst)
|
||||||
|
|
||||||
VADD(vD0, vA, vB);
|
VADD(vD0, vA, vB);
|
||||||
VMOV(vD1, vD0);
|
VMOV(vD1, vD0);
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::faddx(UGeckoInstruction inst)
|
void JitArm::faddx(UGeckoInstruction inst)
|
||||||
|
@ -415,12 +428,16 @@ void JitArm::faddx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vA = fpr.R0(inst.FA);
|
ARMReg vA = fpr.R0(inst.FA);
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD = fpr.R0(inst.FD, false);
|
ARMReg vD = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VADD(vD, vA, vB);
|
VADD(vD, vA, vB);
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fsubsx(UGeckoInstruction inst)
|
void JitArm::fsubsx(UGeckoInstruction inst)
|
||||||
|
@ -428,6 +445,11 @@ void JitArm::fsubsx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vA = fpr.R0(inst.FA);
|
ARMReg vA = fpr.R0(inst.FA);
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD0 = fpr.R0(inst.FD, false);
|
ARMReg vD0 = fpr.R0(inst.FD, false);
|
||||||
|
@ -435,7 +457,6 @@ void JitArm::fsubsx(UGeckoInstruction inst)
|
||||||
|
|
||||||
VSUB(vD0, vA, vB);
|
VSUB(vD0, vA, vB);
|
||||||
VMOV(vD1, vD0);
|
VMOV(vD1, vD0);
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fsubx(UGeckoInstruction inst)
|
void JitArm::fsubx(UGeckoInstruction inst)
|
||||||
|
@ -443,12 +464,16 @@ void JitArm::fsubx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vA = fpr.R0(inst.FA);
|
ARMReg vA = fpr.R0(inst.FA);
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD = fpr.R0(inst.FD, false);
|
ARMReg vD = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VSUB(vD, vA, vB);
|
VSUB(vD, vA, vB);
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fmulsx(UGeckoInstruction inst)
|
void JitArm::fmulsx(UGeckoInstruction inst)
|
||||||
|
@ -456,6 +481,11 @@ void JitArm::fmulsx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
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, false);
|
ARMReg vD0 = fpr.R0(inst.FD, false);
|
||||||
|
@ -463,31 +493,37 @@ void JitArm::fmulsx(UGeckoInstruction inst)
|
||||||
|
|
||||||
VMUL(vD0, vA, vC);
|
VMUL(vD0, vA, vC);
|
||||||
VMOV(vD1, vD0);
|
VMOV(vD1, vD0);
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
void JitArm::fmulx(UGeckoInstruction inst)
|
void JitArm::fmulx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
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, false);
|
ARMReg vD0 = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VMUL(vD0, vA, vC);
|
VMUL(vD0, vA, vC);
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
void JitArm::fmrx(UGeckoInstruction inst)
|
void JitArm::fmrx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ARMReg vB = fpr.R0(inst.FB);
|
ARMReg vB = fpr.R0(inst.FB);
|
||||||
ARMReg vD = fpr.R0(inst.FD, false);
|
ARMReg vD = fpr.R0(inst.FD, false);
|
||||||
|
|
||||||
VMOV(vD, vB);
|
VMOV(vD, vB);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fmaddsx(UGeckoInstruction inst)
|
void JitArm::fmaddsx(UGeckoInstruction inst)
|
||||||
|
@ -495,6 +531,11 @@ void JitArm::fmaddsx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
|
|
||||||
ARMReg vA0 = fpr.R0(a);
|
ARMReg vA0 = fpr.R0(a);
|
||||||
|
@ -513,8 +554,6 @@ void JitArm::fmaddsx(UGeckoInstruction inst)
|
||||||
VMOV(vD1, V0);
|
VMOV(vD1, V0);
|
||||||
|
|
||||||
fpr.Unlock(V0);
|
fpr.Unlock(V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fmaddx(UGeckoInstruction inst)
|
void JitArm::fmaddx(UGeckoInstruction inst)
|
||||||
|
@ -522,6 +561,11 @@ void JitArm::fmaddx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
|
|
||||||
ARMReg vA0 = fpr.R0(a);
|
ARMReg vA0 = fpr.R0(a);
|
||||||
|
@ -538,8 +582,6 @@ void JitArm::fmaddx(UGeckoInstruction inst)
|
||||||
VMOV(vD0, V0);
|
VMOV(vD0, V0);
|
||||||
|
|
||||||
fpr.Unlock(V0);
|
fpr.Unlock(V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fnmaddx(UGeckoInstruction inst)
|
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;
|
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 vA0 = fpr.R0(a);
|
||||||
ARMReg vB0 = fpr.R0(b);
|
ARMReg vB0 = fpr.R0(b);
|
||||||
ARMReg vC0 = fpr.R0(c);
|
ARMReg vC0 = fpr.R0(c);
|
||||||
|
@ -563,8 +610,6 @@ void JitArm::fnmaddx(UGeckoInstruction inst)
|
||||||
VNEG(vD0, V0);
|
VNEG(vD0, V0);
|
||||||
|
|
||||||
fpr.Unlock(V0);
|
fpr.Unlock(V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
void JitArm::fnmaddsx(UGeckoInstruction inst)
|
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;
|
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 vA0 = fpr.R0(a);
|
||||||
ARMReg vB0 = fpr.R0(b);
|
ARMReg vB0 = fpr.R0(b);
|
||||||
ARMReg vC0 = fpr.R0(c);
|
ARMReg vC0 = fpr.R0(c);
|
||||||
|
@ -589,8 +639,6 @@ void JitArm::fnmaddsx(UGeckoInstruction inst)
|
||||||
VNEG(vD1, V0);
|
VNEG(vD1, V0);
|
||||||
|
|
||||||
fpr.Unlock(V0);
|
fpr.Unlock(V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Messes up Super Mario Sunshine title screen
|
// XXX: Messes up Super Mario Sunshine title screen
|
||||||
|
@ -601,6 +649,11 @@ void JitArm::fresx(UGeckoInstruction inst)
|
||||||
|
|
||||||
u32 b = inst.FB, d = inst.FD;
|
u32 b = inst.FB, d = inst.FD;
|
||||||
|
|
||||||
|
if (inst.Rc) {
|
||||||
|
Default(inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Default(inst); return;
|
Default(inst); return;
|
||||||
|
|
||||||
ARMReg vB0 = fpr.R0(b);
|
ARMReg vB0 = fpr.R0(b);
|
||||||
|
@ -613,8 +666,6 @@ void JitArm::fresx(UGeckoInstruction inst)
|
||||||
VDIV(vD1, V0, vB0);
|
VDIV(vD1, V0, vB0);
|
||||||
VDIV(vD0, V0, vB0);
|
VDIV(vD0, V0, vB0);
|
||||||
fpr.Unlock(V0);
|
fpr.Unlock(V0);
|
||||||
|
|
||||||
if (inst.Rc) Helper_UpdateCR1(vD0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::fselx(UGeckoInstruction inst)
|
void JitArm::fselx(UGeckoInstruction inst)
|
||||||
|
|
Loading…
Reference in New Issue