authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-24 19:45:06+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-26 16:28:41+02:00
log7c09e09457fdd04fa3c28d32ecc91ea4454c09aa
tree357a212c84ead7d7b100602470a8c88bc29b1c8b
parent0e3303ccd9985f4336ccde779b2f1b90f130d7a2
signaturelock-open Commit is signed but in an unrecognized format.

wasm: implement atomic stores


1 files changed, 42 insertions(+), 5 deletions(-)

src/arch/wasm/CodeGen.zig+42-5
...@@ -1970,10 +1970,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1970,10 +1970,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1970 .is_err_ptr,1970 .is_err_ptr,
1971 .is_non_err_ptr,1971 .is_non_err_ptr,
19721972
1973 .atomic_store_unordered,
1974 .atomic_store_monotonic,
1975 .atomic_store_release,
1976 .atomic_store_seq_cst,
1977 .err_return_trace,1973 .err_return_trace,
1978 .set_err_return_trace,1974 .set_err_return_trace,
1979 .save_err_return_trace_index,1975 .save_err_return_trace_index,
...@@ -1987,6 +1983,12 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1987,6 +1983,12 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1987 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),1983 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
19881984
1989 .atomic_load => func.airAtomicLoad(inst),1985 .atomic_load => func.airAtomicLoad(inst),
1986 .atomic_store_unordered,
1987 .atomic_store_monotonic,
1988 .atomic_store_release,
1989 .atomic_store_seq_cst,
1990 // in WebAssembly, all atomic instructions are sequentially ordered.
1991 => func.airAtomicStore(inst),
1990 .atomic_rmw => func.airAtomicRmw(inst),1992 .atomic_rmw => func.airAtomicRmw(inst),
1991 .cmpxchg_weak => func.airCmpxchg(inst),1993 .cmpxchg_weak => func.airCmpxchg(inst),
1992 .cmpxchg_strong => func.airCmpxchg(inst),1994 .cmpxchg_strong => func.airCmpxchg(inst),
...@@ -6634,7 +6636,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6634,7 +6636,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6634 try func.emitWValue(ptr_operand);6636 try func.emitWValue(ptr_operand);
6635 try func.emitWValue(expected_val);6637 try func.emitWValue(expected_val);
6636 try func.emitWValue(new_val);6638 try func.emitWValue(new_val);
6637 try func.addAtomicMemArg(.i32_atomic_rmw_cmpxchg, .{6639 try func.addAtomicMemArg(switch (ty.abiSize(func.target)) {
6640 1 => .i32_atomic_rmw8_cmpxchg_u,
6641 2 => .i32_atomic_rmw16_cmpxchg_u,
6642 4 => .i32_atomic_rmw_cmpxchg,
6643 8 => .i32_atomic_rmw_cmpxchg,
6644 else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}),
6645 }, .{
6638 .offset = ptr_operand.offset(),6646 .offset = ptr_operand.offset(),
6639 .alignment = ty.abiAlignment(func.target),6647 .alignment = ty.abiAlignment(func.target),
6640 });6648 });
...@@ -6880,3 +6888,32 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6880,3 +6888,32 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68806888
6881 return func.finishAir(inst, .none, &.{});6889 return func.finishAir(inst, .none, &.{});
6882}6890}
6891
6892fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6893 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
6894
6895 const ptr = try func.resolveInst(bin_op.lhs);
6896 const operand = try func.resolveInst(bin_op.rhs);
6897 const ptr_ty = func.air.typeOf(bin_op.lhs);
6898 const ty = ptr_ty.childType();
6899
6900 if (func.useAtomicFeature()) {
6901 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {
6902 1 => .i32_atomic_store8,
6903 2 => .i32_atomic_store16,
6904 4 => .i32_atomic_store,
6905 8 => .i64_atomic_store,
6906 else => |size| return func.fail("TODO: @atomicLoad for types with abi size {d}", .{size}),
6907 };
6908 try func.emitWValue(ptr);
6909 try func.lowerToStack(operand);
6910 try func.addAtomicMemArg(tag, .{
6911 .offset = ptr.offset(),
6912 .alignment = ty.abiAlignment(func.target),
6913 });
6914 } else {
6915 try func.store(ptr, operand, ty, 0);
6916 }
6917
6918 return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
6919}