From 302e9c891b66173fa47e4d9363c7f09b6d46f3be Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 17 Sep 2013 10:59:12 +0000 Subject: [PATCH] [ARM] crand/crandc/creqv/crnand/crnor/cror/crorc/crxor/mcrf/mfcr/mtcrf/mtsr/mcrxr/mfsr implementations. --- Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 7 + .../JitArm32/JitArm_SystemRegisters.cpp | 181 ++++++++++++++++++ .../Src/PowerPC/JitArm32/JitArm_Tables.cpp | 28 +-- 3 files changed, 202 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index aec0ee85d9..e4bf7d6941 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -179,6 +179,13 @@ 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); // LoadStore void stX(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp index 5509687184..c1e0678910 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp @@ -85,6 +85,101 @@ void JitArm::mfspr(UGeckoInstruction inst) break; } } + +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 + { + for (int i = 0; i < 8; i++) + { + if ((crm & (0x80 >> i)) != 0) + { + MOV(rA, gpr.R(inst.RS)); + LSR(rA, rA, 28 - (i * 4)); + AND(rA, rA, 0xF); + STRB(rA, R9, PPCSTATE_OFF(cr_fast[i])); + } + } + } + } + gpr.Unlock(rA); +} + +void JitArm::mtsr(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITSystemRegistersOff) + + STR(gpr.R(inst.RS), R9, PPCSTATE_OFF(sr[inst.SR])); +} + +void JitArm::mfsr(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITSystemRegistersOff) + + 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) { INSTRUCTION_START @@ -98,6 +193,7 @@ void JitArm::mtmsr(UGeckoInstruction inst) WriteExit(js.compilerPC + 4, 0); } + void JitArm::mfmsr(UGeckoInstruction inst) { INSTRUCTION_START @@ -106,3 +202,88 @@ void JitArm::mfmsr(UGeckoInstruction inst) LDR(gpr.R(inst.RD), R9, PPCSTATE_OFF(msr)); } +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])); + } + 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); + RBIT(rA, rA); + break; + + case 129: // crandc + RBIT(rB, rB); + AND(rA, rA, rB); + break; + + case 193: // crxor + EOR(rA, rA, rB); + break; + + case 225: // crnand + AND(rA, rA, rB); + RBIT(rA, rA); + break; + + case 257: // crand + AND(rA, rA, rB); + break; + + case 289: // creqv + EOR(rA, rA, rB); + RBIT(rA, rA); + break; + + case 417: // crorc + RBIT(rB, rB); + 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/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 8f0417f447..514cce035b 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -175,17 +175,17 @@ static GekkoOPTemplate table19[] = { {528, &JitArm::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, {16, &JitArm::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, - {257, &JitArm::Default}, //"crand", OPTYPE_CR, FL_EVIL}}, - {129, &JitArm::Default}, //"crandc", OPTYPE_CR, FL_EVIL}}, - {289, &JitArm::Default}, //"creqv", OPTYPE_CR, FL_EVIL}}, - {225, &JitArm::Default}, //"crnand", OPTYPE_CR, FL_EVIL}}, - {33, &JitArm::Default}, //"crnor", OPTYPE_CR, FL_EVIL}}, - {449, &JitArm::Default}, //"cror", OPTYPE_CR, FL_EVIL}}, - {417, &JitArm::Default}, //"crorc", OPTYPE_CR, FL_EVIL}}, - {193, &JitArm::Default}, //"crxor", OPTYPE_CR, FL_EVIL}}, + {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}}, {150, &JitArm::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}}, - {0, &JitArm::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}}, + {0, &JitArm::mcrf}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}}, {50, &JitArm::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}}, {18, &JitArm::Break}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}} @@ -279,17 +279,17 @@ static GekkoOPTemplate table31[] = {759, &JitArm::Default}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, {983, &JitArm::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, - {19, &JitArm::Default}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}}, + {19, &JitArm::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}}, {83, &JitArm::mfmsr}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}}, - {144, &JitArm::Default}, //"mtcrf", OPTYPE_SYSTEM, 0}}, + {144, &JitArm::mtcrf}, //"mtcrf", OPTYPE_SYSTEM, 0}}, {146, &JitArm::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}}, - {210, &JitArm::Default}, //"mtsr", OPTYPE_SYSTEM, 0}}, + {210, &JitArm::mtsr}, //"mtsr", OPTYPE_SYSTEM, 0}}, {242, &JitArm::Default}, //"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::Default}, //"mcrxr", OPTYPE_SYSTEM, 0}}, - {595, &JitArm::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, + {512, &JitArm::mcrxr}, //"mcrxr", OPTYPE_SYSTEM, 0}}, + {595, &JitArm::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},