summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2015-01-22 10:31:22 -0600
committerRyan Houdek <Sonicadvance1@gmail.com>2015-01-22 10:31:22 -0600
commitbb1ca26c57445c6d66f0016562f21f56efce6ffc (patch)
tree012ec1757598f0f6795330a308f2645cd2d742b4 /Source/Core
parentd27bd9d291a178892674cdffc397b586b37c0f2b (diff)
parent85754c63cac812311ccc5eb7a3c74b9f2a4b5490 (diff)
Merge pull request #1940 from Sonicadvance1/AArch64_implement_xer
[AArch64] Implement mfspr/mtspr XER routines.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
index 01df60015f..fab8eb7247 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
@@ -206,6 +206,18 @@ void JitArm64::mfspr(UGeckoInstruction inst)
switch (iIndex)
{
case SPR_XER:
+ {
+ gpr.BindToRegister(inst.RD, false);
+ ARM64Reg RD = gpr.R(inst.RD);
+ ARM64Reg WA = gpr.GetReg();
+ LDRH(INDEX_UNSIGNED, RD, X29, PPCSTATE_OFF(xer_stringctrl));
+ LDRB(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_ca));
+ ORR(RD, RD, WA, ArithOption(WA, ST_LSL, XER_CA_SHIFT));
+ LDRB(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_so_ov));
+ ORR(RD, RD, WA, ArithOption(WA, ST_LSL, XER_OV_SHIFT));
+ gpr.Unlock(WA);
+ }
+ break;
case SPR_WPAR:
case SPR_DEC:
case SPR_TL:
@@ -261,18 +273,15 @@ void JitArm64::mtspr(UGeckoInstruction inst)
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));
+ AND(WA, RD, 24, 30);
STRH(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_stringctrl));
- UBFM(WA, RD, XER_CA_SHIFT, XER_CA_SHIFT);
+ UBFM(WA, RD, XER_CA_SHIFT, XER_CA_SHIFT + 1);
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);
+ gpr.Unlock(WA);
}
break;
default: