zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit fd47eddc862b0a5bd90949fe21cf87a716c5464c (tree)
parent 650976b2262a9ce715ebeb1e5949b7b453b75f2f
Author: Luuk de Gram <luuk@degram.dev>
Date:   Fri, 21 Apr 2023 16:27:24 +0200

wasm: implement `@atomicLoad`

Uses the atomic instructions when cpu feature is enabled, otherwise
lowers it down to a regular load.

Diffstat:
Msrc/arch/wasm/CodeGen.zig | 28+++++++++++++++++++++++++++-
Msrc/arch/wasm/Emit.zig | 7+++++++
2 files changed, 34 insertions(+), 1 deletion(-)

diff --git 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 @@ -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);