authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-25 19:52:36+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-26 16:28:41+02:00
logb26a46d05b9a22b35f385948bc24059600213751
tree18fc7ad908cdd327403a85d6388e521b028e77b9
parent7c09e09457fdd04fa3c28d32ecc91ea4454c09aa
signaturelock-open Commit is signed but in an unrecognized format.

wasm: support pointers in `cmpxchg`


1 files changed, 29 insertions(+), 16 deletions(-)

src/arch/wasm/CodeGen.zig+29-16
...@@ -6631,11 +6631,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6631,11 +6631,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6631 const expected_val = try func.resolveInst(extra.expected_value);6631 const expected_val = try func.resolveInst(extra.expected_value);
6632 const new_val = try func.resolveInst(extra.new_value);6632 const new_val = try func.resolveInst(extra.new_value);
66336633
6634 const cmp_result = try func.allocLocal(Type.bool);
6635
6634 const ptr_val = if (func.useAtomicFeature()) val: {6636 const ptr_val = if (func.useAtomicFeature()) val: {
6635 const val_local = try func.allocLocal(ty);6637 const val_local = try func.allocLocal(ty);
6636 try func.emitWValue(ptr_operand);6638 try func.emitWValue(ptr_operand);
6637 try func.emitWValue(expected_val);6639 try func.lowerToStack(expected_val);
6638 try func.emitWValue(new_val);6640 try func.lowerToStack(new_val);
6639 try func.addAtomicMemArg(switch (ty.abiSize(func.target)) {6641 try func.addAtomicMemArg(switch (ty.abiSize(func.target)) {
6640 1 => .i32_atomic_rmw8_cmpxchg_u,6642 1 => .i32_atomic_rmw8_cmpxchg_u,
6641 2 => .i32_atomic_rmw16_cmpxchg_u,6643 2 => .i32_atomic_rmw16_cmpxchg_u,
...@@ -6648,32 +6650,43 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6648,32 +6650,43 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6648 });6650 });
6649 try func.addLabel(.local_tee, val_local.local.value);6651 try func.addLabel(.local_tee, val_local.local.value);
6650 _ = try func.cmp(.stack, expected_val, ty, .eq);6652 _ = try func.cmp(.stack, expected_val, ty, .eq);
6653 try func.addLabel(.local_set, cmp_result.local.value);
6651 break :val val_local;6654 break :val val_local;
6652 } else val: {6655 } else val: {
6656 if (ty.abiSize(func.target) > 8) {
6657 return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{});
6658 }
6653 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);6659 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);
66546660
6655 try func.lowerToStack(ptr_operand);6661 try func.lowerToStack(ptr_operand);
6656 try func.emitWValue(new_val);6662 try func.lowerToStack(new_val);
6657 try func.emitWValue(ptr_val);6663 try func.emitWValue(ptr_val);
6658 const cmp_tmp = try func.cmp(ptr_val, expected_val, ty, .eq);6664 _ = try func.cmp(ptr_val, expected_val, ty, .eq);
6659 const cmp_result = try cmp_tmp.toLocal(func, Type.bool);6665 try func.addLabel(.local_tee, cmp_result.local.value);
6660 try func.emitWValue(cmp_result);
6661 try func.addTag(.select);6666 try func.addTag(.select);
6662 try func.store(.stack, .stack, ty, 0);6667 try func.store(.stack, .stack, ty, 0);
6663 try func.emitWValue(cmp_result);
66646668
6665 break :val ptr_val;6669 break :val ptr_val;
6666 };6670 };
66676671
6668 try func.addImm32(-1);6672 const result_ptr = if (isByRef(result_ty, func.target)) val: {
6669 try func.addTag(.i32_xor);6673 try func.emitWValue(cmp_result);
6670 try func.addImm32(1);6674 try func.addImm32(-1);
6671 try func.addTag(.i32_and);6675 try func.addTag(.i32_xor);
6672 const and_result = try WValue.toLocal(.stack, func, Type.bool);6676 try func.addImm32(1);
66736677 try func.addTag(.i32_and);
6674 const result_ptr = try func.allocStack(result_ty);6678 const and_result = try WValue.toLocal(.stack, func, Type.bool);
6675 try func.store(result_ptr, and_result, Type.bool, @intCast(u32, ty.abiSize(func.target)));6679 const result_ptr = try func.allocStack(result_ty);
6676 try func.store(result_ptr, ptr_val, ty, 0);6680 try func.store(result_ptr, and_result, Type.bool, @intCast(u32, ty.abiSize(func.target)));
6681 try func.store(result_ptr, ptr_val, ty, 0);
6682 break :val result_ptr;
6683 } else val: {
6684 try func.addImm32(0);
6685 try func.emitWValue(ptr_val);
6686 try func.emitWValue(cmp_result);
6687 try func.addTag(.select);
6688 break :val try WValue.toLocal(.stack, func, result_ty);
6689 };
66776690
6678 return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.new_value, extra.expected_value });6691 return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.new_value, extra.expected_value });
6679}6692}