From 602702fdcb1b7d80be59e8deeb09e1a186d4fa9f Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 7 Jan 2015 14:59:41 -0600 Subject: [PATCH] [AArch64] Implement three system register instructions. --- Source/Core/Core/PowerPC/JitArm64/Jit.h | 3 + .../JitArm64/JitArm64_SystemRegisters.cpp | 87 +++++++++++++++++++ .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 6 +- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index d3e51ee168..bff5061432 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -108,6 +108,9 @@ public: void mfsrin(UGeckoInstruction inst); void mtsrin(UGeckoInstruction inst); void twx(UGeckoInstruction inst); + void mfspr(UGeckoInstruction inst); + void mftb(UGeckoInstruction inst); + void mtspr(UGeckoInstruction inst); // LoadStore void icbi(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp index ea6ea6c46a..01df60015f 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp @@ -196,3 +196,90 @@ void JitArm64::twx(UGeckoInstruction inst) WriteExit(js.compilerPC + 4); } } + +void JitArm64::mfspr(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITSystemRegistersOff); + + u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + switch (iIndex) + { + case SPR_XER: + case SPR_WPAR: + case SPR_DEC: + case SPR_TL: + case SPR_TU: + FALLBACK_IF(true); + default: + gpr.BindToRegister(inst.RD, false); + ARM64Reg RD = gpr.R(inst.RD); + LDR(INDEX_UNSIGNED, RD, X29, PPCSTATE_OFF(spr) + iIndex * 4); + break; + } +} + +void JitArm64::mftb(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITSystemRegistersOff); + mfspr(inst); +} + +void JitArm64::mtspr(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITSystemRegistersOff); + + u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + + switch (iIndex) + { + case SPR_DMAU: + + case SPR_SPRG0: + case SPR_SPRG1: + case SPR_SPRG2: + case SPR_SPRG3: + + case SPR_SRR0: + case SPR_SRR1: + // These are safe to do the easy way, see the bottom of this function. + break; + + case SPR_LR: + case SPR_CTR: + case SPR_GQR0: + case SPR_GQR0 + 1: + case SPR_GQR0 + 2: + case SPR_GQR0 + 3: + case SPR_GQR0 + 4: + case SPR_GQR0 + 5: + case SPR_GQR0 + 6: + case SPR_GQR0 + 7: + // These are safe to do the easy way, see the bottom of this function. + break; + case SPR_XER: + { + FALLBACK_IF(true); + ARM64Reg RD = gpr.R(inst.RD); + ARM64Reg WA = gpr.GetReg(); + ARM64Reg mask = gpr.GetReg(); + MOVI2R(mask, 0xFF7F); + AND(WA, RD, mask, ArithOption(mask, ST_LSL, 0)); + STRH(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_stringctrl)); + UBFM(WA, RD, XER_CA_SHIFT, XER_CA_SHIFT); + STRB(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_ca)); + UBFM(WA, RD, XER_OV_SHIFT, 31); // Same as WA = RD >> XER_OV_SHIFT + STRB(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_so_ov)); + gpr.Unlock(WA, mask); + } + break; + default: + FALLBACK_IF(true); + } + + // OK, this is easy. + ARM64Reg RD = gpr.R(inst.RD); + STR(INDEX_UNSIGNED, RD, X29, PPCSTATE_OFF(spr) + iIndex * 4); +} diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index fae0a3bdc9..84721f58ec 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -272,9 +272,9 @@ static GekkoOPTemplate table31[] = {146, &JitArm64::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {210, &JitArm64::mtsr}, //"mtsr", OPTYPE_SYSTEM, 0}}, {242, &JitArm64::mtsrin}, //"mtsrin", OPTYPE_SYSTEM, 0}}, - {339, &JitArm64::FallBackToInterpreter}, //"mfspr", OPTYPE_SPR, FL_OUT_D}}, - {467, &JitArm64::FallBackToInterpreter}, //"mtspr", OPTYPE_SPR, 0, 2}}, - {371, &JitArm64::FallBackToInterpreter}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}}, + {339, &JitArm64::mfspr}, //"mfspr", OPTYPE_SPR, FL_OUT_D}}, + {467, &JitArm64::mtspr}, //"mtspr", OPTYPE_SPR, 0, 2}}, + {371, &JitArm64::mftb}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}}, {512, &JitArm64::FallBackToInterpreter}, //"mcrxr", OPTYPE_SYSTEM, 0}}, {595, &JitArm64::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {659, &JitArm64::mfsrin}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},