diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index ec57ddca14ac..e7ce3cca52f9 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -3666,11 +3666,13 @@ class MacroAssembler : public MacroAssemblerSpecific { void compareExchange64(const Synchronization& sync, const Address& mem, Register64 expected, Register64 replacement, - Register64 output) DEFINED_ON(arm, arm64, x64, x86); + Register64 output) + DEFINED_ON(arm, arm64, x64, x86, mips64); void compareExchange64(const Synchronization& sync, const BaseIndex& mem, Register64 expected, Register64 replacement, - Register64 output) DEFINED_ON(arm, arm64, x64, x86); + Register64 output) + DEFINED_ON(arm, arm64, x64, x86, mips64); // Exchange with memory. Return the value initially in memory. // MIPS: `valueTemp`, `offsetTemp` and `maskTemp` must be defined for 8-bit @@ -3700,11 +3702,11 @@ class MacroAssembler : public MacroAssemblerSpecific { void atomicExchange64(const Synchronization& sync, const Address& mem, Register64 value, Register64 output) - DEFINED_ON(arm, arm64, x64, x86); + DEFINED_ON(arm, arm64, x64, x86, mips64); void atomicExchange64(const Synchronization& sync, const BaseIndex& mem, Register64 value, Register64 output) - DEFINED_ON(arm, arm64, x64, x86); + DEFINED_ON(arm, arm64, x64, x86, mips64); // Read-modify-write with memory. Return the value in memory before the // operation. @@ -3759,7 +3761,7 @@ class MacroAssembler : public MacroAssemblerSpecific { void atomicFetchOp64(const Synchronization& sync, AtomicOp op, Register64 value, const Address& mem, Register64 temp, - Register64 output) DEFINED_ON(arm, arm64, x64); + Register64 output) DEFINED_ON(arm, arm64, x64, mips64); void atomicFetchOp64(const Synchronization& sync, AtomicOp op, const Address& value, const Address& mem, @@ -3767,7 +3769,7 @@ class MacroAssembler : public MacroAssemblerSpecific { void atomicFetchOp64(const Synchronization& sync, AtomicOp op, Register64 value, const BaseIndex& mem, Register64 temp, - Register64 output) DEFINED_ON(arm, arm64, x64); + Register64 output) DEFINED_ON(arm, arm64, x64, mips64); void atomicFetchOp64(const Synchronization& sync, AtomicOp op, const Address& value, const BaseIndex& mem, @@ -3785,14 +3787,14 @@ class MacroAssembler : public MacroAssemblerSpecific { void atomicEffectOp64(const Synchronization& sync, AtomicOp op, Register64 value, const Address& mem, Register64 temp) - DEFINED_ON(arm, arm64); + DEFINED_ON(arm, arm64, mips64); void atomicEffectOp64(const Synchronization& sync, AtomicOp op, Register64 value, const BaseIndex& mem) DEFINED_ON(x64); void atomicEffectOp64(const Synchronization& sync, AtomicOp op, Register64 value, const BaseIndex& mem, Register64 temp) - DEFINED_ON(arm, arm64); + DEFINED_ON(arm, arm64, mips64); // 64-bit atomic load. On 64-bit systems, use regular load with // Synchronization::Load, not this method. diff --git a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp index 8e48c2c0e389..5c55bf0742f3 100644 --- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp +++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp @@ -2168,30 +2168,113 @@ void CodeGenerator::visitAtomicExchangeTypedArrayElement( } } -void CodeGenerator::visitAtomicLoad64(LAtomicLoad64* lir) { MOZ_CRASH("NYI"); } - -void CodeGenerator::visitAtomicStore64(LAtomicStore64* lir) { - MOZ_CRASH("NYI"); -} - void CodeGenerator::visitCompareExchangeTypedArrayElement64( LCompareExchangeTypedArrayElement64* lir) { - MOZ_CRASH("NYI"); + Register elements = ToRegister(lir->elements()); + Register oldval = ToRegister(lir->oldval()); + Register newval = ToRegister(lir->newval()); + Register64 temp1 = ToRegister64(lir->temp1()); + Register64 temp2 = ToRegister64(lir->temp2()); + Register out = ToRegister(lir->output()); + Register64 tempOut(out); + + Scalar::Type arrayType = lir->mir()->arrayType(); + + masm.loadBigInt64(oldval, temp1); + masm.loadBigInt64(newval, tempOut); + + if (lir->index()->isConstant()) { + Address dest = ToAddress(elements, lir->index(), arrayType); + masm.compareExchange64(Synchronization::Full(), dest, temp1, tempOut, + temp2); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), + ScaleFromScalarType(arrayType)); + masm.compareExchange64(Synchronization::Full(), dest, temp1, tempOut, + temp2); + } + + emitCreateBigInt(lir, arrayType, temp2, out, temp1.scratchReg()); } void CodeGenerator::visitAtomicExchangeTypedArrayElement64( LAtomicExchangeTypedArrayElement64* lir) { - MOZ_CRASH("NYI"); + Register elements = ToRegister(lir->elements()); + Register value = ToRegister(lir->value()); + Register64 temp1 = ToRegister64(lir->temp1()); + Register64 temp2 = Register64(ToRegister(lir->temp2())); + Register out = ToRegister(lir->output()); + + Scalar::Type arrayType = lir->mir()->arrayType(); + + masm.loadBigInt64(value, temp1); + + if (lir->index()->isConstant()) { + Address dest = ToAddress(elements, lir->index(), arrayType); + masm.atomicExchange64(Synchronization::Full(), dest, temp1, temp2); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), + ScaleFromScalarType(arrayType)); + masm.atomicExchange64(Synchronization::Full(), dest, temp1, temp2); + } + + emitCreateBigInt(lir, arrayType, temp2, out, temp1.scratchReg()); } void CodeGenerator::visitAtomicTypedArrayElementBinop64( LAtomicTypedArrayElementBinop64* lir) { - MOZ_CRASH("NYI"); + MOZ_ASSERT(lir->mir()->hasUses()); + + Register elements = ToRegister(lir->elements()); + Register value = ToRegister(lir->value()); + Register64 temp1 = ToRegister64(lir->temp1()); + Register64 temp2 = ToRegister64(lir->temp2()); + Register out = ToRegister(lir->output()); + Register64 tempOut = Register64(out); + + Scalar::Type arrayType = lir->mir()->arrayType(); + AtomicOp atomicOp = lir->mir()->operation(); + + masm.loadBigInt64(value, temp1); + + if (lir->index()->isConstant()) { + Address dest = ToAddress(elements, lir->index(), arrayType); + masm.atomicFetchOp64(Synchronization::Full(), atomicOp, temp1, dest, + tempOut, temp2); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), + ScaleFromScalarType(arrayType)); + masm.atomicFetchOp64(Synchronization::Full(), atomicOp, temp1, dest, + tempOut, temp2); + } + + emitCreateBigInt(lir, arrayType, temp2, out, temp1.scratchReg()); } void CodeGenerator::visitAtomicTypedArrayElementBinopForEffect64( LAtomicTypedArrayElementBinopForEffect64* lir) { - MOZ_CRASH("NYI"); + MOZ_ASSERT(!lir->mir()->hasUses()); + + Register elements = ToRegister(lir->elements()); + Register value = ToRegister(lir->value()); + Register64 temp1 = ToRegister64(lir->temp1()); + Register64 temp2 = ToRegister64(lir->temp2()); + + Scalar::Type arrayType = lir->mir()->arrayType(); + AtomicOp atomicOp = lir->mir()->operation(); + + masm.loadBigInt64(value, temp1); + + if (lir->index()->isConstant()) { + Address dest = ToAddress(elements, lir->index(), arrayType); + masm.atomicEffectOp64(Synchronization::Full(), atomicOp, temp1, dest, + temp2); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), + ScaleFromScalarType(arrayType)); + masm.atomicEffectOp64(Synchronization::Full(), atomicOp, temp1, dest, + temp2); + } } void CodeGenerator::visitWasmCompareExchangeI64(LWasmCompareExchangeI64* lir) { diff --git a/js/src/jit/mips-shared/Lowering-mips-shared.cpp b/js/src/jit/mips-shared/Lowering-mips-shared.cpp index 9d11b4349b16..e9ce0a4b0f77 100644 --- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp +++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp @@ -602,16 +602,23 @@ void LIRGenerator::visitCompareExchangeTypedArrayElement( const LAllocation index = useRegisterOrIndexConstant(ins->index(), ins->arrayType()); + const LAllocation newval = useRegister(ins->newval()); + const LAllocation oldval = useRegister(ins->oldval()); + if (Scalar::isBigIntType(ins->arrayType())) { - MOZ_CRASH("NYI"); + LInt64Definition temp1 = tempInt64(); + LInt64Definition temp2 = tempInt64(); + + auto* lir = new (alloc()) LCompareExchangeTypedArrayElement64( + elements, index, oldval, newval, temp1, temp2); + define(lir, ins); + assignSafepoint(lir, ins); + return; } // If the target is a floating register then we need a temp at the // CodeGenerator level for creating the result. - const LAllocation newval = useRegister(ins->newval()); - const LAllocation oldval = useRegister(ins->oldval()); - LDefinition outTemp = LDefinition::BogusTemp(); LDefinition valueTemp = LDefinition::BogusTemp(); LDefinition offsetTemp = LDefinition::BogusTemp(); @@ -637,8 +644,6 @@ void LIRGenerator::visitCompareExchangeTypedArrayElement( void LIRGenerator::visitAtomicExchangeTypedArrayElement( MAtomicExchangeTypedArrayElement* ins) { - MOZ_ASSERT(ins->arrayType() <= Scalar::Uint32); - MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); MOZ_ASSERT(ins->index()->type() == MIRType::IntPtr); @@ -646,14 +651,24 @@ void LIRGenerator::visitAtomicExchangeTypedArrayElement( const LAllocation index = useRegisterOrIndexConstant(ins->index(), ins->arrayType()); + const LAllocation value = useRegister(ins->value()); + if (Scalar::isBigIntType(ins->arrayType())) { - MOZ_CRASH("NYI"); + LInt64Definition temp1 = tempInt64(); + LDefinition temp2 = temp(); + + auto* lir = new (alloc()) LAtomicExchangeTypedArrayElement64( + elements, index, value, temp1, temp2); + define(lir, ins); + assignSafepoint(lir, ins); + return; } // If the target is a floating register then we need a temp at the // CodeGenerator level for creating the result. - const LAllocation value = useRegister(ins->value()); + MOZ_ASSERT(ins->arrayType() <= Scalar::Uint32); + LDefinition outTemp = LDefinition::BogusTemp(); LDefinition valueTemp = LDefinition::BogusTemp(); LDefinition offsetTemp = LDefinition::BogusTemp(); @@ -677,14 +692,6 @@ void LIRGenerator::visitAtomicExchangeTypedArrayElement( define(lir, ins); } -void LIRGeneratorMIPSShared::lowerAtomicLoad64(MLoadUnboxedScalar* ins) { - MOZ_CRASH("NYI"); -} - -void LIRGeneratorMIPSShared::lowerAtomicStore64(MStoreUnboxedScalar* ins) { - MOZ_CRASH("NYI"); -} - void LIRGenerator::visitWasmCompareExchangeHeap(MWasmCompareExchangeHeap* ins) { MOZ_ASSERT(ins->base()->type() == MIRType::Int32); @@ -794,7 +801,27 @@ void LIRGenerator::visitAtomicTypedArrayElementBinop( const LAllocation value = useRegister(ins->value()); if (Scalar::isBigIntType(ins->arrayType())) { - MOZ_CRASH("NYI"); + LInt64Definition temp1 = tempInt64(); + LInt64Definition temp2 = tempInt64(); + + // Case 1: the result of the operation is not used. + // + // We can omit allocating the result BigInt. + + if (ins->isForEffect()) { + auto* lir = new (alloc()) LAtomicTypedArrayElementBinopForEffect64( + elements, index, value, temp1, temp2); + add(lir, ins); + return; + } + + // Case 2: the result of the operation is used. + + auto* lir = new (alloc()) + LAtomicTypedArrayElementBinop64(elements, index, value, temp1, temp2); + define(lir, ins); + assignSafepoint(lir, ins); + return; } LDefinition valueTemp = LDefinition::BogusTemp(); diff --git a/js/src/jit/mips-shared/Lowering-mips-shared.h b/js/src/jit/mips-shared/Lowering-mips-shared.h index f99aaa95dd33..ba6dde774fa1 100644 --- a/js/src/jit/mips-shared/Lowering-mips-shared.h +++ b/js/src/jit/mips-shared/Lowering-mips-shared.h @@ -69,9 +69,6 @@ class LIRGeneratorMIPSShared : public LIRGeneratorShared { void lowerBigIntLsh(MBigIntLsh* ins); void lowerBigIntRsh(MBigIntRsh* ins); - void lowerAtomicLoad64(MLoadUnboxedScalar* ins); - void lowerAtomicStore64(MStoreUnboxedScalar* ins); - LTableSwitch* newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy, MTableSwitch* ins); diff --git a/js/src/jit/mips64/CodeGenerator-mips64.cpp b/js/src/jit/mips64/CodeGenerator-mips64.cpp index ff09b39598a5..6b53e2bd27c0 100644 --- a/js/src/jit/mips64/CodeGenerator-mips64.cpp +++ b/js/src/jit/mips64/CodeGenerator-mips64.cpp @@ -514,3 +514,48 @@ void CodeGenerator::visitTestI64AndBranch(LTestI64AndBranch* lir) { emitBranch(input.reg, Imm32(0), Assembler::NonZero, ifTrue, ifFalse); } + +void CodeGenerator::visitAtomicLoad64(LAtomicLoad64* lir) { + Register elements = ToRegister(lir->elements()); + Register temp = ToRegister(lir->temp()); + Register64 temp64 = ToRegister64(lir->temp64()); + Register out = ToRegister(lir->output()); + const MLoadUnboxedScalar* mir = lir->mir(); + + Scalar::Type storageType = mir->storageType(); + + auto sync = Synchronization::Load(); + masm.memoryBarrierBefore(sync); + if (lir->index()->isConstant()) { + Address source = + ToAddress(elements, lir->index(), storageType, mir->offsetAdjustment()); + masm.load64(source, temp64); + } else { + BaseIndex source(elements, ToRegister(lir->index()), + ScaleFromScalarType(storageType), mir->offsetAdjustment()); + masm.load64(source, temp64); + } + masm.memoryBarrierAfter(sync); + emitCreateBigInt(lir, storageType, temp64, out, temp); +} + +void CodeGenerator::visitAtomicStore64(LAtomicStore64* lir) { + Register elements = ToRegister(lir->elements()); + Register value = ToRegister(lir->value()); + Register64 temp1 = ToRegister64(lir->temp1()); + + Scalar::Type writeType = lir->mir()->writeType(); + + masm.loadBigInt64(value, temp1); + auto sync = Synchronization::Store(); + masm.memoryBarrierBefore(sync); + if (lir->index()->isConstant()) { + Address dest = ToAddress(elements, lir->index(), writeType); + masm.store64(temp1, dest); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), + ScaleFromScalarType(writeType)); + masm.store64(temp1, dest); + } + masm.memoryBarrierAfter(sync); +} diff --git a/js/src/jit/mips64/Lowering-mips64.cpp b/js/src/jit/mips64/Lowering-mips64.cpp index 3c557e8ad1df..e9cda9299c40 100644 --- a/js/src/jit/mips64/Lowering-mips64.cpp +++ b/js/src/jit/mips64/Lowering-mips64.cpp @@ -88,6 +88,25 @@ void LIRGeneratorMIPS64::lowerBigIntMod(MBigIntMod* ins) { assignSafepoint(lir, ins); } +void LIRGeneratorMIPS64::lowerAtomicLoad64(MLoadUnboxedScalar* ins) { + const LUse elements = useRegister(ins->elements()); + const LAllocation index = + useRegisterOrIndexConstant(ins->index(), ins->storageType()); + + auto* lir = new (alloc()) LAtomicLoad64(elements, index, temp(), tempInt64()); + define(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGeneratorMIPS64::lowerAtomicStore64(MStoreUnboxedScalar* ins) { + LUse elements = useRegister(ins->elements()); + LAllocation index = + useRegisterOrIndexConstant(ins->index(), ins->writeType()); + LAllocation value = useRegister(ins->value()); + + add(new (alloc()) LAtomicStore64(elements, index, value, tempInt64()), ins); +} + void LIRGenerator::visitBox(MBox* box) { MDefinition* opd = box->getOperand(0); diff --git a/js/src/jit/mips64/Lowering-mips64.h b/js/src/jit/mips64/Lowering-mips64.h index 67a444f5e253..b8543de6d2d5 100644 --- a/js/src/jit/mips64/Lowering-mips64.h +++ b/js/src/jit/mips64/Lowering-mips64.h @@ -43,6 +43,9 @@ class LIRGeneratorMIPS64 : public LIRGeneratorMIPSShared { void lowerBigIntDiv(MBigIntDiv* ins); void lowerBigIntMod(MBigIntMod* ins); + + void lowerAtomicLoad64(MLoadUnboxedScalar* ins); + void lowerAtomicStore64(MStoreUnboxedScalar* ins); }; typedef LIRGeneratorMIPS64 LIRGeneratorSpecific; diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 92a55afa79a4..2102b06bb03d 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -2561,20 +2561,24 @@ void MacroAssemblerMIPS64Compat::wasmStoreI64Impl( } template -static void WasmCompareExchange64(MacroAssembler& masm, - const wasm::MemoryAccessDesc& access, - const T& mem, Register64 expect, - Register64 replace, Register64 output) { +static void CompareExchange64(MacroAssembler& masm, + const wasm::MemoryAccessDesc* access, + const Synchronization& sync, const T& mem, + Register64 expect, Register64 replace, + Register64 output) { + MOZ_ASSERT(oldval != output && newval != output); masm.computeEffectiveAddress(mem, SecondScratchReg); Label tryAgain; Label exit; - masm.memoryBarrierBefore(access.sync()); + masm.memoryBarrierBefore(sync); masm.bind(&tryAgain); - masm.append(access, masm.size()); + if (access) { + masm.append(*access, masm.size()); + } masm.as_lld(output.reg, SecondScratchReg, 0); masm.ma_b(output.reg, expect.reg, &exit, Assembler::NotEqual, ShortJump); @@ -2583,7 +2587,7 @@ static void WasmCompareExchange64(MacroAssembler& masm, masm.ma_b(ScratchRegister, ScratchRegister, &tryAgain, Assembler::Zero, ShortJump); - masm.memoryBarrierAfter(access.sync()); + masm.memoryBarrierAfter(sync); masm.bind(&exit); } @@ -2593,7 +2597,8 @@ void MacroAssembler::wasmCompareExchange64(const wasm::MemoryAccessDesc& access, Register64 expect, Register64 replace, Register64 output) { - WasmCompareExchange64(*this, access, mem, expect, replace, output); + CompareExchange64(*this, &access, access.sync(), mem, expect, replace, + output); } void MacroAssembler::wasmCompareExchange64(const wasm::MemoryAccessDesc& access, @@ -2601,58 +2606,100 @@ void MacroAssembler::wasmCompareExchange64(const wasm::MemoryAccessDesc& access, Register64 expect, Register64 replace, Register64 output) { - WasmCompareExchange64(*this, access, mem, expect, replace, output); + CompareExchange64(*this, &access, access.sync(), mem, expect, replace, + output); +} + +void MacroAssembler::compareExchange64(const Synchronization& sync, + const Address& mem, Register64 expect, + Register64 replace, Register64 output) { + CompareExchange64(*this, nullptr, sync, mem, expect, replace, output); +} + +void MacroAssembler::compareExchange64(const Synchronization& sync, + const BaseIndex& mem, Register64 expect, + Register64 replace, Register64 output) { + CompareExchange64(*this, nullptr, sync, mem, expect, replace, output); } template static void AtomicExchange64(MacroAssembler& masm, - const wasm::MemoryAccessDesc& access, const T& mem, - Register64 src, Register64 output) { + const wasm::MemoryAccessDesc* access, + const Synchronization& sync, const T& mem, + Register64 value, Register64 output) { + MOZ_ASSERT(value != output); masm.computeEffectiveAddress(mem, SecondScratchReg); Label tryAgain; - masm.memoryBarrierBefore(access.sync()); + masm.memoryBarrierBefore(sync); masm.bind(&tryAgain); - masm.append(access, masm.size()); - masm.as_lld(output.reg, SecondScratchReg, 0); + if (access) { + masm.append(*access, masm.size()); + } - masm.movePtr(src.reg, ScratchRegister); + masm.as_lld(output.reg, SecondScratchReg, 0); + masm.movePtr(value.reg, ScratchRegister); masm.as_scd(ScratchRegister, SecondScratchReg, 0); masm.ma_b(ScratchRegister, ScratchRegister, &tryAgain, Assembler::Zero, ShortJump); - masm.memoryBarrierAfter(access.sync()); + masm.memoryBarrierAfter(sync); +} + +template +static void WasmAtomicExchange64(MacroAssembler& masm, + const wasm::MemoryAccessDesc& access, + const T& mem, Register64 value, + Register64 output) { + AtomicExchange64(masm, &access, access.sync(), mem, value, output); } void MacroAssembler::wasmAtomicExchange64(const wasm::MemoryAccessDesc& access, const Address& mem, Register64 src, Register64 output) { - AtomicExchange64(*this, access, mem, src, output); + WasmAtomicExchange64(*this, access, mem, src, output); } void MacroAssembler::wasmAtomicExchange64(const wasm::MemoryAccessDesc& access, const BaseIndex& mem, Register64 src, Register64 output) { - AtomicExchange64(*this, access, mem, src, output); + WasmAtomicExchange64(*this, access, mem, src, output); +} + +void MacroAssembler::atomicExchange64(const Synchronization& sync, + const Address& mem, Register64 value, + Register64 output) { + AtomicExchange64(*this, nullptr, sync, mem, value, output); +} + +void MacroAssembler::atomicExchange64(const Synchronization& sync, + const BaseIndex& mem, Register64 value, + Register64 output) { + AtomicExchange64(*this, nullptr, sync, mem, value, output); } template static void AtomicFetchOp64(MacroAssembler& masm, - const wasm::MemoryAccessDesc& access, AtomicOp op, + const wasm::MemoryAccessDesc* access, + const Synchronization& sync, AtomicOp op, Register64 value, const T& mem, Register64 temp, Register64 output) { + MOZ_ASSERT(value != output); + MOZ_ASSERT(value != temp); masm.computeEffectiveAddress(mem, SecondScratchReg); Label tryAgain; - masm.memoryBarrierBefore(access.sync()); + masm.memoryBarrierBefore(sync); masm.bind(&tryAgain); + if (access) { + masm.append(*access, masm.size()); + } - masm.append(access, masm.size()); masm.as_lld(output.reg, SecondScratchReg, 0); switch (op) { @@ -2678,21 +2725,45 @@ static void AtomicFetchOp64(MacroAssembler& masm, masm.as_scd(temp.reg, SecondScratchReg, 0); masm.ma_b(temp.reg, temp.reg, &tryAgain, Assembler::Zero, ShortJump); - masm.memoryBarrierAfter(access.sync()); + masm.memoryBarrierAfter(sync); } void MacroAssembler::wasmAtomicFetchOp64(const wasm::MemoryAccessDesc& access, AtomicOp op, Register64 value, const Address& mem, Register64 temp, Register64 output) { - AtomicFetchOp64(*this, access, op, value, mem, temp, output); + AtomicFetchOp64(*this, &access, access.sync(), op, value, mem, temp, output); } void MacroAssembler::wasmAtomicFetchOp64(const wasm::MemoryAccessDesc& access, AtomicOp op, Register64 value, const BaseIndex& mem, Register64 temp, Register64 output) { - AtomicFetchOp64(*this, access, op, value, mem, temp, output); + AtomicFetchOp64(*this, &access, access.sync(), op, value, mem, temp, output); +} + +void MacroAssembler::atomicFetchOp64(const Synchronization& sync, AtomicOp op, + Register64 value, const Address& mem, + Register64 temp, Register64 output) { + AtomicFetchOp64(*this, nullptr, sync, op, value, mem, temp, output); +} + +void MacroAssembler::atomicFetchOp64(const Synchronization& sync, AtomicOp op, + Register64 value, const BaseIndex& mem, + Register64 temp, Register64 output) { + AtomicFetchOp64(*this, nullptr, sync, op, value, mem, temp, output); +} + +void MacroAssembler::atomicEffectOp64(const Synchronization& sync, AtomicOp op, + Register64 value, const Address& mem, + Register64 temp) { + AtomicFetchOp64(*this, nullptr, sync, op, value, mem, temp, temp); +} + +void MacroAssembler::atomicEffectOp64(const Synchronization& sync, AtomicOp op, + Register64 value, const BaseIndex& mem, + Register64 temp) { + AtomicFetchOp64(*this, nullptr, sync, op, value, mem, temp, temp); } // ========================================================================