From f666df72c00518d355a70591a280f6118856bdc1 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 1 Jul 2021 13:29:25 +0200 Subject: [PATCH] JitArm64: Implement stwbrx/sthbrx --- .../PowerPC/JitArm64/JitArm64_BackPatch.cpp | 12 +++---- .../PowerPC/JitArm64/JitArm64_LoadStore.cpp | 32 ++++++++++--------- .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 4 +-- .../Core/Core/PowerPC/JitArm64/Jit_Util.cpp | 24 ++++++++++++++ Source/Core/Core/PowerPC/JitArm64/Jit_Util.h | 3 ++ 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index f2472a3eda..575e7e8f0d 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -93,17 +93,14 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR else if (flags & BackPatchInfo::FLAG_STORE) { ARM64Reg temp = ARM64Reg::W0; - if (flags & BackPatchInfo::FLAG_SIZE_32) - REV32(temp, RS); - else if (flags & BackPatchInfo::FLAG_SIZE_16) - REV16(temp, RS); + temp = ByteswapBeforeStore(this, temp, RS, flags, true); if (flags & BackPatchInfo::FLAG_SIZE_32) STR(temp, MEM_REG, addr); else if (flags & BackPatchInfo::FLAG_SIZE_16) STRH(temp, MEM_REG, addr); else - STRB(RS, MEM_REG, addr); + STRB(temp, MEM_REG, addr); } else if (flags & BackPatchInfo::FLAG_ZERO_256) { @@ -200,7 +197,10 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR } else if (flags & BackPatchInfo::FLAG_STORE) { - MOV(ARM64Reg::W0, RS); + ARM64Reg temp = ARM64Reg::W0; + temp = ByteswapBeforeStore(this, temp, RS, flags, false); + if (temp != ARM64Reg::W0) + MOV(ARM64Reg::W0, temp); if (flags & BackPatchInfo::FLAG_SIZE_32) MOVP2R(ARM64Reg::X8, &PowerPC::Write_U32); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index fbc106941f..f9599cc467 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -239,21 +239,19 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s accessSize = 8; LDR(IndexType::Unsigned, ARM64Reg::X0, PPC_REG, PPCSTATE_OFF(gather_pipe_ptr)); + + ARM64Reg temp = ARM64Reg::W1; + temp = ByteswapBeforeStore(this, temp, RS, flags, true); + if (accessSize == 32) - { - REV32(ARM64Reg::W1, RS); - STR(IndexType::Post, ARM64Reg::W1, ARM64Reg::X0, 4); - } + STR(IndexType::Post, temp, ARM64Reg::X0, 4); else if (accessSize == 16) - { - REV16(ARM64Reg::W1, RS); - STRH(IndexType::Post, ARM64Reg::W1, ARM64Reg::X0, 2); - } + STRH(IndexType::Post, temp, ARM64Reg::X0, 2); else - { - STRB(IndexType::Post, RS, ARM64Reg::X0, 1); - } + STRB(IndexType::Post, temp, ARM64Reg::X0, 1); + STR(IndexType::Unsigned, ARM64Reg::X0, PPC_REG, PPCSTATE_OFF(gather_pipe_ptr)); + js.fifoBytesSinceCheck += accessSize >> 3; } else if (jo.fastmem_arena && is_immediate && PowerPC::IsOptimizableRAMAddress(imm_addr)) @@ -261,7 +259,7 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s MOVI2R(XA, imm_addr); EmitBackpatchRoutine(flags, true, false, RS, XA, BitSet32(0), BitSet32(0)); } - else if (mmio_address && !(flags & BackPatchInfo::FLAG_REVERSE)) + else if (mmio_address) { MMIOWriteRegToAddr(Memory::mmio_mapping.get(), this, regs_in_use, fprs_in_use, RS, mmio_address, flags); @@ -370,6 +368,7 @@ void JitArm64::stX(UGeckoInstruction inst) switch (inst.OPCD) { case 31: + regOffset = b; switch (inst.SUBOP10) { case 183: // stwux @@ -377,21 +376,24 @@ void JitArm64::stX(UGeckoInstruction inst) [[fallthrough]]; case 151: // stwx flags |= BackPatchInfo::FLAG_SIZE_32; - regOffset = b; break; case 247: // stbux update = true; [[fallthrough]]; case 215: // stbx flags |= BackPatchInfo::FLAG_SIZE_8; - regOffset = b; break; case 439: // sthux update = true; [[fallthrough]]; case 407: // sthx flags |= BackPatchInfo::FLAG_SIZE_16; - regOffset = b; + break; + case 662: // stwbrx + flags |= BackPatchInfo::FLAG_REVERSE | BackPatchInfo::FLAG_SIZE_32; + break; + case 918: // sthbrx + flags |= BackPatchInfo::FLAG_REVERSE | BackPatchInfo::FLAG_SIZE_16; break; } break; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index a3b5cce8c9..f23cf7a363 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -249,8 +249,8 @@ constexpr std::array table31{{ {247, &JitArm64::stX}, // stbux // store bytereverse - {662, &JitArm64::FallBackToInterpreter}, // stwbrx - {918, &JitArm64::FallBackToInterpreter}, // sthbrx + {662, &JitArm64::stX}, // stwbrx + {918, &JitArm64::stX}, // sthbrx {661, &JitArm64::FallBackToInterpreter}, // stswx {725, &JitArm64::FallBackToInterpreter}, // stswi diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit_Util.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit_Util.cpp index 33a4aa1409..953e000288 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit_Util.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit_Util.cpp @@ -219,6 +219,28 @@ void ByteswapAfterLoad(ARM64XEmitter* emit, ARM64Reg dst_reg, ARM64Reg src_reg, emit->MOV(dst_reg, src_reg); } +ARM64Reg ByteswapBeforeStore(ARM64XEmitter* emit, ARM64Reg tmp_reg, ARM64Reg src_reg, u32 flags, + bool want_reversed) +{ + ARM64Reg dst_reg = src_reg; + + if (want_reversed == !(flags & BackPatchInfo::FLAG_REVERSE)) + { + if (flags & BackPatchInfo::FLAG_SIZE_32) + { + dst_reg = tmp_reg; + emit->REV32(dst_reg, src_reg); + } + else if (flags & BackPatchInfo::FLAG_SIZE_16) + { + dst_reg = tmp_reg; + emit->REV16(dst_reg, src_reg); + } + } + + return dst_reg; +} + void MMIOLoadToReg(MMIO::Mapping* mmio, Arm64Gen::ARM64XEmitter* emit, BitSet32 gprs_in_use, BitSet32 fprs_in_use, ARM64Reg dst_reg, u32 address, u32 flags) { @@ -247,6 +269,8 @@ void MMIOLoadToReg(MMIO::Mapping* mmio, Arm64Gen::ARM64XEmitter* emit, BitSet32 void MMIOWriteRegToAddr(MMIO::Mapping* mmio, Arm64Gen::ARM64XEmitter* emit, BitSet32 gprs_in_use, BitSet32 fprs_in_use, ARM64Reg src_reg, u32 address, u32 flags) { + src_reg = ByteswapBeforeStore(emit, ARM64Reg::W1, src_reg, flags, false); + if (flags & BackPatchInfo::FLAG_SIZE_8) { MMIOWriteCodeGenerator gen(emit, gprs_in_use, fprs_in_use, src_reg, address); diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit_Util.h b/Source/Core/Core/PowerPC/JitArm64/Jit_Util.h index dc814d1353..942a1f7dd6 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit_Util.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit_Util.h @@ -12,6 +12,9 @@ void ByteswapAfterLoad(Arm64Gen::ARM64XEmitter* emit, Arm64Gen::ARM64Reg dst_reg, Arm64Gen::ARM64Reg src_reg, u32 flags, bool is_reversed, bool is_extended); +Arm64Gen::ARM64Reg ByteswapBeforeStore(Arm64Gen::ARM64XEmitter* emit, Arm64Gen::ARM64Reg tmp_reg, + Arm64Gen::ARM64Reg src_reg, u32 flags, bool want_reversed); + void MMIOLoadToReg(MMIO::Mapping* mmio, Arm64Gen::ARM64XEmitter* emit, BitSet32 gprs_in_use, BitSet32 fprs_in_use, Arm64Gen::ARM64Reg dst_reg, u32 address, u32 flags);