summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2015-01-07 14:59:41 -0600
committerRyan Houdek <Sonicadvance1@gmail.com>2015-01-08 19:56:47 -0600
commit602702fdcb1b7d80be59e8deeb09e1a186d4fa9f (patch)
treeef6e587bbcd23f57c450eca83da9c81a13a7176f /Source/Core
parent0dd3804cf77c5edef79aa12e4e82770814f07a7d (diff)
[AArch64] Implement three system register instructions.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h3
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp87
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp6
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}},