diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp index ed6cf4d1f..8197b9900 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp @@ -877,6 +877,56 @@ DEF_OP(AtomicFetchXor) { } } +DEF_OP(AtomicFetchNeg) { + auto Op = IROp->C(); + auto MemSrc = GetReg(Op->Header.Args[0].ID()); + + // TMP2-TMP3 + switch (Op->Size) { + case 1: { + aarch64::Label LoopTop; + bind(&LoopTop); + ldaxrb(TMP2.W(), MemOperand(MemSrc)); + neg(TMP3.W(), TMP2.W()); + stlxrb(TMP4.W(), TMP3.W(), MemOperand(MemSrc)); + cbnz(TMP4.W(), &LoopTop); + mov(GetReg(Node), TMP2.W()); + break; + } + case 2: { + aarch64::Label LoopTop; + bind(&LoopTop); + ldaxrh(TMP2.W(), MemOperand(MemSrc)); + neg(TMP3.W(), TMP2.W()); + stlxrh(TMP4.W(), TMP3.W(), MemOperand(MemSrc)); + cbnz(TMP4.W(), &LoopTop); + mov(GetReg(Node), TMP2.W()); + break; + } + case 4: { + aarch64::Label LoopTop; + bind(&LoopTop); + ldaxr(TMP2.W(), MemOperand(MemSrc)); + neg(TMP3.W(), TMP2.W()); + stlxr(TMP4.W(), TMP3.W(), MemOperand(MemSrc)); + cbnz(TMP4.W(), &LoopTop); + mov(GetReg(Node), TMP2.W()); + break; + } + case 8: { + aarch64::Label LoopTop; + bind(&LoopTop); + ldaxr(TMP2, MemOperand(MemSrc)); + neg(TMP3, TMP2); + stlxr(TMP4, TMP3, MemOperand(MemSrc)); + cbnz(TMP4, &LoopTop); + mov(GetReg(Node), TMP2); + break; + } + default: LOGMAN_MSG_A("Unhandled Atomic size: %d", Op->Size); + } +} + #undef DEF_OP void Arm64JITCore::RegisterAtomicHandlers() { #define REGISTER_OP(op, x) OpHandlers[FEXCore::IR::IROps::OP_##op] = &Arm64JITCore::Op_##x @@ -893,6 +943,7 @@ void Arm64JITCore::RegisterAtomicHandlers() { REGISTER_OP(ATOMICFETCHAND, AtomicFetchAnd); REGISTER_OP(ATOMICFETCHOR, AtomicFetchOr); REGISTER_OP(ATOMICFETCHXOR, AtomicFetchXor); + REGISTER_OP(ATOMICFETCHNEG, AtomicFetchNeg); #undef REGISTER_OP } } diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index ae48558e0..002a7bc23 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -257,6 +257,7 @@ private: DEF_OP(AtomicFetchAnd); DEF_OP(AtomicFetchOr); DEF_OP(AtomicFetchXor); + DEF_OP(AtomicFetchNeg); ///< Branch ops DEF_OP(GuestCallDirect);