summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2014-07-17 03:40:02 +0000
committerPierre Bourdon <delroth@gmail.com>2014-07-30 21:41:18 -0700
commitfda2190a3787e4571ed77a9e2325c5a4e7fe3ff9 (patch)
tree0eb57c58cf776472b4721f080f5984bcdb5d86f2
parent3627bd21f1fc513f5bafd07bed4de9d9b119a583 (diff)
Support the 64bit CR flags in the ARM JIT.
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/Jit.cpp18
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/Jit.h17
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp58
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/JitArm_FloatingPoint.cpp133
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/JitArm_Integer.cpp197
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/JitArm_Paired.cpp259
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/JitArm_SystemRegisters.cpp198
-rw-r--r--Source/Core/Core/PowerPC/JitArm32/JitArm_Tables.cpp38
8 files changed, 137 insertions, 781 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/PowerPC/JitArm32/Jit.cpp
index afe4d490cc..97ef0644ec 100644
--- a/Source/Core/Core/PowerPC/JitArm32/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/Jit.cpp
@@ -233,31 +233,25 @@ void JitArm::SingleStep()
void JitArm::Trace()
{
- char regs[500] = "";
- char fregs[750] = "";
+ std::string regs;
+ std::string fregs;
#ifdef JIT_LOG_GPR
for (int i = 0; i < 32; i++)
{
- char reg[50];
- sprintf(reg, "r%02d: %08x ", i, PowerPC::ppcState.gpr[i]);
- strncat(regs, reg, sizeof(regs) - 1);
+ regs += StringFromFormat("r%02d: %08x ", i, PowerPC::ppcState.gpr[i]);
}
#endif
#ifdef JIT_LOG_FPR
for (int i = 0; i < 32; i++)
{
- char reg[50];
- sprintf(reg, "f%02d: %016x ", i, riPS0(i));
- strncat(fregs, reg, sizeof(fregs) - 1);
+ fregs += StringFromFormat("f%02d: %016x ", i, riPS0(i));
}
#endif
- DEBUG_LOG(DYNA_REC, "JITARM PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s",
- PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3],
- PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr,
- PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs);
+ DEBUG_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x FPSCR: %08x MSR: %08x LR: %08x %s %s",
+ PC, SRR0, SRR1, PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), fregs.c_str());
}
void JitArm::PrintDebug(UGeckoInstruction inst, u32 level)
diff --git a/Source/Core/Core/PowerPC/JitArm32/Jit.h b/Source/Core/Core/PowerPC/JitArm32/Jit.h
index 30681d63e5..c4cfcaa115 100644
--- a/Source/Core/Core/PowerPC/JitArm32/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm32/Jit.h
@@ -50,6 +50,8 @@ private:
void Helper_UpdateCR1(ARMReg fpscr, ARMReg temp);
void SetFPException(ARMReg Reg, u32 Exception);
+
+ FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
public:
JitArm() : code_buffer(32000) {}
~JitArm() {}
@@ -96,8 +98,7 @@ public:
void WriteCallInterpreter(UGeckoInstruction _inst);
void Cleanup();
- void GenerateRC(int cr = 0);
- void ComputeRC(int cr = 0);
+ void ComputeRC(ARMReg value, int cr = 0);
void ComputeRC(s32 value, int cr);
void ComputeCarry();
@@ -143,8 +144,6 @@ public:
void cntlzwx(UGeckoInstruction _inst);
void cmp (UGeckoInstruction _inst);
void cmpi(UGeckoInstruction _inst);
- void cmpl(UGeckoInstruction _inst);
- void cmpli(UGeckoInstruction _inst);
void negx(UGeckoInstruction _inst);
void mulhwux(UGeckoInstruction _inst);
void rlwimix(UGeckoInstruction _inst);
@@ -160,13 +159,9 @@ public:
void mtspr(UGeckoInstruction _inst);
void mfspr(UGeckoInstruction _inst);
void mftb(UGeckoInstruction _inst);
- void crXXX(UGeckoInstruction _inst);
void mcrf(UGeckoInstruction _inst);
- void mfcr(UGeckoInstruction _inst);
- void mtcrf(UGeckoInstruction _inst);
void mtsr(UGeckoInstruction _inst);
void mfsr(UGeckoInstruction _inst);
- void mcrxr(UGeckoInstruction _inst);
void twx(UGeckoInstruction _inst);
// LoadStore
@@ -193,8 +188,6 @@ public:
void fmaddx(UGeckoInstruction _inst);
void fctiwx(UGeckoInstruction _inst);
void fctiwzx(UGeckoInstruction _inst);
- void fcmpo(UGeckoInstruction _inst);
- void fcmpu(UGeckoInstruction _inst);
void fnmaddx(UGeckoInstruction _inst);
void fnmaddsx(UGeckoInstruction _inst);
void fresx(UGeckoInstruction _inst);
@@ -232,10 +225,6 @@ public:
void ps_nabs(UGeckoInstruction _inst);
void ps_rsqrte(UGeckoInstruction _inst);
void ps_sel(UGeckoInstruction _inst);
- void ps_cmpu0(UGeckoInstruction _inst);
- void ps_cmpu1(UGeckoInstruction _inst);
- void ps_cmpo0(UGeckoInstruction _inst);
- void ps_cmpo1(UGeckoInstruction _inst);
// LoadStore paired
void psq_l(UGeckoInstruction _inst);
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp
index de76f030f6..09d4b33acb 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp
@@ -16,15 +16,6 @@
// The branches are known good, or at least reasonably good.
// No need for a disable-mechanism.
-// If defined, clears CR0 at blr and bl-s. If the assumption that
-// flags never carry over between functions holds, then the task for
-// an optimizer becomes much easier.
-
-// #define ACID_TEST
-
-// Zelda and many more games seem to pass the Acid Test.
-
-
using namespace ArmGen;
void JitArm::sc(UGeckoInstruction inst)
{
@@ -121,13 +112,7 @@ void JitArm::bx(UGeckoInstruction inst)
destination = SignExt26(inst.LI << 2);
else
destination = js.compilerPC + SignExt26(inst.LI << 2);
-#ifdef ACID_TEST
- if (inst.LK)
- {
- MOV(R14, 0);
- STRB(R14, R9, PPCSTATE_OFF(cr_fast[0]));
- }
-#endif
+
if (destination == js.compilerPC)
{
//PanicAlert("Idle loop detected at %08x", destination);
@@ -168,15 +153,10 @@ void JitArm::bcx(UGeckoInstruction inst)
FixupBranch pConditionDontBranch;
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit
{
- LDRB(rA, R9, PPCSTATE_OFF(cr_fast) + (inst.BI >> 2));
- TST(rA, 8 >> (inst.BI & 3));
-
- //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
- if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch
- pConditionDontBranch = B_CC(CC_EQ); // Zero
- else
- pConditionDontBranch = B_CC(CC_NEQ); // Not Zero
+ pConditionDontBranch = JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3),
+ !(inst.BO_2 & BO_BRANCH_IF_TRUE));
}
+
if (inst.LK)
{
u32 Jumpto = js.compilerPC + 4;
@@ -240,20 +220,13 @@ void JitArm::bcctrx(UGeckoInstruction inst)
else
{
// Rare condition seen in (just some versions of?) Nintendo's NES Emulator
-
// BO_2 == 001zy -> b if false
// BO_2 == 011zy -> b if true
ARMReg rA = gpr.GetReg();
ARMReg rB = gpr.GetReg();
- LDRB(rA, R9, PPCSTATE_OFF(cr_fast) + (inst.BI >> 2));
- TST(rA, 8 >> (inst.BI & 3));
- CCFlags branch;
- if (inst.BO_2 & BO_BRANCH_IF_TRUE)
- branch = CC_EQ;
- else
- branch = CC_NEQ;
- FixupBranch b = B_CC(branch);
+ FixupBranch b = JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3),
+ !(inst.BO_2 & BO_BRANCH_IF_TRUE));
LDR(rA, R9, PPCSTATE_OFF(spr[SPR_CTR]));
BIC(rA, rA, 0x3);
@@ -304,25 +277,10 @@ void JitArm::bclrx(UGeckoInstruction inst)
FixupBranch pConditionDontBranch;
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit
{
- LDRB(rA, R9, PPCSTATE_OFF(cr_fast) + (inst.BI >> 2));
- TST(rA, 8 >> (inst.BI & 3));
- //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
- if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch
- pConditionDontBranch = B_CC(CC_EQ); // Zero
- else
- pConditionDontBranch = B_CC(CC_NEQ); // Not Zero
+ pConditionDontBranch = JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3),
+ !(inst.BO_2 & BO_BRANCH_IF_TRUE));
}
- // This below line can be used to prove that blr "eats flags" in practice.
- // This observation will let us do a lot of fun observations.
- #ifdef ACID_TEST
- if (inst.LK)
- {
- MOV(R14, 0);
- STRB(R14, R9, PPCSTATE_OFF(cr_fast[0]));
- }
- #endif
-
//MOV(32, R(EAX), M(&LR));
//AND(32, R(EAX), Imm32(0xFFFFFFFC));
LDR(rA, R9, PPCSTATE_OFF(spr[SPR_LR]));
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_FloatingPoint.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_FloatingPoint.cpp
index 6bd36cff2c..79a0b79885 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_FloatingPoint.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_FloatingPoint.cpp
@@ -19,8 +19,6 @@
void JitArm::Helper_UpdateCR1(ARMReg fpscr, ARMReg temp)
{
- UBFX(temp, fpscr, 28, 4);
- STRB(temp, R9, PPCSTATE_OFF(cr_fast[1]));
}
void JitArm::fctiwx(UGeckoInstruction inst)
@@ -129,7 +127,6 @@ void JitArm::fctiwx(UGeckoInstruction inst)
fpr.Unlock(V2);
}
-
void JitArm::fctiwzx(UGeckoInstruction inst)
{
INSTRUCTION_START
@@ -210,136 +207,6 @@ void JitArm::fctiwzx(UGeckoInstruction inst)
fpr.Unlock(V2);
}
-void JitArm::fcmpo(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITFloatingPointOff);
- u32 a = inst.FA, b = inst.FB;
- int cr = inst.CRFD;
-
- ARMReg vA = fpr.R0(a);
- ARMReg vB = fpr.R0(b);
- ARMReg fpscrReg = gpr.GetReg();
- ARMReg crReg = gpr.GetReg();
- Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
- Operand2 LessThan(0x8, 0xA); // 0x8000
- Operand2 GreaterThan(0x4, 0xA); // 0x4000
- Operand2 EqualTo(0x2, 0xA); // 0x2000
- Operand2 NANRes(0x1, 0xA); // 0x1000
- FixupBranch Done1, Done2, Done3;
- LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- BIC(fpscrReg, fpscrReg, FPRFMask);
-
- VCMPE(vA, vB);
- VMRS(_PC);
- SetCC(CC_LT);
- ORR(fpscrReg, fpscrReg, LessThan);
- MOV(crReg, 8);
- Done1 = B();
- SetCC(CC_GT);
- ORR(fpscrReg, fpscrReg, GreaterThan);
- MOV(crReg, 4);
- Done2 = B();
- SetCC(CC_EQ);
- ORR(fpscrReg, fpscrReg, EqualTo);
- MOV(crReg, 2);
- Done3 = B();
- SetCC();
-
- ORR(fpscrReg, fpscrReg, NANRes);
- MOV(crReg, 1);
-
- VCMPE(vA, vA);
- VMRS(_PC);
- FixupBranch NanA = B_CC(CC_NEQ);
- VCMPE(vB, vB);
- VMRS(_PC);
- FixupBranch NanB = B_CC(CC_NEQ);
-
- SetFPException(fpscrReg, FPSCR_VXVC);
- FixupBranch Done4 = B();
-
- SetJumpTarget(NanA);
- SetJumpTarget(NanB);
-
- SetFPException(fpscrReg, FPSCR_VXSNAN);
-
- TST(fpscrReg, VEMask);
-
- FixupBranch noVXVC = B_CC(CC_NEQ);
- SetFPException(fpscrReg, FPSCR_VXVC);
-
- SetJumpTarget(noVXVC);
- SetJumpTarget(Done1);
- SetJumpTarget(Done2);
- SetJumpTarget(Done3);
- SetJumpTarget(Done4);
- STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
- STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- gpr.Unlock(fpscrReg, crReg);
-}
-
-void JitArm::fcmpu(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITFloatingPointOff);
- u32 a = inst.FA, b = inst.FB;
- int cr = inst.CRFD;
-
- ARMReg vA = fpr.R0(a);
- ARMReg vB = fpr.R0(b);
- ARMReg fpscrReg = gpr.GetReg();
- ARMReg crReg = gpr.GetReg();
- Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
- Operand2 LessThan(0x8, 0xA); // 0x8000
- Operand2 GreaterThan(0x4, 0xA); // 0x4000
- Operand2 EqualTo(0x2, 0xA); // 0x2000
- Operand2 NANRes(0x1, 0xA); // 0x1000
- FixupBranch Done1, Done2, Done3;
- LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- BIC(fpscrReg, fpscrReg, FPRFMask);
-
- VCMPE(vA, vB);
- VMRS(_PC);
- SetCC(CC_LT);
- ORR(fpscrReg, fpscrReg, LessThan);
- MOV(crReg, 8);
- Done1 = B();
- SetCC(CC_GT);
- ORR(fpscrReg, fpscrReg, GreaterThan);
- MOV(crReg, 4);
- Done2 = B();
- SetCC(CC_EQ);
- ORR(fpscrReg, fpscrReg, EqualTo);
- MOV(crReg, 2);
- Done3 = B();
- SetCC();
-
- ORR(fpscrReg, fpscrReg, NANRes);
- MOV(crReg, 1);
-
- VCMPE(vA, vA);
- VMRS(_PC);
- FixupBranch NanA = B_CC(CC_NEQ);
- VCMPE(vB, vB);
- VMRS(_PC);
- FixupBranch NanB = B_CC(CC_NEQ);
- FixupBranch Done4 = B();
-
- SetJumpTarget(NanA);
- SetJumpTarget(NanB);
-
- SetFPException(fpscrReg, FPSCR_VXSNAN);
-
- SetJumpTarget(Done1);
- SetJumpTarget(Done2);
- SetJumpTarget(Done3);
- SetJumpTarget(Done4);
- STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
- STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- gpr.Unlock(fpscrReg, crReg);
-}
-
void JitArm::fabsx(UGeckoInstruction inst)
{
INSTRUCTION_START
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_Integer.cpp
index 5f47aefb34..6f7e6854dc 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_Integer.cpp
@@ -14,42 +14,27 @@
#include "Core/PowerPC/JitArm32/JitAsm.h"
#include "Core/PowerPC/JitArm32/JitRegCache.h"
-// Assumes that Sign and Zero flags were set by the last operation. Preserves all flags and registers.
-// Jit64 ComputerRC is signed
-// JIT64 GenerateRC is unsigned
-void JitArm::GenerateRC(int cr) {
+void JitArm::ComputeRC(ARMReg value, int cr) {
ARMReg rB = gpr.GetReg();
- MOV(rB, 0x4); // Result > 0
- SetCC(CC_EQ); MOV(rB, 0x2); // Result == 0
- SetCC(CC_MI); MOV(rB, 0x8); // Result < 0
- SetCC();
-
- STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr);
- gpr.Unlock(rB);
-}
-void JitArm::ComputeRC(int cr) {
- ARMReg rB = gpr.GetReg();
+ Operand2 ASRReg(value, ST_ASR, 31);
- MOV(rB, 0x2); // Result == 0
- SetCC(CC_LT); MOV(rB, 0x8); // Result < 0
- SetCC(CC_GT); MOV(rB, 0x4); // Result > 0
- SetCC();
+ STR(value, R9, PPCSTATE_OFF(cr_val[cr]));
+ MOV(rB, ASRReg);
+ STR(rB, R9, PPCSTATE_OFF(cr_val[cr]) + sizeof(u32));
- STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr);
gpr.Unlock(rB);
}
void JitArm::ComputeRC(s32 value, int cr) {
ARMReg rB = gpr.GetReg();
- if (value < 0)
- MOV(rB, 0x8);
- else if (value > 0)
- MOV(rB, 0x4);
- else
- MOV(rB, 0x2);
+ Operand2 ASRReg(rB, ST_ASR, 31);
+
+ MOVI2R(rB, value);
+ STR(rB, R9, PPCSTATE_OFF(cr_val[cr]));
+ MOV(rB, ASRReg);
+ STR(rB, R9, PPCSTATE_OFF(cr_val[cr]) + sizeof(u32));
- STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr);
gpr.Unlock(rB);
}
@@ -195,7 +180,6 @@ void JitArm::arith(UGeckoInstruction inst)
u32 Imm[2] = {0, 0};
bool Rc = false;
bool carry = false;
- bool isUnsigned = false;
bool shiftedImm = false;
switch (inst.OPCD)
@@ -306,7 +290,6 @@ void JitArm::arith(UGeckoInstruction inst)
case 522: // addcox
carry = true;
case 40: // subfx
- isUnsigned = true;
case 235: // mullwx
case 266:
case 747: // mullwox
@@ -431,6 +414,8 @@ void JitArm::arith(UGeckoInstruction inst)
if (Rc) ComputeRC(gpr.GetImm(dest), 0);
return;
}
+
+ u32 dest = d;
// One or the other isn't a IMM
switch (inst.OPCD)
{
@@ -472,6 +457,7 @@ void JitArm::arith(UGeckoInstruction inst)
case 24:
case 25:
{
+ dest = a;
ARMReg rA = gpr.GetReg();
RS = gpr.R(s);
RA = gpr.R(a);
@@ -483,6 +469,7 @@ void JitArm::arith(UGeckoInstruction inst)
case 26:
case 27:
{
+ dest = a;
ARMReg rA = gpr.GetReg();
RS = gpr.R(s);
RA = gpr.R(a);
@@ -495,6 +482,7 @@ void JitArm::arith(UGeckoInstruction inst)
case 28:
case 29:
{
+ dest = a;
ARMReg rA = gpr.GetReg();
RS = gpr.R(s);
RA = gpr.R(a);
@@ -507,12 +495,14 @@ void JitArm::arith(UGeckoInstruction inst)
switch (inst.SUBOP10)
{
case 24:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
LSLS(RA, RS, RB);
break;
case 28:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
@@ -525,12 +515,14 @@ void JitArm::arith(UGeckoInstruction inst)
SUBS(RD, RB, RA);
break;
case 60:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
BICS(RA, RS, RB);
break;
case 124:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
@@ -545,6 +537,7 @@ void JitArm::arith(UGeckoInstruction inst)
MULS(RD, RA, RB);
break;
case 284:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
@@ -552,6 +545,7 @@ void JitArm::arith(UGeckoInstruction inst)
MVNS(RA, RA);
break;
case 316:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
@@ -559,6 +553,7 @@ void JitArm::arith(UGeckoInstruction inst)
break;
case 412:
{
+ dest = a;
ARMReg rA = gpr.GetReg();
RA = gpr.R(a);
RS = gpr.R(s);
@@ -569,12 +564,14 @@ void JitArm::arith(UGeckoInstruction inst)
}
break;
case 444:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
ORRS(RA, RS, RB);
break;
case 476:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
@@ -582,12 +579,14 @@ void JitArm::arith(UGeckoInstruction inst)
MVNS(RA, RA);
break;
case 536:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
LSRS(RA, RS, RB);
break;
case 792:
+ dest = a;
RA = gpr.R(a);
RS = gpr.R(s);
RB = gpr.R(b);
@@ -605,7 +604,7 @@ void JitArm::arith(UGeckoInstruction inst)
break;
}
if (carry) ComputeCarry();
- if (Rc) isUnsigned ? GenerateRC() : ComputeRC();
+ if (Rc) ComputeRC(gpr.R(dest));
}
void JitArm::addex(UGeckoInstruction inst)
@@ -624,7 +623,7 @@ void JitArm::addex(UGeckoInstruction inst)
GetCarryAndClear(rA);
ADDS(RD, RA, RB);
FinalizeCarry(rA);
- if (inst.Rc) ComputeRC();
+ if (inst.Rc) ComputeRC(RD);
gpr.Unlock(rA);
}
@@ -638,10 +637,7 @@ void JitArm::cntlzwx(UGeckoInstruction inst)
ARMReg RS = gpr.R(s);
CLZ(RA, RS);
if (inst.Rc)
- {
- CMP(RA, 0);
- ComputeRC();
- }
+ ComputeRC(RA);
}
void JitArm::mulhwux(UGeckoInstruction inst)
@@ -655,8 +651,8 @@ void JitArm::mulhwux(UGeckoInstruction inst)
ARMReg RB = gpr.R(b);
ARMReg RD = gpr.R(d);
ARMReg rA = gpr.GetReg(false);
- UMULLS(rA, RD, RA, RB);
- if (inst.Rc) ComputeRC();
+ UMULL(rA, RD, RA, RB);
+ if (inst.Rc) ComputeRC(RD);
}
void JitArm::extshx(UGeckoInstruction inst)
@@ -674,10 +670,8 @@ void JitArm::extshx(UGeckoInstruction inst)
ARMReg rA = gpr.R(a);
ARMReg rS = gpr.R(s);
SXTH(rA, rS);
- if (inst.Rc){
- CMP(rA, 0);
- ComputeRC();
- }
+ if (inst.Rc)
+ ComputeRC(rA);
}
void JitArm::extsbx(UGeckoInstruction inst)
{
@@ -694,10 +688,8 @@ void JitArm::extsbx(UGeckoInstruction inst)
ARMReg rA = gpr.R(a);
ARMReg rS = gpr.R(s);
SXTB(rA, rS);
- if (inst.Rc){
- CMP(rA, 0);
- ComputeRC();
- }
+ if (inst.Rc)
+ ComputeRC(rA);
}
void JitArm::cmp (UGeckoInstruction inst)
{
@@ -713,11 +705,7 @@ void JitArm::cmp (UGeckoInstruction inst)
return;
}
- ARMReg RA = gpr.R(a);
- ARMReg RB = gpr.R(b);
- CMP(RA, RB);
-
- ComputeRC(crf);
+ FALLBACK_IF(true);
}
void JitArm::cmpi(UGeckoInstruction inst)
{
@@ -726,71 +714,12 @@ void JitArm::cmpi(UGeckoInstruction inst)
u32 a = inst.RA;
int crf = inst.CRFD;
if (gpr.IsImm(a))
- ComputeRC((s32)gpr.GetImm(a) - inst.SIMM_16, crf);
- else
- {
- ARMReg RA = gpr.R(a);
- if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256)
- CMP(RA, inst.SIMM_16);
- else
- {
- ARMReg rA = gpr.GetReg();
- MOVI2R(rA, inst.SIMM_16);
- CMP(RA, rA);
- gpr.Unlock(rA);
- }
- ComputeRC(crf);
- }
-}
-void JitArm::cmpl(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITIntegerOff);
-
- ARMReg RA = gpr.R(inst.RA);
- ARMReg RB = gpr.R(inst.RB);
- ARMReg rA = gpr.GetReg();
- int crf = inst.CRFD;
-
- CMP(RA, RB);
- // Unsigned GenerateRC()
-
- MOV(rA, 0x2); // Result == 0
- SetCC(CC_LO); MOV(rA, 0x8); // Result < 0
- SetCC(CC_HI); MOV(rA, 0x4); // Result > 0
- SetCC();
-
- STRB(rA, R9, PPCSTATE_OFF(cr_fast) + crf);
- gpr.Unlock(rA);
-}
-
-void JitArm::cmpli(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITIntegerOff);
-
- ARMReg RA = gpr.R(inst.RA);
- ARMReg rA = gpr.GetReg();
- int crf = inst.CRFD;
- u32 uimm = (u32)inst.UIMM;
- if (uimm < 256)
- {
- CMP(RA, uimm);
- }
- else
{
- MOVI2R(rA, (u32)inst.UIMM);
- CMP(RA, rA);
+ ComputeRC((s32)gpr.GetImm(a) - inst.SIMM_16, crf);
+ return;
}
- // Unsigned GenerateRC()
-
- MOV(rA, 0x2); // Result == 0
- SetCC(CC_LO); MOV(rA, 0x8); // Result < 0
- SetCC(CC_HI); MOV(rA, 0x4); // Result > 0
- SetCC();
- STRB(rA, R9, PPCSTATE_OFF(cr_fast) + crf);
- gpr.Unlock(rA);
+ FALLBACK_IF(true);
}
void JitArm::negx(UGeckoInstruction inst)
@@ -801,11 +730,10 @@ void JitArm::negx(UGeckoInstruction inst)
ARMReg RA = gpr.R(inst.RA);
ARMReg RD = gpr.R(inst.RD);
- RSBS(RD, RA, 0);
+ RSB(RD, RA, 0);
if (inst.Rc)
- {
- GenerateRC();
- }
+ ComputeRC(RD);
+
if (inst.OE)
{
BKPT(0x333);
@@ -825,19 +753,12 @@ void JitArm::rlwimix(UGeckoInstruction inst)
MOVI2R(rA, mask);
Operand2 Shift(RS, ST_ROR, 32 - inst.SH); // This rotates left, while ARM has only rotate right, so swap it.
+ BIC (rB, RA, rA); // RA & ~mask
+ AND (rA, rA, Shift);
+ ORR(RA, rB, rA);
+
if (inst.Rc)
- {
- BIC (rB, RA, rA); // RA & ~mask
- AND (rA, rA, Shift);
- ORRS(RA, rB, rA);
- GenerateRC();
- }
- else
- {
- BIC (rB, RA, rA); // RA & ~mask
- AND (rA, rA, Shift);
- ORR(RA, rB, rA);
- }
+ ComputeRC(RA);
gpr.Unlock(rA, rB);
}
@@ -853,13 +774,10 @@ void JitArm::rlwinmx(UGeckoInstruction inst)
MOVI2R(rA, mask);
Operand2 Shift(RS, ST_ROR, 32 - inst.SH); // This rotates left, while ARM has only rotate right, so swap it.
+ AND(RA, rA, Shift);
+
if (inst.Rc)
- {
- ANDS(RA, rA, Shift);
- GenerateRC();
- }
- else
- AND (RA, rA, Shift);
+ ComputeRC(RA);
gpr.Unlock(rA);
//m_GPR[inst.RA] = _rotl(m_GPR[inst.RS],inst.SH) & mask;
@@ -882,13 +800,10 @@ void JitArm::rlwnmx(UGeckoInstruction inst)
SUB(rB, rB, RB);
Operand2 Shift(RS, ST_ROR, rB); // Register shifted register
+ AND(RA, rA, Shift);
+
if (inst.Rc)
- {
- ANDS(RA, rA, Shift);
- GenerateRC();
- }
- else
- AND (RA, rA, Shift);
+ ComputeRC(RA);
gpr.Unlock(rA, rB);
}
@@ -908,9 +823,9 @@ void JitArm::srawix(UGeckoInstruction inst)
Operand2 mask = Operand2(2, 2); // XER_CA_MASK
MOV(tmp, RS);
- ASRS(RA, RS, amount);
+ ASR(RA, RS, amount);
if (inst.Rc)
- GenerateRC();
+ ComputeRC(RA);
LSL(tmp, tmp, 32 - amount);
TST(tmp, RA);
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_Paired.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_Paired.cpp
index 4584058206..520e243327 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_Paired.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_Paired.cpp
@@ -611,263 +611,4 @@ void JitArm::ps_nabs(UGeckoInstruction inst)
VABS(vD1, vB1);
VNEG(vD1, vD1);
}
-void JitArm::ps_cmpu0(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITFloatingPointOff);
- u32 a = inst.FA, b = inst.FB;
- int cr = inst.CRFD;
-
- ARMReg vA = fpr.R0(a);
- ARMReg vB = fpr.R0(b);
- ARMReg fpscrReg = gpr.GetReg();
- ARMReg crReg = gpr.GetReg();
- Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
- Operand2 LessThan(0x8, 0xA); // 0x8000
- Operand2 GreaterThan(0x4, 0xA); // 0x4000
- Operand2 EqualTo(0x2, 0xA); // 0x2000
- Operand2 NANRes(0x1, 0xA); // 0x1000
- FixupBranch Done1, Done2, Done3;
- LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- BIC(fpscrReg, fpscrReg, FPRFMask);
-
- VCMPE(vA, vB);
- VMRS(_PC);
- SetCC(CC_LT);
- ORR(fpscrReg, fpscrReg, LessThan);
- MOV(crReg, 8);
- Done1 = B();
- SetCC(CC_GT);
- ORR(fpscrReg, fpscrReg, GreaterThan);
- MOV(crReg, 4);
- Done2 = B();
- SetCC(CC_EQ);
- ORR(fpscrReg, fpscrReg, EqualTo);
- MOV(crReg, 2);
- Done3 = B();
- SetCC();
-
- ORR(fpscrReg, fpscrReg, NANRes);
- MOV(crReg, 1);
-
- VCMPE(vA, vA);
- VMRS(_PC);
- FixupBranch NanA = B_CC(CC_NEQ);
- VCMPE(vB, vB);
- VMRS(_PC);
- FixupBranch NanB = B_CC(CC_NEQ);
- FixupBranch Done4 = B();
-
- SetJumpTarget(NanA);
- SetJumpTarget(NanB);
-
- SetFPException(fpscrReg, FPSCR_VXSNAN);
-
- SetJumpTarget(Done1);
- SetJumpTarget(Done2);
- SetJumpTarget(Done3);
- SetJumpTarget(Done4);
- STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
- STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- gpr.Unlock(fpscrReg, crReg);
-}
-
-void JitArm::ps_cmpu1(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITFloatingPointOff);
- u32 a = inst.FA, b = inst.FB;
- int cr = inst.CRFD;
-
- ARMReg vA = fpr.R1(a);
- ARMReg vB = fpr.R1(b);
- ARMReg fpscrReg = gpr.GetReg();
- ARMReg crReg = gpr.GetReg();
- Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
- Operand2 LessThan(0x8, 0xA); // 0x8000
- Operand2 GreaterThan(0x4, 0xA); // 0x4000
- Operand2 EqualTo(0x2, 0xA); // 0x2000
- Operand2 NANRes(0x1, 0xA); // 0x1000
- FixupBranch Done1, Done2, Done3;
- LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- BIC(fpscrReg, fpscrReg, FPRFMask);
-
- VCMPE(vA, vB);
- VMRS(_PC);
- SetCC(CC_LT);
- ORR(fpscrReg, fpscrReg, LessThan);
- MOV(crReg, 8);
- Done1 = B();
- SetCC(CC_GT);
- ORR(fpscrReg, fpscrReg, GreaterThan);
- MOV(crReg, 4);
- Done2 = B();
- SetCC(CC_EQ);
- ORR(fpscrReg, fpscrReg, EqualTo);
- MOV(crReg, 2);
- Done3 = B();
- SetCC();
-
- ORR(fpscrReg, fpscrReg, NANRes);
- MOV(crReg, 1);
-
- VCMPE(vA, vA);
- VMRS(_PC);
- FixupBranch NanA = B_CC(CC_NEQ);
- VCMPE(vB, vB);
- VMRS(_PC);
- FixupBranch NanB = B_CC(CC_NEQ);
- FixupBranch Done4 = B();
-
- SetJumpTarget(NanA);
- SetJumpTarget(NanB);
-
- SetFPException(fpscrReg, FPSCR_VXSNAN);
-
- SetJumpTarget(Done1);
- SetJumpTarget(Done2);
- SetJumpTarget(Done3);
- SetJumpTarget(Done4);
- STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
- STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- gpr.Unlock(fpscrReg, crReg);
-}
-
-void JitArm::ps_cmpo0(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITFloatingPointOff);
- u32 a = inst.FA, b = inst.FB;
- int cr = inst.CRFD;
-
- ARMReg vA = fpr.R0(a);
- ARMReg vB = fpr.R0(b);
- ARMReg fpscrReg = gpr.GetReg();
- ARMReg crReg = gpr.GetReg();
- Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
- Operand2 LessThan(0x8, 0xA); // 0x8000
- Operand2 GreaterThan(0x4, 0xA); // 0x4000
- Operand2 EqualTo(0x2, 0xA); // 0x2000
- Operand2 NANRes(0x1, 0xA); // 0x1000
- FixupBranch Done1, Done2, Done3;
- LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- BIC(fpscrReg, fpscrReg, FPRFMask);
-
- VCMPE(vA, vB);
- VMRS(_PC);
- SetCC(CC_LT);
- ORR(fpscrReg, fpscrReg, LessThan);
- MOV(crReg, 8);
- Done1 = B();
- SetCC(CC_GT);
- ORR(fpscrReg, fpscrReg, GreaterThan);
- MOV(crReg, 4);
- Done2 = B();
- SetCC(CC_EQ);
- ORR(fpscrReg, fpscrReg, EqualTo);
- MOV(crReg, 2);
- Done3 = B();
- SetCC();
-
- ORR(fpscrReg, fpscrReg, NANRes);
- MOV(crReg, 1);
-
- VCMPE(vA, vA);
- VMRS(_PC);
- FixupBranch NanA = B_CC(CC_NEQ);
- VCMPE(vB, vB);
- VMRS(_PC);
- FixupBranch NanB = B_CC(CC_NEQ);
-
- SetFPException(fpscrReg, FPSCR_VXVC);
- FixupBranch Done4 = B();
-
- SetJumpTarget(NanA);
- SetJumpTarget(NanB);
-
- SetFPException(fpscrReg, FPSCR_VXSNAN);
-
- TST(fpscrReg, VEMask);
-
- FixupBranch noVXVC = B_CC(CC_NEQ);
- SetFPException(fpscrReg, FPSCR_VXVC);
-
- SetJumpTarget(noVXVC);
- SetJumpTarget(Done1);
- SetJumpTarget(Done2);
- SetJumpTarget(Done3);
- SetJumpTarget(Done4);
- STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
- STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- gpr.Unlock(fpscrReg, crReg);
-}
-
-void JitArm::ps_cmpo1(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITFloatingPointOff);
- u32 a = inst.FA, b = inst.FB;
- int cr = inst.CRFD;
-
- ARMReg vA = fpr.R1(a);
- ARMReg vB = fpr.R1(b);
- ARMReg fpscrReg = gpr.GetReg();
- ARMReg crReg = gpr.GetReg();
- Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
- Operand2 LessThan(0x8, 0xA); // 0x8000
- Operand2 GreaterThan(0x4, 0xA); // 0x4000
- Operand2 EqualTo(0x2, 0xA); // 0x2000
- Operand2 NANRes(0x1, 0xA); // 0x1000
- FixupBranch Done1, Done2, Done3;
- LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- BIC(fpscrReg, fpscrReg, FPRFMask);
-
- VCMPE(vA, vB);
- VMRS(_PC);
- SetCC(CC_LT);
- ORR(fpscrReg, fpscrReg, LessThan);
- MOV(crReg, 8);
- Done1 = B();
- SetCC(CC_GT);
- ORR(fpscrReg, fpscrReg, GreaterThan);
- MOV(crReg, 4);
- Done2 = B();
- SetCC(CC_EQ);
- ORR(fpscrReg, fpscrReg, EqualTo);
- MOV(crReg, 2);
- Done3 = B();
- SetCC();
-
- ORR(fpscrReg, fpscrReg, NANRes);
- MOV(crReg, 1);
-
- VCMPE(vA, vA);
- VMRS(_PC);
- FixupBranch NanA = B_CC(CC_NEQ);
- VCMPE(vB, vB);
- VMRS(_PC);
- FixupBranch NanB = B_CC(CC_NEQ);
-
- SetFPException(fpscrReg, FPSCR_VXVC);
- FixupBranch Done4 = B();
-
- SetJumpTarget(NanA);
- SetJumpTarget(NanB);
-
- SetFPException(fpscrReg, FPSCR_VXSNAN);
-
- TST(fpscrReg, VEMask);
-
- FixupBranch noVXVC = B_CC(CC_NEQ);
- SetFPException(fpscrReg, FPSCR_VXVC);
-
- SetJumpTarget(noVXVC);
- SetJumpTarget(Done1);
- SetJumpTarget(Done2);
- SetJumpTarget(Done3);
- SetJumpTarget(Done4);
- STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
- STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
- gpr.Unlock(fpscrReg, crReg);
-}
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_SystemRegisters.cpp
index ff129f9674..d17e61a88f 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_SystemRegisters.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_SystemRegisters.cpp
@@ -14,6 +14,46 @@
#include "Core/PowerPC/JitArm32/JitAsm.h"
#include "Core/PowerPC/JitArm32/JitRegCache.h"
+FixupBranch JitArm::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
+{
+ ARMReg RA = gpr.GetReg();
+
+ Operand2 SOBit(2, 2); // 0x10000000
+ Operand2 LTBit(1, 1); // 0x80000000
+
+ FixupBranch branch;
+ switch (bit)
+ {
+ case CR_SO_BIT: // check bit 61 set
+ LDR(RA, R9, PPCSTATE_OFF(cr_val[field]) + sizeof(u32));
+ TST(RA, SOBit);
+ branch = B_CC(jump_if_set ? CC_NEQ : CC_EQ);
+ break;
+ case CR_EQ_BIT: // check bits 31-0 == 0
+ LDR(RA, R9, PPCSTATE_OFF(cr_val[field]));
+ CMP(RA, 0);
+ branch = B_CC(jump_if_set ? CC_EQ : CC_NEQ);
+ break;
+ case CR_GT_BIT: // check val > 0
+ LDR(RA, R9, PPCSTATE_OFF(cr_val[field]));
+ CMP(RA, 1);
+ LDR(RA, R9, PPCSTATE_OFF(cr_val[field]) + sizeof(u32));
+ SBCS(RA, RA, 0);
+ branch = B_CC(jump_if_set ? CC_GE : CC_LT);
+ break;
+ case CR_LT_BIT: // check bit 62 set
+ LDR(RA, R9, PPCSTATE_OFF(cr_val[field]) + sizeof(u32));
+ TST(RA, LTBit);
+ branch = B_CC(jump_if_set ? CC_NEQ : CC_EQ);
+ break;
+ default:
+ _assert_msg_(DYNA_REC, false, "Invalid CR bit");
+ }
+
+ gpr.Unlock(RA);
+ return branch;
+}
+
void JitArm::mtspr(UGeckoInstruction inst)
{
INSTRUCTION_START
@@ -84,67 +124,6 @@ void JitArm::mfspr(UGeckoInstruction inst)
}
}
-void JitArm::mfcr(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITSystemRegistersOff);
- // USES_CR
- ARMReg rA = gpr.GetReg();
- ARMReg rB = gpr.GetReg();
- int d = inst.RD;
- LDRB(rA, R9, PPCSTATE_OFF(cr_fast[0]));
-
- for (int i = 1; i < 8; i++)
- {
- LDRB(rB, R9, PPCSTATE_OFF(cr_fast[i]));
- LSL(rA, rA, 4);
- ORR(rA, rA, rB);
- }
- MOV(gpr.R(d), rA);
- gpr.Unlock(rA, rB);
-}
-
-void JitArm::mtcrf(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITSystemRegistersOff);
-
- ARMReg rA = gpr.GetReg();
-
- // USES_CR
- u32 crm = inst.CRM;
- if (crm != 0)
- {
- if (gpr.IsImm(inst.RS))
- {
- for (int i = 0; i < 8; i++)
- {
- if ((crm & (0x80 >> i)) != 0)
- {
- u8 newcr = (gpr.GetImm(inst.RS) >> (28 - (i * 4))) & 0xF;
- MOV(rA, newcr);
- STRB(rA, R9, PPCSTATE_OFF(cr_fast[i]));
- }
- }
- }
- else
- {
- ARMReg rB = gpr.GetReg();
- MOV(rA, gpr.R(inst.RS));
- for (int i = 0; i < 8; i++)
- {
- if ((crm & (0x80 >> i)) != 0)
- {
- UBFX(rB, rA, 28 - (i * 4), 4);
- STRB(rB, R9, PPCSTATE_OFF(cr_fast[i]));
- }
- }
- gpr.Unlock(rB);
- }
- }
- gpr.Unlock(rA);
-}
-
void JitArm::mtsr(UGeckoInstruction inst)
{
INSTRUCTION_START
@@ -160,25 +139,6 @@ void JitArm::mfsr(UGeckoInstruction inst)
LDR(gpr.R(inst.RD), R9, PPCSTATE_OFF(sr[inst.SR]));
}
-void JitArm::mcrxr(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITSystemRegistersOff);
-
- ARMReg rA = gpr.GetReg();
- ARMReg rB = gpr.GetReg();
- // Copy XER[0-3] into CR[inst.CRFD]
- LDR(rA, R9, PPCSTATE_OFF(spr[SPR_XER]));
- MOV(rB, rA);
- LSR(rA, rA, 28);
- STRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRFD]));
-
- // Clear XER[0-3]
- Operand2 Top4(0xF, 2);
- BIC(rB, rB, Top4);
- STR(rB, R9, PPCSTATE_OFF(spr[SPR_XER]));
- gpr.Unlock(rA, rB);
-}
void JitArm::mtmsr(UGeckoInstruction inst)
{
@@ -206,84 +166,16 @@ void JitArm::mcrf(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITSystemRegistersOff);
+
ARMReg rA = gpr.GetReg();
if (inst.CRFS != inst.CRFD)
{
- LDRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRFS]));
- STRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRFD]));
+ LDR(rA, R9, PPCSTATE_OFF(cr_val[inst.CRFS]));
+ STR(rA, R9, PPCSTATE_OFF(cr_val[inst.CRFD]));
+ LDR(rA, R9, PPCSTATE_OFF(cr_val[inst.CRFS]) + sizeof(u32));
+ STR(rA, R9, PPCSTATE_OFF(cr_val[inst.CRFD]) + sizeof(u32));
}
gpr.Unlock(rA);
}
-void JitArm::crXXX(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITSystemRegistersOff);
-
- ARMReg rA = gpr.GetReg();
- ARMReg rB = gpr.GetReg();
- // Get bit CRBA aligned with bit CRBD
- LDRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRBA >> 2]));
- int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3);
- if (shiftA < 0)
- LSL(rA, rA, -shiftA);
- else if (shiftA > 0)
- LSR(rA, rA, shiftA);
-
- // Get bit CRBB aligned with bit CRBD
- int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3);
- LDRB(rB, R9, PPCSTATE_OFF(cr_fast[inst.CRBB >> 2]));
- if (shiftB < 0)
- LSL(rB, rB, -shiftB);
- else if (shiftB > 0)
- LSR(rB, rB, shiftB);
-
- // Compute combined bit
- switch (inst.SUBOP10)
- {
- case 33: // crnor
- ORR(rA, rA, rB);
- MVN(rA, rA);
- break;
-
- case 129: // crandc
- MVN(rB, rB);
- AND(rA, rA, rB);
- break;
-
- case 193: // crxor
- EOR(rA, rA, rB);
- break;
-
- case 225: // crnand
- AND(rA, rA, rB);
- MVN(rA, rA);
- break;
-
- case 257: // crand
- AND(rA, rA, rB);
- break;
-
- case 289: // creqv
- EOR(rA, rA, rB);
- MVN(rA, rA);
- break;
-
- case 417: // crorc
- MVN(rA, rA);
- ORR(rA, rA, rB);
- break;
-
- case 449: // cror
- ORR(rA, rA, rB);
- break;
- }
- // Store result bit in CRBD
- AND(rA, rA, 0x8 >> (inst.CRBD & 3));
- LDRB(rB, R9, PPCSTATE_OFF(cr_fast[inst.CRBD >> 2]));
- BIC(rB, rB, 0x8 >> (inst.CRBD & 3));
- ORR(rB, rB, rA);
- STRB(rB, R9, PPCSTATE_OFF(cr_fast[inst.CRBD >> 2]));
- gpr.Unlock(rA, rB);
-}
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_Tables.cpp
index 5176a4e8d9..d7c1882f44 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_Tables.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_Tables.cpp
@@ -47,7 +47,7 @@ static GekkoOPTemplate primarytable[] =
{7, &JitArm::arith}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
{8, &JitArm::subfic}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
- {10, &JitArm::cmpli}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
+ {10, &JitArm::FallBackToInterpreter}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
{11, &JitArm::cmpi}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
{12, &JitArm::arith}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
{13, &JitArm::arith}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}},
@@ -112,14 +112,14 @@ static GekkoOPTemplate primarytable[] =
static GekkoOPTemplate table4[] =
{ //SUBOP10
- {0, &JitArm::ps_cmpu0}, //"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}},
- {32, &JitArm::ps_cmpo0}, //"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}},
+ {0, &JitArm::FallBackToInterpreter}, //"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}},
+ {32, &JitArm::FallBackToInterpreter}, //"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}},
{40, &JitArm::ps_neg}, //"ps_neg", OPTYPE_PS, FL_RC_BIT}},
{136, &JitArm::ps_nabs}, //"ps_nabs", OPTYPE_PS, FL_RC_BIT}},
{264, &JitArm::ps_abs}, //"ps_abs", OPTYPE_PS, FL_RC_BIT}},
- {64, &JitArm::ps_cmpu1}, //"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}},
+ {64, &JitArm::FallBackToInterpreter}, //"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}},
{72, &JitArm::ps_mr}, //"ps_mr", OPTYPE_PS, FL_RC_BIT}},
- {96, &JitArm::ps_cmpo1}, //"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}},
+ {96, &JitArm::FallBackToInterpreter}, //"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}},
{528, &JitArm::ps_merge00}, //"ps_merge00", OPTYPE_PS, FL_RC_BIT}},
{560, &JitArm::ps_merge01}, //"ps_merge01", OPTYPE_PS, FL_RC_BIT}},
{592, &JitArm::ps_merge10}, //"ps_merge10", OPTYPE_PS, FL_RC_BIT}},
@@ -162,14 +162,14 @@ static GekkoOPTemplate table19[] =
{
{528, &JitArm::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
{16, &JitArm::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
- {257, &JitArm::crXXX}, //"crand", OPTYPE_CR, FL_EVIL}},
- {129, &JitArm::crXXX}, //"crandc", OPTYPE_CR, FL_EVIL}},
- {289, &JitArm::crXXX}, //"creqv", OPTYPE_CR, FL_EVIL}},
- {225, &JitArm::crXXX}, //"crnand", OPTYPE_CR, FL_EVIL}},
- {33, &JitArm::crXXX}, //"crnor", OPTYPE_CR, FL_EVIL}},
- {449, &JitArm::crXXX}, //"cror", OPTYPE_CR, FL_EVIL}},
- {417, &JitArm::crXXX}, //"crorc", OPTYPE_CR, FL_EVIL}},
- {193, &JitArm::crXXX}, //"crxor", OPTYPE_CR, FL_EVIL}},
+ {257, &JitArm::FallBackToInterpreter}, //"crand", OPTYPE_CR, FL_EVIL}},
+ {129, &JitArm::FallBackToInterpreter}, //"crandc", OPTYPE_CR, FL_EVIL}},
+ {289, &JitArm::FallBackToInterpreter}, //"creqv", OPTYPE_CR, FL_EVIL}},
+ {225, &JitArm::FallBackToInterpreter}, //"crnand", OPTYPE_CR, FL_EVIL}},
+ {33, &JitArm::FallBackToInterpreter}, //"crnor", OPTYPE_CR, FL_EVIL}},
+ {449, &JitArm::FallBackToInterpreter}, //"cror", OPTYPE_CR, FL_EVIL}},
+ {417, &JitArm::FallBackToInterpreter}, //"crorc", OPTYPE_CR, FL_EVIL}},
+ {193, &JitArm::FallBackToInterpreter}, //"crxor", OPTYPE_CR, FL_EVIL}},
{150, &JitArm::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}},
{0, &JitArm::mcrf}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
@@ -190,7 +190,7 @@ static GekkoOPTemplate table31[] =
{476, &JitArm::arith}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{284, &JitArm::arith}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{0, &JitArm::cmp}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
- {32, &JitArm::cmpl}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
+ {32, &JitArm::FallBackToInterpreter}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{26, &JitArm::cntlzwx}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{922, &JitArm::extshx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{954, &JitArm::extsbx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
@@ -266,16 +266,16 @@ static GekkoOPTemplate table31[] =
{759, &JitArm::stfXX}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
{983, &JitArm::FallBackToInterpreter}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
- {19, &JitArm::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
+ {19, &JitArm::FallBackToInterpreter}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
{83, &JitArm::mfmsr}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}},
- {144, &JitArm::mtcrf}, //"mtcrf", OPTYPE_SYSTEM, 0}},
+ {144, &JitArm::FallBackToInterpreter}, //"mtcrf", OPTYPE_SYSTEM, 0}},
{146, &JitArm::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{210, &JitArm::mtsr}, //"mtsr", OPTYPE_SYSTEM, 0}},
{242, &JitArm::FallBackToInterpreter}, //"mtsrin", OPTYPE_SYSTEM, 0}},
{339, &JitArm::mfspr}, //"mfspr", OPTYPE_SPR, FL_OUT_D}},
{467, &JitArm::mtspr}, //"mtspr", OPTYPE_SPR, 0, 2}},
{371, &JitArm::mftb}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}},
- {512, &JitArm::mcrxr}, //"mcrxr", OPTYPE_SYSTEM, 0}},
+ {512, &JitArm::FallBackToInterpreter}, //"mcrxr", OPTYPE_SYSTEM, 0}},
{595, &JitArm::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
{659, &JitArm::FallBackToInterpreter}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
@@ -337,8 +337,8 @@ static GekkoOPTemplate table59[] =
static GekkoOPTemplate table63[] =
{
{264, &JitArm::fabsx}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}},
- {32, &JitArm::fcmpo}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}},
- {0, &JitArm::fcmpu}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}},
+ {32, &JitArm::FallBackToInterpreter}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}},
+ {0, &JitArm::FallBackToInterpreter}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}},
{14, &JitArm::fctiwx}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}},
{15, &JitArm::fctiwzx}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}},
{72, &JitArm::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}},