diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 786b3fea766f0e9e232f79a62f8f31099487c4c2..fb27f8f343f0343d482d93360e06f56d69014db5 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1965,7 +1965,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { .is_non_err_ptr, .fence, - .atomic_load, .atomic_store_unordered, .atomic_store_monotonic, .atomic_store_release, @@ -1983,6 +1982,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { .c_va_start, => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), + .atomic_load => func.airAtomicLoad(inst), .cmpxchg_weak => func.airCmpxchg(inst), .cmpxchg_strong => func.airCmpxchg(inst), @@ -6664,3 +6664,29 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.new_value, extra.expected_value }); } + +fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const atomic_load = func.air.instructions.items(.data)[inst].atomic_load; + const ptr = try func.resolveInst(atomic_load.ptr); + const ty = func.air.typeOfIndex(inst); + + if (func.useAtomicFeature()) { + const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) { + 1 => .i32_atomic_load8_u, + 2 => .i32_atomic_load16_u, + 4 => .i32_atomic_load, + 8 => .i64_atomic_load, + else => |size| return func.fail("TODO: @atomicLoad for integers with abi size {d}", .{size}), + }; + try func.emitWValue(ptr); + try func.addAtomicMemArg(tag, .{ + .offset = ptr.offset(), + .alignment = ty.abiAlignment(func.target), + }); + } else { + _ = try func.load(ptr, ty, 0); + } + + const result = try WValue.toLocal(.stack, func, ty); + return func.finishAir(inst, result, &.{atomic_load.ptr}); +} diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 173a2ac672cd689c0dff62701f42f8c624d64a0f..420f0d7606f35920bee7a11a749922b93e9447a0 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -529,6 +529,13 @@ fn emitAtomic(emit: *Emit, inst: Mir.Inst.Index) !void { switch (@intToEnum(std.wasm.AtomicsOpcode, opcode)) { .i32_atomic_rmw_cmpxchg, .i64_atomic_rmw_cmpxchg, + .i32_atomic_load, + .i64_atomic_load, + .i32_atomic_load8_u, + .i32_atomic_load16_u, + .i64_atomic_load8_u, + .i64_atomic_load16_u, + .i64_atomic_load32_u, => { const mem_arg = emit.mir.extraData(Mir.MemArg, extra_index + 1).data; try encodeMemArg(mem_arg, writer);