authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-18 21:06:03+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-04-26 16:28:37+02:00
log5bbd482286930a17d37ef46396c419edee98573c
tree94635a77cf214f78e025b8a27c3eb788f062e506
parent7285eedcd26b92afb03c313a167133103a78ded5
signature Commit is signed but in an unrecognized format.

wasm: implement `cmpxchg{weak/strong}`


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

src/arch/wasm/CodeGen.zig+39-2
...@@ -1956,8 +1956,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1956,8 +1956,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1956 .is_err_ptr,1956 .is_err_ptr,
1957 .is_non_err_ptr,1957 .is_non_err_ptr,
19581958
1959 .cmpxchg_weak,
1960 .cmpxchg_strong,
1961 .fence,1959 .fence,
1962 .atomic_load,1960 .atomic_load,
1963 .atomic_store_unordered,1961 .atomic_store_unordered,
...@@ -1977,6 +1975,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1977,6 +1975,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1977 .c_va_start,1975 .c_va_start,
1978 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),1976 => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
19791977
1978 .cmpxchg_weak => func.airCmpxchg(inst),
1979 .cmpxchg_strong => func.airCmpxchg(inst),
1980
1980 .add_optimized,1981 .add_optimized,
1981 .addwrap_optimized,1982 .addwrap_optimized,
1982 .sub_optimized,1983 .sub_optimized,
...@@ -6597,3 +6598,39 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6597,3 +6598,39 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
65976598
6598 return func.finishAir(inst, result, &.{ty_op.operand});6599 return func.finishAir(inst, result, &.{ty_op.operand});
6599}6600}
6601
6602fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6603 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
6604 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
6605
6606 const ptr_ty = func.air.typeOf(extra.ptr);
6607 const ty = ptr_ty.childType();
6608 const result_ty = func.air.typeOfIndex(inst);
6609
6610 const ptr_operand = try func.resolveInst(extra.ptr);
6611 const expected_val = try func.resolveInst(extra.expected_value);
6612 const new_val = try func.resolveInst(extra.new_value);
6613
6614 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);
6615
6616 try func.lowerToStack(ptr_operand);
6617 try func.emitWValue(new_val);
6618 try func.emitWValue(ptr_val);
6619 const cmp_tmp = try func.cmp(ptr_val, expected_val, ty, .eq);
6620 const cmp_result = try cmp_tmp.toLocal(func, Type.bool);
6621 try func.emitWValue(cmp_result);
6622 try func.addTag(.select);
6623 try func.store(.stack, .stack, ty, 0);
6624 try func.addImm32(-1);
6625 try func.emitWValue(cmp_result);
6626 try func.addTag(.i32_xor);
6627 try func.addImm32(1);
6628 try func.addTag(.i32_and);
6629 const and_result = try WValue.toLocal(.stack, func, Type.bool);
6630
6631 const result_ptr = try func.allocStack(result_ty);
6632 try func.store(result_ptr, and_result, Type.bool, @intCast(u32, ty.abiSize(func.target)));
6633 try func.store(result_ptr, ptr_val, ty, 0);
6634
6635 return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.new_value, extra.expected_value });
6636}