authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-21 16:27:24+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-26 16:28:40+02:00
logfd47eddc862b0a5bd90949fe21cf87a716c5464c
treeff0553de1166f9d69cb82085be54864dfc36d907
parent650976b2262a9ce715ebeb1e5949b7b453b75f2f
signature Commit is signed but in an unrecognized format.

wasm: implement `@atomicLoad`

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

2 files changed, 34 insertions(+), 1 deletions(-)

src/arch/wasm/CodeGen.zig+27-1
...@@ -1965,7 +1965,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1965,7 +1965,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1965 .is_non_err_ptr,1965 .is_non_err_ptr,
19661966
1967 .fence,1967 .fence,
1968 .atomic_load,
1969 .atomic_store_unordered,1968 .atomic_store_unordered,
1970 .atomic_store_monotonic,1969 .atomic_store_monotonic,
1971 .atomic_store_release,1970 .atomic_store_release,
...@@ -1983,6 +1982,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1983,6 +1982,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1983 .c_va_start,1982 .c_va_start,
1984 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),1983 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
19851984
1985 .atomic_load => func.airAtomicLoad(inst),
1986 .cmpxchg_weak => func.airCmpxchg(inst),1986 .cmpxchg_weak => func.airCmpxchg(inst),
1987 .cmpxchg_strong => func.airCmpxchg(inst),1987 .cmpxchg_strong => func.airCmpxchg(inst),
19881988
...@@ -6664,3 +6664,29 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6664,3 +6664,29 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66646664
6665 return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.new_value, extra.expected_value });6665 return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.new_value, extra.expected_value });
6666}6666}
6667
6668fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6669 const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;
6670 const ptr = try func.resolveInst(atomic_load.ptr);
6671 const ty = func.air.typeOfIndex(inst);
6672
6673 if (func.useAtomicFeature()) {
6674 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {
6675 1 => .i32_atomic_load8_u,
6676 2 => .i32_atomic_load16_u,
6677 4 => .i32_atomic_load,
6678 8 => .i64_atomic_load,
6679 else => |size| return func.fail("TODO: @atomicLoad for integers with abi size {d}", .{size}),
6680 };
6681 try func.emitWValue(ptr);
6682 try func.addAtomicMemArg(tag, .{
6683 .offset = ptr.offset(),
6684 .alignment = ty.abiAlignment(func.target),
6685 });
6686 } else {
6687 _ = try func.load(ptr, ty, 0);
6688 }
6689
6690 const result = try WValue.toLocal(.stack, func, ty);
6691 return func.finishAir(inst, result, &.{atomic_load.ptr});
6692}
src/arch/wasm/Emit.zig+7
...@@ -529,6 +529,13 @@ fn emitAtomic(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -529,6 +529,13 @@ fn emitAtomic(emit: *Emit, inst: Mir.Inst.Index) !void {
529 switch (@intToEnum(std.wasm.AtomicsOpcode, opcode)) {529 switch (@intToEnum(std.wasm.AtomicsOpcode, opcode)) {
530 .i32_atomic_rmw_cmpxchg,530 .i32_atomic_rmw_cmpxchg,
531 .i64_atomic_rmw_cmpxchg,531 .i64_atomic_rmw_cmpxchg,
532 .i32_atomic_load,
533 .i64_atomic_load,
534 .i32_atomic_load8_u,
535 .i32_atomic_load16_u,
536 .i64_atomic_load8_u,
537 .i64_atomic_load16_u,
538 .i64_atomic_load32_u,
532 => {539 => {
533 const mem_arg = emit.mir.extraData(Mir.MemArg, extra_index + 1).data;540 const mem_arg = emit.mir.extraData(Mir.MemArg, extra_index + 1).data;
534 try encodeMemArg(mem_arg, writer);541 try encodeMemArg(mem_arg, writer);