From 91ac4ccdd8bba33dcdd8fc549d2b9bce02a4e3c8 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 6 Apr 2021 18:47:50 -0700 Subject: [PATCH] Adds LDAXP and STLXP backpatch handlers This will be used in the next commit --- .../Source/Interface/Core/ArchHelpers/Arm64.h | 6 ++++ .../Source/Interface/Core/JIT/Arm64/JIT.cpp | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64.h b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64.h index 16e5a135b..d7b1a6796 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64.h +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64.h @@ -12,6 +12,12 @@ namespace FEXCore::ArchHelpers::Arm64 { constexpr uint32_t ATOMIC_MEM_MASK = 0x3B200C00; constexpr uint32_t ATOMIC_MEM_INST = 0x38200000; + constexpr uint32_t LDAXP_MASK = 0xBF'FF'80'00; + constexpr uint32_t LDAXP_INST = 0x88'7F'80'00; + + constexpr uint32_t STLXP_MASK = 0xBF'E0'80'00; + constexpr uint32_t STLXP_INST = 0x88'20'80'00; + // Load ops are 4 bits // Acquire and release bits are independent on the instruction constexpr uint32_t ATOMIC_ADD_OP = 0b0000; diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index df010c84d..829eb8798 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -359,6 +359,34 @@ bool Arm64JITCore::HandleSIGBUS(int Signal, void *info, void *ucontext) { // Back up one instruction and have another go ArchHelpers::Context::SetPc(ucontext, ArchHelpers::Context::GetPc(ucontext) - 4); } + else if ((Instr & FEXCore::ArchHelpers::Arm64::LDAXP_MASK) == FEXCore::ArchHelpers::Arm64::LDAXP_INST) { // LDAXP + uint32_t DataReg2 = (Instr >> 10) & 0x1F; + // Convert to LDP + uint32_t LDP = 0b0010'1001'0100'0000'0000'0000'0000'0000; + LDP |= Size << 31; + LDP |= DataReg2 << 10; + LDP |= AddrReg << 5; + LDP |= DataReg; + PC[-1] = DMB; + PC[0] = LDP; + PC[1] = DMB; + // Back up one instruction and have another go + ArchHelpers::Context::SetPc(ucontext, ArchHelpers::Context::GetPc(ucontext) - 4); + } + else if ((Instr & FEXCore::ArchHelpers::Arm64::STLXP_MASK) == FEXCore::ArchHelpers::Arm64::STLXP_INST) { // STLXP + uint32_t DataReg2 = (Instr >> 10) & 0x1F; + // Convert to STP + uint32_t STP = 0b0010'1001'0000'0000'0000'0000'0000'0000; + STP |= Size << 31; + STP |= DataReg2 << 10; + STP |= AddrReg << 5; + STP |= DataReg; + PC[-1] = DMB; + PC[0] = STP; + PC[1] = DMB; + // Back up one instruction and have another go + ArchHelpers::Context::SetPc(ucontext, ArchHelpers::Context::GetPc(ucontext) - 4); + } else if ((Instr & FEXCore::ArchHelpers::Arm64::CASPAL_MASK) == FEXCore::ArchHelpers::Arm64::CASPAL_INST) { // CASPAL if (FEXCore::ArchHelpers::Arm64::HandleCASPAL(ucontext, info, Instr)) { // Skip this instruction now