From 7b9565c4e677792631e1c62781f1318b0321e811 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 4 Jun 2015 22:16:27 -0500 Subject: [PATCH] [AArch64] Implement lmw/stmw. --- Source/Core/Core/PowerPC/JitArm64/Jit.h | 2 + .../PowerPC/JitArm64/JitArm64_LoadStore.cpp | 111 ++++++++++++++++++ .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 4 +- 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 18463b669e..55c7b86435 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -115,6 +115,8 @@ public: void icbi(UGeckoInstruction inst); void lXX(UGeckoInstruction inst); void stX(UGeckoInstruction inst); + void lmw(UGeckoInstruction inst); + void stmw(UGeckoInstruction inst); // LoadStore floating point void lfXX(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index 919d693826..aba1493899 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -515,3 +515,114 @@ void JitArm64::stX(UGeckoInstruction inst) gpr.Unlock(WA); } } + +void JitArm64::lmw(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreOff); + FALLBACK_IF(!jo.fastmem); + + u32 a = inst.RA; + + ARM64Reg WA = gpr.GetReg(); + ARM64Reg XA = EncodeRegTo64(WA); + if (a) + { + bool add = inst.SIMM_16 >= 0; + u16 off = std::abs(inst.SIMM_16); + if (off < 4096) + { + if (add) + ADD(WA, gpr.R(a), off); + else + SUB(WA, gpr.R(a), off); + } + else + { + u16 remaining = off >> 12; + if (add) + { + ADD(WA, WA, remaining, true); + ADD(WA, gpr.R(a), off & 0xFFF); + } + else + { + SUB(WA, WA, remaining, true); + SUB(WA, gpr.R(a), off & 0xFFF); + } + } + } + else + { + MOVI2R(WA, (u32)(s32)(s16)inst.SIMM_16); + } + + u8* base = UReg_MSR(MSR).DR ? Memory::logical_base : Memory::physical_base; + MOVK(XA, ((u64)base >> 32) & 0xFFFF, SHIFT_32); + + for (int i = inst.RD; i < 32; i++) + { + gpr.BindToRegister(i, false); + ARM64Reg RX = gpr.R(i); + LDR(INDEX_UNSIGNED, RX, XA, (i - inst.RD) * 4); + REV32(RX, RX); + } + + gpr.Unlock(WA); +} + +void JitArm64::stmw(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreOff); + FALLBACK_IF(!jo.fastmem); + + u32 a = inst.RA; + + ARM64Reg WA = gpr.GetReg(); + ARM64Reg XA = EncodeRegTo64(WA); + ARM64Reg WB = gpr.GetReg(); + + if (a) + { + bool add = inst.SIMM_16 >= 0; + u16 off = std::abs(inst.SIMM_16); + if (off < 4096) + { + if (add) + ADD(WA, gpr.R(a), off); + else + SUB(WA, gpr.R(a), off); + } + else + { + u16 remaining = off >> 12; + if (add) + { + ADD(WA, WA, remaining, true); + ADD(WA, gpr.R(a), off & 0xFFF); + } + else + { + SUB(WA, WA, remaining, true); + SUB(WA, gpr.R(a), off & 0xFFF); + } + } + } + else + { + MOVI2R(WA, (u32)(s32)(s16)inst.SIMM_16); + } + + u8* base = UReg_MSR(MSR).DR ? Memory::logical_base : Memory::physical_base; + MOVK(XA, ((u64)base >> 32) & 0xFFFF, SHIFT_32); + + for (int i = inst.RD; i < 32; i++) + { + ARM64Reg RX = gpr.R(i); + REV32(WB, RX); + STR(INDEX_UNSIGNED, WB, XA, (i - inst.RD) * 4); + } + + gpr.Unlock(WA, WB); +} diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index 4b7b0d65f1..fa5ed296ff 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -79,8 +79,8 @@ static GekkoOPTemplate primarytable[] = {38, &JitArm64::stX}, // stb {39, &JitArm64::stX}, // stbu - {46, &JitArm64::FallBackToInterpreter}, // lmw - {47, &JitArm64::FallBackToInterpreter}, // stmw + {46, &JitArm64::lmw}, // lmw + {47, &JitArm64::stmw}, // stmw {48, &JitArm64::lfXX}, // lfs {49, &JitArm64::lfXX}, // lfsu