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 {
19701970 .is_err_ptr,
19711971 .is_non_err_ptr,
19721972
1973 .atomic_store_unordered,
1974 .atomic_store_monotonic,
1975 .atomic_store_release,
1976 .atomic_store_seq_cst,
19771973 .err_return_trace,
19781974 .set_err_return_trace,
19791975 .save_err_return_trace_index,
......@@ -1987,6 +1983,12 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19871983 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
19881984
19891985 .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),
19901992 .atomic_rmw => func.airAtomicRmw(inst),
19911993 .cmpxchg_weak => func.airCmpxchg(inst),
19921994 .cmpxchg_strong => func.airCmpxchg(inst),
......@@ -6634,7 +6636,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66346636 try func.emitWValue(ptr_operand);
66356637 try func.emitWValue(expected_val);
66366638 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 }, .{
66386646 .offset = ptr_operand.offset(),
66396647 .alignment = ty.abiAlignment(func.target),
66406648 });
......@@ -6880,3 +6888,32 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68806888
68816889 return func.finishAir(inst, .none, &.{});
68826890}
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}