Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[ARM] Implement CR1 setting for the few floating point instructions t…
…hat 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.
  • Loading branch information
Sonicadvance1 committed Sep 25, 2013
1 parent 54843ad commit 691f76b
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/PowerPC/JitArm32/Jit.h
Expand Up @@ -67,7 +67,7 @@ class JitArm : public JitBase, public ArmGen::ARMXCodeBlock

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:
Expand Down
113 changes: 82 additions & 31 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -360,141 +360,182 @@ 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)
{
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)
{
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)
{
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);
ARMReg vD1 = fpr.R1(inst.FD, false);

VADD(vD0, vA, vB);
VMOV(vD1, vD0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}

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);
ARMReg vD1 = fpr.R1(inst.FD, false);

VSUB(vD0, vA, vB);
VMOV(vD1, vD0);
if (inst.Rc) Helper_UpdateCR1(vD0);
}

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);
ARMReg vD1 = fpr.R1(inst.FD, false);

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)
{
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);
Expand All @@ -513,15 +554,18 @@ void JitArm::fmaddsx(UGeckoInstruction inst)
VMOV(vD1, V0);

fpr.Unlock(V0);

if (inst.Rc) Helper_UpdateCR1(vD0);
}

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);
Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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)
{
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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)
Expand Down

0 comments on commit 691f76b

Please sign in to comment.