diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-04-21 16:27:24 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-04-26 16:28:40 +0200 |
| commit | fd47eddc862b0a5bd90949fe21cf87a716c5464c (patch) | |
| tree | ff0553de1166f9d69cb82085be54864dfc36d907 /src | |
| parent | 650976b2262a9ce715ebeb1e5949b7b453b75f2f (diff) | |
| download | zig-fd47eddc862b0a5bd90949fe21cf87a716c5464c.tar.gz zig-fd47eddc862b0a5bd90949fe21cf87a716c5464c.zip | |
wasm: implement `@atomicLoad`
Uses the atomic instructions when cpu feature is enabled, otherwise
lowers it down to a regular load.
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 28 | ||||
| -rw-r--r-- | src/arch/wasm/Emit.zig | 7 |
2 files changed, 34 insertions, 1 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 786b3fea76..fb27f8f343 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 173a2ac672..420f0d7606 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); |
