atomics A.1a: RMW ops + recognizer + methods, emit bails (lock)
fetch_add/sub/and/or/xor/min/max wired end-to-end except LLVM emission (bails
loudly; A.1b makes it real). New IR op atomic_rmw + RmwKind (no nand) +
AtomicRmw{ptr, operand, val_ty, ordering, kind}. print arm; comptime_vm arm
implements real single-thread RMW (load/compute/store/return-old, signed|unsigned
min/max from val_ty). Recognizer extended (rmwKindFromName) — RMW restricted to
integer T (float fadd / pointer RMW out of scope, rejected loudly); all orderings
valid for RMW. Methods fetch_* on Atomic($T) with comptime $o: Ordering.
examples/1701 locked to the bail. Suite green (716/0).
This commit is contained in:
@@ -684,6 +684,33 @@ pub const Vm = struct {
|
||||
try self.writeField(table, frame.get(a.ptr.index()), vty, frame.get(a.val.index()));
|
||||
return .{ .value = 0 };
|
||||
},
|
||||
// RMW at comptime (single-thread): load old, compute new, store new,
|
||||
// return old — the ordering is a no-op. min/max pick signed vs
|
||||
// unsigned compare from the value type.
|
||||
.atomic_rmw => |a| {
|
||||
const table = try self.requireTable();
|
||||
const vty = if (a.val_ty != .void) a.val_ty else ins.ty;
|
||||
const old = try self.readField(table, frame.get(a.ptr.index()), ins.ty);
|
||||
const operand = frame.get(a.operand.index());
|
||||
const new_val: Reg = switch (a.kind) {
|
||||
.add => old +% operand,
|
||||
.sub => old -% operand,
|
||||
.@"and" => old & operand,
|
||||
.@"or" => old | operand,
|
||||
.xor => old ^ operand,
|
||||
.min, .max => blk: {
|
||||
const want_max = a.kind == .max;
|
||||
if (table.isUnsignedInt(vty)) {
|
||||
const uo: u64 = @bitCast(old);
|
||||
const up: u64 = @bitCast(operand);
|
||||
break :blk @bitCast(if (want_max) @max(uo, up) else @min(uo, up));
|
||||
}
|
||||
break :blk if (want_max) @max(old, operand) else @min(old, operand);
|
||||
},
|
||||
};
|
||||
try self.writeField(table, frame.get(a.ptr.index()), vty, new_val);
|
||||
return .{ .value = old };
|
||||
},
|
||||
.struct_init => |agg| {
|
||||
const table = try self.requireTable();
|
||||
const sty = ins.ty;
|
||||
|
||||
Reference in New Issue
Block a user