From 232eeff483b90d5c70d53ea46561cf26464b71ca Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 22 Feb 2021 22:27:10 -0800 Subject: [PATCH] Implements BTC, BTR, BTS atomic variants BTS specifically is being used for threading related tasks. Which could be why our threading has been unstable. --- .../Interface/Core/OpcodeDispatcher.cpp | 62 +++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 068c63e09..b00cde528 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2487,14 +2487,24 @@ void OpDispatchBuilder::BTROp(OpcodeArgs) { // Now add the addresses together and load the memory OrderedNode *MemoryLocation = _Add(Dest, Src); - OrderedNode *Value = _LoadMemAutoTSO(GPRClass, 1, MemoryLocation, 1); - - // Now shift in to the correct bit location - Result = _Lshr(Value, BitSelect); OrderedNode *BitMask = _Lshl(_Constant(1), BitSelect); BitMask = _Not(BitMask); - Value = _And(Value, BitMask); - _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); + + if (DestIsLockedMem(Op)) { + // XXX: Technically this can optimize to an AArch64 ldclralb + // We don't current support this IR op though + Result = _AtomicFetchAnd(MemoryLocation, BitMask, 1); + // Now shift in to the correct bit location + Result = _Lshr(Result, BitSelect); + } + else { + OrderedNode *Value = _LoadMemAutoTSO(GPRClass, 1, MemoryLocation, 1); + + // Now shift in to the correct bit location + Result = _Lshr(Value, BitSelect); + Value = _And(Value, BitMask); + _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); + } } SetRFLAG(Result); } @@ -2554,13 +2564,21 @@ void OpDispatchBuilder::BTSOp(OpcodeArgs) { // Now add the addresses together and load the memory OrderedNode *MemoryLocation = _Add(Dest, Src); - OrderedNode *Value = _LoadMemAutoTSO(GPRClass, 1, MemoryLocation, 1); - - // Now shift in to the correct bit location - Result = _Lshr(Value, BitSelect); OrderedNode *BitMask = _Lshl(_Constant(1), BitSelect); - Value = _Or(Value, BitMask); - _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); + + if (DestIsLockedMem(Op)) { + Result = _AtomicFetchOr(MemoryLocation, BitMask, 1); + // Now shift in to the correct bit location + Result = _Lshr(Result, BitSelect); + } + else { + OrderedNode *Value = _LoadMemAutoTSO(GPRClass, 1, MemoryLocation, 1); + + // Now shift in to the correct bit location + Result = _Lshr(Value, BitSelect); + Value = _Or(Value, BitMask); + _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); + } } SetRFLAG(Result); } @@ -2619,13 +2637,21 @@ void OpDispatchBuilder::BTCOp(OpcodeArgs) { // Now add the addresses together and load the memory OrderedNode *MemoryLocation = _Add(Dest, Src); - OrderedNode *Value = _LoadMemAutoTSO(GPRClass, 1, MemoryLocation, 1); - - // Now shift in to the correct bit location - Result = _Lshr(Value, BitSelect); OrderedNode *BitMask = _Lshl(_Constant(1), BitSelect); - Value = _Xor(Value, BitMask); - _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); + + if (DestIsLockedMem(Op)) { + Result = _AtomicFetchXor(MemoryLocation, BitMask, 1); + // Now shift in to the correct bit location + Result = _Lshr(Result, BitSelect); + } + else { + OrderedNode *Value = _LoadMemAutoTSO(GPRClass, 1, MemoryLocation, 1); + + // Now shift in to the correct bit location + Result = _Lshr(Value, BitSelect); + Value = _Xor(Value, BitMask); + _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); + } } SetRFLAG(Result); }