atomics A.0a: lib + IR ops + recognizer, emit bails (lock commit)
Stream A (atomics) foundation. Net-new atomic load/store codegen path, wired end-to-end except LLVM emission, which deliberately bails loudly so the example locks to a clean diagnostic (A.0b turns it green — cadence: no commit both adds a test and makes it pass). - library/modules/std/atomic.sx: Ordering enum, Atomic($T) transparent wrapper (init/load/store, seq_cst-only for now), atomic_load/atomic_store #builtin intrinsics. Opt-in import, NOT in the universal std facade (Ordering in the prelude grows every program's type table + churns 37 .ir snapshots). - IR: atomic_load/atomic_store ops + AtomicOrdering (all 5) + structs (inst.zig); print arms; comptime_vm arms reuse load/store (single-thread correct); recognizer tryLowerAtomicIntrinsic (const-ordering + scalar-size guards, both loud); emit dispatch -> emitAtomicLoad/Store bail via comptime_failed. - examples/1700-atomics-load-store.sx locked to the bail diagnostic. Full ordering surface (a.load(.acquire)) blocked on comptime-constant ordering propagation (comptime enum value params) — A.0.5, migrated not legacy.
This commit is contained in:
@@ -161,6 +161,10 @@ pub const Op = union(enum) {
|
||||
load: UnaryOp, // load from pointer
|
||||
store: Store, // store value to pointer
|
||||
|
||||
// ── Atomics ─────────────────────────────────────────────────────
|
||||
atomic_load: AtomicLoad, // atomic load from pointer with memory ordering
|
||||
atomic_store: AtomicStore, // atomic store to pointer with memory ordering
|
||||
|
||||
// ── Struct ops ──────────────────────────────────────────────────
|
||||
struct_init: Aggregate, // construct struct from field values
|
||||
struct_get: FieldAccess, // read struct field by index
|
||||
@@ -294,6 +298,27 @@ pub const Store = struct {
|
||||
val_ty: TypeId = .void,
|
||||
};
|
||||
|
||||
/// Memory ordering for atomic ops. The sx-surface `Ordering` enum
|
||||
/// (`relaxed`/`acquire`/`release`/`acq_rel`/`seq_cst`) is read statically at
|
||||
/// lower-time (the arg MUST be a constant enum literal) and baked here, so the
|
||||
/// op carries no runtime ordering operand. The LLVM mapping is EXPLICIT (LLVM's
|
||||
/// `LLVMAtomicOrdering` is non-contiguous: Monotonic=2/Acquire=4/…/SeqCst=7) —
|
||||
/// never an identity cast.
|
||||
pub const AtomicOrdering = enum { relaxed, acquire, release, acq_rel, seq_cst };
|
||||
|
||||
pub const AtomicLoad = struct {
|
||||
ptr: Ref,
|
||||
ordering: AtomicOrdering,
|
||||
};
|
||||
|
||||
pub const AtomicStore = struct {
|
||||
ptr: Ref,
|
||||
val: Ref,
|
||||
/// Declared type of the stored value (same role as `Store.val_ty`).
|
||||
val_ty: TypeId = .void,
|
||||
ordering: AtomicOrdering,
|
||||
};
|
||||
|
||||
pub const Conversion = struct {
|
||||
operand: Ref,
|
||||
from: TypeId,
|
||||
|
||||
Reference in New Issue
Block a user