From e90164b519c2943d83f390793c8545de46ba5fe3 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 9 May 2022 16:50:43 -0700 Subject: [PATCH] Arm64: Fixes AtomicSwap It wasn't using acquire semantics, only release semantics. This was causing the swap to load data from a stale cacheline, causing the futex system in glibc to break. This break only occured if you tried going down the RCPC codepath because of edge case memory ordering problems. This then enables the RCPC code path now since it works. --- External/FEXCore/Source/Interface/Core/HostFeatures.cpp | 6 +----- .../FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/HostFeatures.cpp b/External/FEXCore/Source/Interface/Core/HostFeatures.cpp index 3555e9c21..80c6208b4 100644 --- a/External/FEXCore/Source/Interface/Core/HostFeatures.cpp +++ b/External/FEXCore/Source/Interface/Core/HostFeatures.cpp @@ -59,11 +59,7 @@ HostFeatures::HostFeatures() { // Only supported when FEAT_AFP is supported SupportsFlushInputsToZero = Features.Has(vixl::CPUFeatures::Feature::kAFP); - - // RCPC is bugged on Snapdragon 865 - // Causes glibc cond16 test to immediately throw assert - // __pthread_mutex_cond_lock: Assertion `mutex->__data.__owner == 0' - SupportsRCPC = false; //Features.Has(vixl::CPUFeatures::Feature::kRCpc); + SupportsRCPC = Features.Has(vixl::CPUFeatures::Feature::kRCpc); // We need to get the CPU's cache line size // We expect sane targets that have correct cacheline sizes across clusters diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp index 885c84904..5bf764dab 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp @@ -509,10 +509,10 @@ DEF_OP(AtomicSwap) { if (CTX->HostFeatures.SupportsAtomics) { mov(TMP2, GetReg(Op->Value.ID())); switch (IROp->Size) { - case 1: swplb(TMP2.W(), GetReg(Node), MemOperand(MemSrc)); break; - case 2: swplh(TMP2.W(), GetReg(Node), MemOperand(MemSrc)); break; - case 4: swpl(TMP2.W(), GetReg(Node), MemOperand(MemSrc)); break; - case 8: swpl(TMP2.X(), GetReg(Node), MemOperand(MemSrc)); break; + case 1: swpalb(TMP2.W(), GetReg(Node), MemOperand(MemSrc)); break; + case 2: swpalh(TMP2.W(), GetReg(Node), MemOperand(MemSrc)); break; + case 4: swpal(TMP2.W(), GetReg(Node), MemOperand(MemSrc)); break; + case 8: swpal(TMP2.X(), GetReg(Node), MemOperand(MemSrc)); break; default: LOGMAN_MSG_A_FMT("Unhandled Atomic size: {}", IROp->Size); } }