commit a2f6367d5228992098a5ed2c3883ec113d623ab9
parent 917ffe99af9830110b9e682f3cfe21690f17ea58
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 1 Jun 2026 19:29:08 -0700
cg: consume public CfreeCgAtomicOp/CfreeCgMemOrder directly (Track 2, atomics slice)
Delete the internal AtomicOp and MemOrder enums (identical 1:1 to the public
CfreeCgAtomicOp/CfreeCgMemOrder) and api_map_atomic_op/api_map_mem_order. Both
the semantic CgTarget and the physical NativeTarget atomic hooks
(atomic_load/store/rmw/cas/fence), the recorded + opt IR aux structs, and every
backend + the interpreter now carry the public enums straight through. The C
frontend keeps its own private copy (separate Principle-1 issue). Value-
preserving; no behavior change. toy 1344/0, cg-api 173/0, smoke x64+rv64 green.
Diffstat:
22 files changed, 187 insertions(+), 241 deletions(-)
diff --git a/src/arch/aa64/native.c b/src/arch/aa64/native.c
@@ -2950,13 +2950,13 @@ static void aa_bitfield_store(NativeTarget* t, NativeAddr addr, NativeLoc src,
static void aa_trap(NativeTarget* t);
-static int aa_order_acquire(MemOrder order) {
- return order == MO_CONSUME || order == MO_ACQUIRE || order == MO_ACQ_REL ||
- order == MO_SEQ_CST;
+static int aa_order_acquire(CfreeCgMemOrder order) {
+ return order == CFREE_CG_MO_CONSUME || order == CFREE_CG_MO_ACQUIRE || order == CFREE_CG_MO_ACQ_REL ||
+ order == CFREE_CG_MO_SEQ_CST;
}
-static int aa_order_release(MemOrder order) {
- return order == MO_RELEASE || order == MO_ACQ_REL || order == MO_SEQ_CST;
+static int aa_order_release(CfreeCgMemOrder order) {
+ return order == CFREE_CG_MO_RELEASE || order == CFREE_CG_MO_ACQ_REL || order == CFREE_CG_MO_SEQ_CST;
}
static NativeLoc aa_i64_reg_loc(u32 reg) {
@@ -3008,31 +3008,31 @@ static void aa_saved_tmp_restore(AANativeTarget* a, u32 reg) {
}
static void aa_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr,
- MemAccess mem, MemOrder order) {
+ MemAccess mem, CfreeCgMemOrder order) {
u32 base = AA_TMP0;
u32 sz = size_idx(mem.size ? mem.size : type_size32(t, dst.type));
aa_atomic_addr_reg(t, addr, base);
aa_emit32(t->mc, aa_order_acquire(order)
? aa_ldar(sz, loc_reg(dst), base)
: aa_ldr_uimm(sz, loc_reg(dst), base, 0));
- if (order == MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
+ if (order == CFREE_CG_MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
}
static void aa_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src,
- MemAccess mem, MemOrder order) {
+ MemAccess mem, CfreeCgMemOrder order) {
u32 base = AA_TMP0;
u32 sz = size_idx(mem.size ? mem.size : type_size32(t, src.type));
- if (order == MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
+ if (order == CFREE_CG_MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
aa_atomic_addr_reg(t, addr, base);
aa_emit32(t->mc, aa_order_release(order)
? aa_stlr(sz, loc_reg(src), base)
: aa_str_uimm(sz, loc_reg(src), base, 0));
- if (order == MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
+ if (order == CFREE_CG_MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
}
-static void aa_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
+static void aa_atomic_rmw(NativeTarget* t, CfreeCgAtomicOp op, NativeLoc dst,
NativeAddr addr, NativeLoc val, MemAccess mem,
- MemOrder order) {
+ CfreeCgMemOrder order) {
AANativeTarget* a = aa_of(t);
u32 base = AA_TMP0;
u32 next_reg = AA_TMP1;
@@ -3040,32 +3040,32 @@ static void aa_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
NativeLoc next = aa_tmp_loc(dst.type, next_reg);
MCLabel retry = t->mc->label_new(t->mc);
u32 sz = size_idx(mem.size ? mem.size : type_size32(t, dst.type));
- if (order == MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
+ if (order == CFREE_CG_MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
aa_saved_tmp_spill(a, status);
aa_atomic_addr_reg(t, addr, base);
t->mc->label_place(t->mc, retry);
aa_emit32(t->mc, aa_order_acquire(order) ? aa_ldaxr(sz, loc_reg(dst), base)
: aa_ldxr(sz, loc_reg(dst), base));
switch (op) {
- case AO_XCHG:
+ case CFREE_CG_ATOMIC_XCHG:
aa_move(t, next, val);
break;
- case AO_ADD:
+ case CFREE_CG_ATOMIC_ADD:
aa_binop(t, BO_IADD, next, dst, val);
break;
- case AO_SUB:
+ case CFREE_CG_ATOMIC_SUB:
aa_binop(t, BO_ISUB, next, dst, val);
break;
- case AO_AND:
+ case CFREE_CG_ATOMIC_AND:
aa_binop(t, BO_AND, next, dst, val);
break;
- case AO_OR:
+ case CFREE_CG_ATOMIC_OR:
aa_binop(t, BO_OR, next, dst, val);
break;
- case AO_XOR:
+ case CFREE_CG_ATOMIC_XOR:
aa_binop(t, BO_XOR, next, dst, val);
break;
- case AO_NAND:
+ case CFREE_CG_ATOMIC_NAND:
aa_binop(t, BO_AND, next, dst, val);
aa_unop(t, UO_BNOT, next, next);
break;
@@ -3078,13 +3078,13 @@ static void aa_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
aa_emit32(t->mc, aa64_cbnz_imm(0, status, 0));
t->mc->emit_label_ref(t->mc, retry, R_AARCH64_CONDBR19, 4, 0);
aa_saved_tmp_restore(a, status);
- if (order == MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
+ if (order == CFREE_CG_MO_SEQ_CST) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
}
static void aa_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
NativeAddr addr, NativeLoc expected,
- NativeLoc desired, MemAccess mem, MemOrder success,
- MemOrder failure) {
+ NativeLoc desired, MemAccess mem, CfreeCgMemOrder success,
+ CfreeCgMemOrder failure) {
u32 base = AA_TMP0;
u32 status = AA_TMP1;
u32 sz = size_idx(mem.size ? mem.size : type_size32(t, prior.type));
@@ -3094,7 +3094,7 @@ static void aa_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
MCLabel retry = t->mc->label_new(t->mc);
MCLabel fail = t->mc->label_new(t->mc);
MCLabel done = t->mc->label_new(t->mc);
- if (success == MO_SEQ_CST || failure == MO_SEQ_CST)
+ if (success == CFREE_CG_MO_SEQ_CST || failure == CFREE_CG_MO_SEQ_CST)
aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
aa_atomic_addr_reg(t, addr, base);
t->mc->label_place(t->mc, retry);
@@ -3113,12 +3113,12 @@ static void aa_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
aa_emit32(t->mc, aa64_clrex(AA64_BARRIER_OPT_SY));
aa_emit_load_imm(t->mc, loc_is_64(t, ok), loc_reg(ok), 0);
t->mc->label_place(t->mc, done);
- if (success == MO_SEQ_CST || failure == MO_SEQ_CST)
+ if (success == CFREE_CG_MO_SEQ_CST || failure == CFREE_CG_MO_SEQ_CST)
aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
}
-static void aa_fence(NativeTarget* t, MemOrder order) {
- if (order != MO_RELAXED) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
+static void aa_fence(NativeTarget* t, CfreeCgMemOrder order) {
+ if (order != CFREE_CG_MO_RELAXED) aa_emit32(t->mc, aa64_dmb(AA64_BARRIER_OPT_ISH));
}
static void aa_intrinsic(NativeTarget* t, IntrinKind kind,
diff --git a/src/arch/c_target/c_emit.c b/src/arch/c_target/c_emit.c
@@ -3245,39 +3245,39 @@ void c_emit_load_const(CTarget* t, Operand dst, ConstBytes cb) {
*
* Lowered to gcc/clang's `__atomic_*` generic builtins. The host compiler
* picks the inline sequence vs. libcall and applies the requested memory
- * order. cfree's MemOrder enum aligns 1-1 with the `__ATOMIC_*` constants. */
+ * order. cfree's CfreeCgMemOrder enum aligns 1-1 with the `__ATOMIC_*` constants. */
-static const char* c_memorder_token(MemOrder o) {
+static const char* c_memorder_token(CfreeCgMemOrder o) {
switch (o) {
- case MO_RELAXED:
+ case CFREE_CG_MO_RELAXED:
return "__ATOMIC_RELAXED";
- case MO_CONSUME:
+ case CFREE_CG_MO_CONSUME:
return "__ATOMIC_CONSUME";
- case MO_ACQUIRE:
+ case CFREE_CG_MO_ACQUIRE:
return "__ATOMIC_ACQUIRE";
- case MO_RELEASE:
+ case CFREE_CG_MO_RELEASE:
return "__ATOMIC_RELEASE";
- case MO_ACQ_REL:
+ case CFREE_CG_MO_ACQ_REL:
return "__ATOMIC_ACQ_REL";
- case MO_SEQ_CST:
+ case CFREE_CG_MO_SEQ_CST:
return "__ATOMIC_SEQ_CST";
}
return "__ATOMIC_SEQ_CST";
}
void c_emit_atomic_load(CTarget* t, Operand dst, Operand addr, MemAccess m,
- MemOrder o);
+ CfreeCgMemOrder o);
void c_emit_atomic_store(CTarget* t, Operand addr, Operand src, MemAccess m,
- MemOrder o);
-void c_emit_atomic_rmw(CTarget* t, AtomicOp op, Operand dst, Operand addr,
- Operand val, MemAccess m, MemOrder o);
+ CfreeCgMemOrder o);
+void c_emit_atomic_rmw(CTarget* t, CfreeCgAtomicOp op, Operand dst, Operand addr,
+ Operand val, MemAccess m, CfreeCgMemOrder o);
void c_emit_atomic_cas(CTarget* t, Operand prior, Operand ok, Operand addr,
Operand expected, Operand desired, MemAccess m,
- MemOrder so, MemOrder fo);
-void c_emit_fence(CTarget* t, MemOrder o);
+ CfreeCgMemOrder so, CfreeCgMemOrder fo);
+void c_emit_fence(CTarget* t, CfreeCgMemOrder o);
void c_emit_atomic_load(CTarget* t, Operand dst, Operand addr, MemAccess m,
- MemOrder o) {
+ CfreeCgMemOrder o) {
(void)m;
c_assert_no_index(t, addr, "atomic_load");
c_ensure_local(t, dst.v.local, dst.type);
@@ -3294,7 +3294,7 @@ void c_emit_atomic_load(CTarget* t, Operand dst, Operand addr, MemAccess m,
}
void c_emit_atomic_store(CTarget* t, Operand addr, Operand src, MemAccess m,
- MemOrder o) {
+ CfreeCgMemOrder o) {
(void)m;
c_assert_no_index(t, addr, "atomic_store");
cbuf_puts(&t->body, " __atomic_store_n((");
@@ -3308,28 +3308,28 @@ void c_emit_atomic_store(CTarget* t, Operand addr, Operand src, MemAccess m,
cbuf_puts(&t->body, ");\n");
}
-static const char* c_atomic_op_builtin(AtomicOp op) {
+static const char* c_atomic_op_builtin(CfreeCgAtomicOp op) {
switch (op) {
- case AO_XCHG:
+ case CFREE_CG_ATOMIC_XCHG:
return "__atomic_exchange_n";
- case AO_ADD:
+ case CFREE_CG_ATOMIC_ADD:
return "__atomic_fetch_add";
- case AO_SUB:
+ case CFREE_CG_ATOMIC_SUB:
return "__atomic_fetch_sub";
- case AO_AND:
+ case CFREE_CG_ATOMIC_AND:
return "__atomic_fetch_and";
- case AO_OR:
+ case CFREE_CG_ATOMIC_OR:
return "__atomic_fetch_or";
- case AO_XOR:
+ case CFREE_CG_ATOMIC_XOR:
return "__atomic_fetch_xor";
- case AO_NAND:
+ case CFREE_CG_ATOMIC_NAND:
return "__atomic_fetch_nand";
}
return NULL;
}
-void c_emit_atomic_rmw(CTarget* t, AtomicOp op, Operand dst, Operand addr,
- Operand val, MemAccess m, MemOrder o) {
+void c_emit_atomic_rmw(CTarget* t, CfreeCgAtomicOp op, Operand dst, Operand addr,
+ Operand val, MemAccess m, CfreeCgMemOrder o) {
(void)m;
SrcLoc loc = t->cur_fn ? t->cur_fn->loc : (SrcLoc){0, 0, 0};
c_assert_no_index(t, addr, "atomic_rmw");
@@ -3355,7 +3355,7 @@ void c_emit_atomic_rmw(CTarget* t, AtomicOp op, Operand dst, Operand addr,
void c_emit_atomic_cas(CTarget* t, Operand prior, Operand ok, Operand addr,
Operand expected, Operand desired, MemAccess m,
- MemOrder so, MemOrder fo) {
+ CfreeCgMemOrder so, CfreeCgMemOrder fo) {
(void)m;
c_assert_no_index(t, addr, "atomic_cas");
/* gcc's __atomic_compare_exchange_n needs a real lvalue holding the
@@ -3397,7 +3397,7 @@ void c_emit_atomic_cas(CTarget* t, Operand prior, Operand ok, Operand addr,
cbuf_puts(&t->body, "; }\n");
}
-void c_emit_fence(CTarget* t, MemOrder o) {
+void c_emit_fence(CTarget* t, CfreeCgMemOrder o) {
cbuf_puts(&t->body, " __atomic_thread_fence(");
cbuf_puts(&t->body, c_memorder_token(o));
cbuf_puts(&t->body, ");\n");
diff --git a/src/arch/c_target/c_emit.h b/src/arch/c_target/c_emit.h
@@ -246,12 +246,12 @@ void c_emit_asm_block(CTarget*, const char*, const AsmConstraint*, u32,
void c_emit_bitfield_load(CTarget*, Operand, Operand, BitFieldAccess);
void c_emit_bitfield_store(CTarget*, Operand, Operand, BitFieldAccess);
void c_emit_tls_addr_of(CTarget*, Operand, ObjSymId, i64);
-void c_emit_atomic_load(CTarget*, Operand, Operand, MemAccess, MemOrder);
-void c_emit_atomic_store(CTarget*, Operand, Operand, MemAccess, MemOrder);
-void c_emit_atomic_rmw(CTarget*, AtomicOp, Operand, Operand, Operand, MemAccess,
- MemOrder);
+void c_emit_atomic_load(CTarget*, Operand, Operand, MemAccess, CfreeCgMemOrder);
+void c_emit_atomic_store(CTarget*, Operand, Operand, MemAccess, CfreeCgMemOrder);
+void c_emit_atomic_rmw(CTarget*, CfreeCgAtomicOp, Operand, Operand, Operand, MemAccess,
+ CfreeCgMemOrder);
void c_emit_atomic_cas(CTarget*, Operand, Operand, Operand, Operand, Operand,
- MemAccess, MemOrder, MemOrder);
-void c_emit_fence(CTarget*, MemOrder);
+ MemAccess, CfreeCgMemOrder, CfreeCgMemOrder);
+void c_emit_fence(CTarget*, CfreeCgMemOrder);
#endif
diff --git a/src/arch/c_target/ir_emit.c b/src/arch/c_target/ir_emit.c
@@ -227,7 +227,7 @@ static void ir_emit_inst(CIrEmitter* e, const CgIrInst* in) {
return;
}
case CG_IR_FENCE:
- c_emit_fence(t, (MemOrder)in->extra.imm);
+ c_emit_fence(t, (CfreeCgMemOrder)in->extra.imm);
return;
case CG_IR_INTRINSIC: {
const CgIrIntrinsicAux* aux = (const CgIrIntrinsicAux*)in->extra.aux;
diff --git a/src/arch/check_target.c b/src/arch/check_target.c
@@ -292,7 +292,7 @@ static void check_asm_block(CgTarget* t, const char* tmpl,
}
static void check_atomic_load(CgTarget* t, Operand dst, Operand addr,
- MemAccess m, MemOrder order) {
+ MemAccess m, CfreeCgMemOrder order) {
(void)t;
(void)dst;
(void)addr;
@@ -301,7 +301,7 @@ static void check_atomic_load(CgTarget* t, Operand dst, Operand addr,
}
static void check_atomic_store(CgTarget* t, Operand addr, Operand src,
- MemAccess m, MemOrder order) {
+ MemAccess m, CfreeCgMemOrder order) {
(void)t;
(void)addr;
(void)src;
@@ -309,9 +309,9 @@ static void check_atomic_store(CgTarget* t, Operand addr, Operand src,
(void)order;
}
-static void check_atomic_rmw(CgTarget* t, AtomicOp op, Operand dst,
+static void check_atomic_rmw(CgTarget* t, CfreeCgAtomicOp op, Operand dst,
Operand addr, Operand val, MemAccess m,
- MemOrder order) {
+ CfreeCgMemOrder order) {
(void)t;
(void)op;
(void)dst;
@@ -323,7 +323,7 @@ static void check_atomic_rmw(CgTarget* t, AtomicOp op, Operand dst,
static void check_atomic_cas(CgTarget* t, Operand prior, Operand ok,
Operand addr, Operand expected, Operand desired,
- MemAccess m, MemOrder success, MemOrder failure) {
+ MemAccess m, CfreeCgMemOrder success, CfreeCgMemOrder failure) {
(void)t;
(void)prior;
(void)ok;
@@ -335,7 +335,7 @@ static void check_atomic_cas(CgTarget* t, Operand prior, Operand ok,
(void)failure;
}
-static void check_fence(CgTarget* t, MemOrder order) {
+static void check_fence(CgTarget* t, CfreeCgMemOrder order) {
(void)t;
(void)order;
}
diff --git a/src/arch/native_target.h b/src/arch/native_target.h
@@ -460,15 +460,15 @@ struct NativeTarget {
void (*ret)(NativeTarget*);
void (*atomic_load)(NativeTarget*, NativeLoc dst, NativeAddr addr, MemAccess,
- MemOrder);
+ CfreeCgMemOrder);
void (*atomic_store)(NativeTarget*, NativeAddr addr, NativeLoc src, MemAccess,
- MemOrder);
- void (*atomic_rmw)(NativeTarget*, AtomicOp, NativeLoc dst, NativeAddr addr,
- NativeLoc val, MemAccess, MemOrder);
+ CfreeCgMemOrder);
+ void (*atomic_rmw)(NativeTarget*, CfreeCgAtomicOp, NativeLoc dst, NativeAddr addr,
+ NativeLoc val, MemAccess, CfreeCgMemOrder);
void (*atomic_cas)(NativeTarget*, NativeLoc prior, NativeLoc ok,
NativeAddr addr, NativeLoc expected, NativeLoc desired,
- MemAccess, MemOrder success, MemOrder failure);
- void (*fence)(NativeTarget*, MemOrder);
+ MemAccess, CfreeCgMemOrder success, CfreeCgMemOrder failure);
+ void (*fence)(NativeTarget*, CfreeCgMemOrder);
/* Variadic support. The optimizer passes the va_list pointer opaquely as a
* NativeLoc (a register or memory location holding the address of the
* va_list object); va_arg additionally receives the argument type and a
diff --git a/src/arch/rv64/native.c b/src/arch/rv64/native.c
@@ -2338,12 +2338,12 @@ static void rv_bitfield_store(NativeTarget* t, NativeAddr ra, NativeLoc src,
rv64_emit32(mc, rv_or(RV_TMP2, RV_TMP2, RV_TMP0));
rv64_emit32(mc, enc_int_store(storage_bytes, RV_TMP2, base, off));
}
-static int rv_order_acquire(MemOrder o) {
- return o == MO_CONSUME || o == MO_ACQUIRE || o == MO_ACQ_REL ||
- o == MO_SEQ_CST;
+static int rv_order_acquire(CfreeCgMemOrder o) {
+ return o == CFREE_CG_MO_CONSUME || o == CFREE_CG_MO_ACQUIRE || o == CFREE_CG_MO_ACQ_REL ||
+ o == CFREE_CG_MO_SEQ_CST;
}
-static int rv_order_release(MemOrder o) {
- return o == MO_RELEASE || o == MO_ACQ_REL || o == MO_SEQ_CST;
+static int rv_order_release(CfreeCgMemOrder o) {
+ return o == CFREE_CG_MO_RELEASE || o == CFREE_CG_MO_ACQ_REL || o == CFREE_CG_MO_SEQ_CST;
}
/* Materialize the atomic operand address into RV_TMP0 (a bare pointer, since
@@ -2356,12 +2356,12 @@ static u32 rv_atomic_addr_reg(RvNativeTarget* a, NativeAddr addr) {
}
static void rv_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr,
- MemAccess mem, MemOrder mo) {
+ MemAccess mem, CfreeCgMemOrder mo) {
RvNativeTarget* a = rv_of(t);
MCEmitter* mc = t->mc;
u32 sf = (mem.size ? mem.size : rv_type_size(t, dst.type)) == 8u ? 1u : 0u;
u32 base = rv_atomic_addr_reg(a, addr);
- if (mo == MO_SEQ_CST) rv64_emit32(mc, rv_fence_rw_rw());
+ if (mo == CFREE_CG_MO_SEQ_CST) rv64_emit32(mc, rv_fence_rw_rw());
if (rv_order_acquire(mo)) {
/* lr.w/d as an ordered load (aq=1). */
rv64_emit32(mc, sf ? rv_lr_d(loc_reg(dst), base, 1, 0)
@@ -2373,7 +2373,7 @@ static void rv_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr,
}
static void rv_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src,
- MemAccess mem, MemOrder mo) {
+ MemAccess mem, CfreeCgMemOrder mo) {
RvNativeTarget* a = rv_of(t);
MCEmitter* mc = t->mc;
u32 sz = mem.size ? mem.size : rv_type_size(t, src.type);
@@ -2381,12 +2381,12 @@ static void rv_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src,
u32 base = rv_atomic_addr_reg(a, addr);
if (rv_order_release(mo)) rv64_emit32(mc, rv_fence_rw_rw());
rv64_emit32(mc, enc_int_store(sz, loc_reg(src), base, 0));
- if (mo == MO_SEQ_CST) rv64_emit32(mc, rv_fence_rw_rw());
+ if (mo == CFREE_CG_MO_SEQ_CST) rv64_emit32(mc, rv_fence_rw_rw());
}
-static void rv_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
+static void rv_atomic_rmw(NativeTarget* t, CfreeCgAtomicOp op, NativeLoc dst,
NativeAddr addr, NativeLoc val, MemAccess mem,
- MemOrder mo) {
+ CfreeCgMemOrder mo) {
RvNativeTarget* a = rv_of(t);
MCEmitter* mc = t->mc;
u32 sf = (mem.size ? mem.size : rv_type_size(t, dst.type)) == 8u ? 1u : 0u;
@@ -2401,25 +2401,25 @@ static void rv_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
mc->label_place(mc, retry);
rv64_emit32(mc, sf ? rv_lr_d(rd, base, aq, 0) : rv_lr_w(rd, base, aq, 0));
switch (op) {
- case AO_XCHG:
+ case CFREE_CG_ATOMIC_XCHG:
rv64_emit32(mc, rv_addi(RV_TMP3, vreg, 0));
break;
- case AO_ADD:
+ case CFREE_CG_ATOMIC_ADD:
rv64_emit32(mc, sf ? rv_add(RV_TMP3, rd, vreg) : rv_addw(RV_TMP3, rd, vreg));
break;
- case AO_SUB:
+ case CFREE_CG_ATOMIC_SUB:
rv64_emit32(mc, sf ? rv_sub(RV_TMP3, rd, vreg) : rv_subw(RV_TMP3, rd, vreg));
break;
- case AO_AND:
+ case CFREE_CG_ATOMIC_AND:
rv64_emit32(mc, rv_and(RV_TMP3, rd, vreg));
break;
- case AO_OR:
+ case CFREE_CG_ATOMIC_OR:
rv64_emit32(mc, rv_or(RV_TMP3, rd, vreg));
break;
- case AO_XOR:
+ case CFREE_CG_ATOMIC_XOR:
rv64_emit32(mc, rv_xor(RV_TMP3, rd, vreg));
break;
- case AO_NAND:
+ case CFREE_CG_ATOMIC_NAND:
rv64_emit32(mc, rv_and(RV_TMP3, rd, vreg));
rv64_emit32(mc, rv_xori(RV_TMP3, RV_TMP3, -1));
break;
@@ -2434,7 +2434,7 @@ static void rv_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
static void rv_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
NativeAddr addr, NativeLoc expected, NativeLoc desired,
- MemAccess mem, MemOrder success, MemOrder failure) {
+ MemAccess mem, CfreeCgMemOrder success, CfreeCgMemOrder failure) {
RvNativeTarget* a = rv_of(t);
MCEmitter* mc = t->mc;
u32 sf = (mem.size ? mem.size : rv_type_size(t, prior.type)) == 8u ? 1u : 0u;
@@ -2468,8 +2468,8 @@ static void rv_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
mc->label_place(mc, done);
}
-static void rv_fence(NativeTarget* t, MemOrder mo) {
- if (mo == MO_RELAXED) return;
+static void rv_fence(NativeTarget* t, CfreeCgMemOrder mo) {
+ if (mo == CFREE_CG_MO_RELAXED) return;
rv64_emit32(t->mc, rv_fence_rw_rw());
}
/* ---- variadics (LP64D ABI_VA_LIST_POINTER) ----
diff --git a/src/arch/wasm/emit.c b/src/arch/wasm/emit.c
@@ -1442,7 +1442,7 @@ void wasm_set_bytes(CGTarget* tg, Operand dst, Operand byte,
}
/* Atomic ops. CG forces `addr` to a REG and accepts reg-or-imm for value
- * operands. Wasm only models seq_cst; the MemOrder argument is captured but
+ * operands. Wasm only models seq_cst; the CfreeCgMemOrder argument is captured but
* not encoded — every emitted atomic op is sequentially consistent. The
* caller-provided MemAccess carries the type and natural alignment we need
* for the memarg width. */
@@ -1454,7 +1454,7 @@ static void atomic_require_addr_reg(WTarget* t, Operand addr,
}
void wasm_atomic_load(CGTarget* tg, Operand dst, Operand addr, MemAccess mem,
- MemOrder mo) {
+ CfreeCgMemOrder mo) {
WTarget* t = (WTarget*)tg;
(void)mo;
if (t->dead) return;
@@ -1471,7 +1471,7 @@ void wasm_atomic_load(CGTarget* tg, Operand dst, Operand addr, MemAccess mem,
}
void wasm_atomic_store(CGTarget* tg, Operand addr, Operand src, MemAccess mem,
- MemOrder mo) {
+ CfreeCgMemOrder mo) {
WTarget* t = (WTarget*)tg;
(void)mo;
if (t->dead) return;
@@ -1487,8 +1487,8 @@ void wasm_atomic_store(CGTarget* tg, Operand addr, Operand src, MemAccess mem,
w->type = mem.type ? mem.type : src.type;
}
-void wasm_atomic_rmw(CGTarget* tg, AtomicOp op, Operand dst, Operand addr,
- Operand val, MemAccess mem, MemOrder mo) {
+void wasm_atomic_rmw(CGTarget* tg, CfreeCgAtomicOp op, Operand dst, Operand addr,
+ Operand val, MemAccess mem, CfreeCgMemOrder mo) {
WTarget* t = (WTarget*)tg;
(void)mo;
if (t->dead) return;
@@ -1496,7 +1496,7 @@ void wasm_atomic_rmw(CGTarget* tg, AtomicOp op, Operand dst, Operand addr,
atomic_require_addr_reg(t, addr, "atomic_rmw");
if (val.kind != OPK_REG && val.kind != OPK_IMM)
wfail(t, "wasm: atomic_rmw value must be REG or IMM");
- /* AO_NAND has no native wasm-threads opcode; the linearizer expands it into
+ /* CFREE_CG_ATOMIC_NAND has no native wasm-threads opcode; the linearizer expands it into
* an atomic cmpxchg retry loop (see WIR_ATOMIC_RMW). */
ensure_shared_memory(t);
WIR* w = wir_push(t);
@@ -1512,7 +1512,7 @@ void wasm_atomic_rmw(CGTarget* tg, AtomicOp op, Operand dst, Operand addr,
void wasm_atomic_cas(CGTarget* tg, Operand prior, Operand ok, Operand addr,
Operand expected, Operand desired, MemAccess mem,
- MemOrder success, MemOrder failure) {
+ CfreeCgMemOrder success, CfreeCgMemOrder failure) {
WTarget* t = (WTarget*)tg;
(void)success;
(void)failure;
@@ -1545,7 +1545,7 @@ void wasm_atomic_cas(CGTarget* tg, Operand prior, Operand ok, Operand addr,
w->type2 = ok.type;
}
-void wasm_fence(CGTarget* tg, MemOrder mo) {
+void wasm_fence(CGTarget* tg, CfreeCgMemOrder mo) {
WTarget* t = (WTarget*)tg;
(void)mo;
if (t->dead) return;
@@ -2191,7 +2191,7 @@ static WasmInsnKind atomic_store_kind_for(WTarget* t, CfreeCgTypeId ty,
wfail(t, "wasm: atomic store i32 size %u not supported", size);
}
-static WasmInsnKind atomic_rmw_kind_for(WTarget* t, AtomicOp op,
+static WasmInsnKind atomic_rmw_kind_for(WTarget* t, CfreeCgAtomicOp op,
CfreeCgTypeId ty, MemAccess ma) {
WasmValType vt = type_valtype(t, ty);
u32 size = ma.size ? ma.size : (u32)abi_cg_sizeof(t->c->abi, ty);
@@ -2208,20 +2208,20 @@ static WasmInsnKind atomic_rmw_kind_for(WTarget* t, AtomicOp op,
size);
}
switch (op) {
- case AO_ADD:
+ case CFREE_CG_ATOMIC_ADD:
return is64 ? WASM_INSN_I64_ATOMIC_RMW_ADD : WASM_INSN_I32_ATOMIC_RMW_ADD;
- case AO_SUB:
+ case CFREE_CG_ATOMIC_SUB:
return is64 ? WASM_INSN_I64_ATOMIC_RMW_SUB : WASM_INSN_I32_ATOMIC_RMW_SUB;
- case AO_AND:
+ case CFREE_CG_ATOMIC_AND:
return is64 ? WASM_INSN_I64_ATOMIC_RMW_AND : WASM_INSN_I32_ATOMIC_RMW_AND;
- case AO_OR:
+ case CFREE_CG_ATOMIC_OR:
return is64 ? WASM_INSN_I64_ATOMIC_RMW_OR : WASM_INSN_I32_ATOMIC_RMW_OR;
- case AO_XOR:
+ case CFREE_CG_ATOMIC_XOR:
return is64 ? WASM_INSN_I64_ATOMIC_RMW_XOR : WASM_INSN_I32_ATOMIC_RMW_XOR;
- case AO_XCHG:
+ case CFREE_CG_ATOMIC_XCHG:
return is64 ? WASM_INSN_I64_ATOMIC_RMW_XCHG
: WASM_INSN_I32_ATOMIC_RMW_XCHG;
- case AO_NAND:
+ case CFREE_CG_ATOMIC_NAND:
wfail(t, "wasm target: atomic NAND has no native wasm-threads opcode");
}
wfail(t, "wasm: unsupported atomic RMW op %d", (int)op);
@@ -3671,7 +3671,7 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) {
break;
}
case WIR_ATOMIC_RMW: {
- if ((AtomicOp)w->cgop == AO_NAND) {
+ if ((CfreeCgAtomicOp)w->cgop == CFREE_CG_ATOMIC_NAND) {
/* wasm-threads has no atomic.rmw.nand. Expand to a cmpxchg retry
* loop computing desired = ~(old & val):
* loop
@@ -3716,7 +3716,7 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) {
break;
}
WasmInsnKind k =
- atomic_rmw_kind_for(t, (AtomicOp)w->cgop, w->type, w->mem);
+ atomic_rmw_kind_for(t, (CfreeCgAtomicOp)w->cgop, w->type, w->mem);
u32 width = wasm_mem_width((uint8_t)k);
emit_push_operand_reg(t, w->a);
emit_push_operand(t, w->imm_kind_b, w->imm_b, w->b, w->type);
diff --git a/src/arch/wasm/internal.h b/src/arch/wasm/internal.h
@@ -80,7 +80,7 @@ typedef enum WIROp {
WIR_SET_BYTES, /* memset-like byte set */
WIR_ATOMIC_LOAD, /* dst = atomic.load(addr_reg), mem holds access info */
WIR_ATOMIC_STORE, /* atomic.store(addr_reg, src) */
- WIR_ATOMIC_RMW, /* dst = atomic.rmw_<op>(addr_reg, val); cgop = AtomicOp */
+ WIR_ATOMIC_RMW, /* dst = atomic.rmw_<op>(addr_reg, val); cgop = CfreeCgAtomicOp */
WIR_ATOMIC_CAS, /* dst = prior; dst2 = ok (i32 0/1); a=addr_reg,
b/imm_kind_b=expected, op_c/imm_kind_c=desired */
WIR_FENCE, /* atomic.fence (memory order ignored, wasm has seq_cst) */
diff --git a/src/arch/wasm/ir_emit.c b/src/arch/wasm/ir_emit.c
@@ -46,13 +46,13 @@ void wasm_va_start(CGTarget*, Operand);
void wasm_va_arg(CGTarget*, Operand, Operand, CfreeCgTypeId);
void wasm_va_end(CGTarget*, Operand);
void wasm_va_copy(CGTarget*, Operand, Operand);
-void wasm_atomic_load(CGTarget*, Operand, Operand, MemAccess, MemOrder);
-void wasm_atomic_store(CGTarget*, Operand, Operand, MemAccess, MemOrder);
-void wasm_atomic_rmw(CGTarget*, AtomicOp, Operand, Operand, Operand, MemAccess,
- MemOrder);
+void wasm_atomic_load(CGTarget*, Operand, Operand, MemAccess, CfreeCgMemOrder);
+void wasm_atomic_store(CGTarget*, Operand, Operand, MemAccess, CfreeCgMemOrder);
+void wasm_atomic_rmw(CGTarget*, CfreeCgAtomicOp, Operand, Operand, Operand, MemAccess,
+ CfreeCgMemOrder);
void wasm_atomic_cas(CGTarget*, Operand, Operand, Operand, Operand, Operand,
- MemAccess, MemOrder, MemOrder);
-void wasm_fence(CGTarget*, MemOrder);
+ MemAccess, CfreeCgMemOrder, CfreeCgMemOrder);
+void wasm_fence(CGTarget*, CfreeCgMemOrder);
void wasm_intrinsic(CGTarget*, IntrinKind, Operand*, u32, const Operand*, u32);
void wasm_asm_block(CGTarget*, const char*, const AsmConstraint*, u32, Operand*,
const AsmConstraint*, u32, const Operand*, const Sym*, u32);
@@ -765,7 +765,7 @@ static void wasm_ir_emit_inst(WasmIrEmitter* e, const CgIrFunc* f,
return;
}
case CG_IR_FENCE:
- wasm_fence(t, (MemOrder)in->extra.imm);
+ wasm_fence(t, (CfreeCgMemOrder)in->extra.imm);
return;
case CG_IR_INTRINSIC: {
const CgIrIntrinsicAux* aux = (const CgIrIntrinsicAux*)in->extra.aux;
diff --git a/src/arch/x64/native.c b/src/arch/x64/native.c
@@ -2822,7 +2822,7 @@ static u32 x64_atomic_base(X64NativeTarget* a, NativeAddr addr) {
}
static void x64_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr,
- MemAccess mem, MemOrder mo) {
+ MemAccess mem, CfreeCgMemOrder mo) {
X64NativeTarget* a = x64_of(t);
u32 sz = mem.size ? mem.size : x64_type_size(t, dst.type);
u32 base;
@@ -2832,14 +2832,14 @@ static void x64_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr,
}
static void x64_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src,
- MemAccess mem, MemOrder mo) {
+ MemAccess mem, CfreeCgMemOrder mo) {
X64NativeTarget* a = x64_of(t);
MCEmitter* mc = t->mc;
u32 sz = mem.size ? mem.size : x64_type_size(t, src.type);
int w = sz == 8u ? 1 : 0;
u32 base = x64_atomic_base(a, addr);
u32 sr = loc_reg(src);
- if (mo == MO_SEQ_CST) {
+ if (mo == CFREE_CG_MO_SEQ_CST) {
/* xchg [mem], r11 implicitly fences. Stage src in rax (r11 holds base). */
if (sr != X64_RAX) emit_mov_rr(mc, w, X64_RAX, sr);
emit_lock_prefix(mc);
@@ -2854,9 +2854,9 @@ static void x64_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src,
emit_mov_store(mc, sz, sr, base, 0);
}
-static void x64_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
+static void x64_atomic_rmw(NativeTarget* t, CfreeCgAtomicOp op, NativeLoc dst,
NativeAddr addr, NativeLoc val, MemAccess mem,
- MemOrder mo) {
+ CfreeCgMemOrder mo) {
X64NativeTarget* a = x64_of(t);
MCEmitter* mc = t->mc;
u32 sz = mem.size ? mem.size : x64_type_size(t, dst.type);
@@ -2874,8 +2874,8 @@ static void x64_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
}
/* val staged in rdx (rax/rcx used by the cmpxchg loop). */
emit_mov_rr(mc, w, X64_RDX, vr);
- if (op == AO_ADD || op == AO_SUB) {
- if (op == AO_SUB) emit_f7_rm(mc, w, X64_F7_SUB_NEG, X64_RDX);
+ if (op == CFREE_CG_ATOMIC_ADD || op == CFREE_CG_ATOMIC_SUB) {
+ if (op == CFREE_CG_ATOMIC_SUB) emit_f7_rm(mc, w, X64_F7_SUB_NEG, X64_RDX);
emit_lock_prefix(mc);
emit_rex(mc, w, X64_RDX, 0, base);
{
@@ -2886,7 +2886,7 @@ static void x64_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
if (dr != X64_RDX) emit_mov_rr(mc, w, dr, X64_RDX);
return;
}
- if (op == AO_XCHG) {
+ if (op == CFREE_CG_ATOMIC_XCHG) {
emit_lock_prefix(mc);
emit_rex(mc, w, X64_RDX, 0, base);
{
@@ -2904,10 +2904,10 @@ static void x64_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
mc->label_place(mc, retry);
emit_mov_rr(mc, w, X64_RCX, X64_RAX);
switch (op) {
- case AO_AND: emit_alu_rr(mc, w, X64_OPC_ALU_AND, X64_RCX, X64_RDX); break;
- case AO_OR: emit_alu_rr(mc, w, X64_OPC_ALU_OR, X64_RCX, X64_RDX); break;
- case AO_XOR: emit_alu_rr(mc, w, X64_OPC_ALU_XOR, X64_RCX, X64_RDX); break;
- case AO_NAND:
+ case CFREE_CG_ATOMIC_AND: emit_alu_rr(mc, w, X64_OPC_ALU_AND, X64_RCX, X64_RDX); break;
+ case CFREE_CG_ATOMIC_OR: emit_alu_rr(mc, w, X64_OPC_ALU_OR, X64_RCX, X64_RDX); break;
+ case CFREE_CG_ATOMIC_XOR: emit_alu_rr(mc, w, X64_OPC_ALU_XOR, X64_RCX, X64_RDX); break;
+ case CFREE_CG_ATOMIC_NAND:
emit_alu_rr(mc, w, X64_OPC_ALU_AND, X64_RCX, X64_RDX);
emit_f7_rm(mc, w, X64_F7_SUB_NOT, X64_RCX);
break;
@@ -2927,7 +2927,7 @@ static void x64_atomic_rmw(NativeTarget* t, AtomicOp op, NativeLoc dst,
static void x64_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
NativeAddr addr, NativeLoc expected, NativeLoc desired,
- MemAccess mem, MemOrder success, MemOrder failure) {
+ MemAccess mem, CfreeCgMemOrder success, CfreeCgMemOrder failure) {
X64NativeTarget* a = x64_of(t);
MCEmitter* mc = t->mc;
u32 sz = mem.size ? mem.size : x64_type_size(t, prior.type);
@@ -2976,8 +2976,8 @@ static void x64_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok,
if (rprior != X64_RAX) emit_mov_rr(mc, w, rprior, X64_RAX);
}
-static void x64_fence(NativeTarget* t, MemOrder mo) {
- if (mo == MO_SEQ_CST) emit_mfence(t->mc);
+static void x64_fence(NativeTarget* t, CfreeCgMemOrder mo) {
+ if (mo == CFREE_CG_MO_SEQ_CST) emit_mfence(t->mc);
}
/* ============================ variadics ============================
diff --git a/src/cg/atomic.c b/src/cg/atomic.c
@@ -51,7 +51,7 @@ void cfree_cg_atomic_load(CfreeCg* g, CfreeCgMemAccess access,
rr = api_alloc_temp_local(g, val_ty);
dst = api_op_local(rr, val_ty);
g->target->atomic_load(g->target, dst, addr, api_mem_for_atomic(g, val_ty),
- api_map_mem_order(order));
+ order);
api_release(g, &ptr);
api_push(g, api_make_sv(dst, val_ty));
}
@@ -73,7 +73,7 @@ void cfree_cg_atomic_store(CfreeCg* g, CfreeCgMemAccess access,
addr = api_force_local(g, &ptr, pty);
src = api_sv_op_is_local_or_imm(&val) ? val.op : api_force_local(g, &val, val_ty);
g->target->atomic_store(g->target, addr, src, api_mem_for_atomic(g, val_ty),
- api_map_mem_order(order));
+ order);
api_release(g, &val);
api_release(g, &ptr);
}
@@ -97,9 +97,9 @@ void cfree_cg_atomic_rmw(CfreeCg* g, CfreeCgMemAccess access,
vop = api_sv_op_is_local_or_imm(&val) ? val.op : api_force_local(g, &val, val_ty);
rr = api_alloc_temp_local(g, val_ty);
dst = api_op_local(rr, val_ty);
- g->target->atomic_rmw(g->target, api_map_atomic_op(op), dst, addr, vop,
+ g->target->atomic_rmw(g->target, op, dst, addr, vop,
api_mem_for_atomic(g, val_ty),
- api_map_mem_order(order));
+ order);
api_release(g, &val);
api_release(g, &ptr);
api_push(g, api_make_sv(dst, val_ty));
@@ -140,7 +140,7 @@ void cfree_cg_atomic_cmpxchg(CfreeCg* g, CfreeCgMemAccess access,
ok = api_op_local(kr, bool_ty);
g->target->atomic_cas(g->target, prior, ok, addr, exp_op, des_op,
api_mem_for_atomic(g, val_ty),
- api_map_mem_order(success), api_map_mem_order(failure));
+ success, failure);
api_release(g, &desired);
api_release(g, &expected);
api_release(g, &ptr);
@@ -151,7 +151,7 @@ void cfree_cg_atomic_cmpxchg(CfreeCg* g, CfreeCgMemAccess access,
void cfree_cg_atomic_fence(CfreeCg* g, CfreeCgMemOrder order) {
if (!g) return;
api_local_const_memory_boundary(g);
- g->target->fence(g->target, api_map_mem_order(order));
+ g->target->fence(g->target, order);
}
/* ============================================================
diff --git a/src/cg/cgtarget.h b/src/cg/cgtarget.h
@@ -92,28 +92,12 @@ typedef enum ConvKind {
CV_BITCAST,
} ConvKind;
-typedef enum AtomicOp {
- AO_XCHG,
- AO_ADD,
- AO_SUB,
- AO_AND,
- AO_OR,
- AO_XOR,
- AO_NAND,
-} AtomicOp;
-
-/* Memory orders. Which orders are legal depends on the atomic op: load excludes
- * release/acq_rel; store excludes acquire/consume/acq_rel; CAS failure order is
- * one of relaxed/consume/acquire/seq_cst and no stronger than success. See the
- * Atomics edge-case rules in doc/IR.md (mirrored by cfree_cg_atomic_is_legal). */
-typedef enum MemOrder {
- MO_RELAXED,
- MO_CONSUME,
- MO_ACQUIRE,
- MO_RELEASE,
- MO_ACQ_REL,
- MO_SEQ_CST,
-} MemOrder;
+/* Atomic op kinds (CfreeCgAtomicOp) and memory orders (CfreeCgMemOrder) come
+ * straight from the public API. Which orders are legal depends on the atomic
+ * op: load excludes release/acq_rel; store excludes acquire/consume/acq_rel;
+ * CAS failure order is one of relaxed/consume/acquire/seq_cst and no stronger
+ * than success. See the Atomics edge-case rules in doc/IR.md (mirrored by
+ * cfree_cg_atomic_is_legal). */
/* Compiler-intrinsic kinds dispatched through CgTarget.intrinsic and carried
* on IR_INTRINSIC via IRIntrinAux.kind. The set is bounded: a backend
@@ -639,16 +623,17 @@ struct CgTarget {
/* ---- atomics ---- */
void (*atomic_load)(CgTarget*, Operand dst /*LOCAL*/, Operand addr, MemAccess,
- MemOrder);
+ CfreeCgMemOrder);
void (*atomic_store)(CgTarget*, Operand addr, Operand src, MemAccess,
- MemOrder);
- void (*atomic_rmw)(CgTarget*, AtomicOp, Operand dst /*LOCAL: prior value*/,
- Operand addr, Operand val, MemAccess, MemOrder);
+ CfreeCgMemOrder);
+ void (*atomic_rmw)(CgTarget*, CfreeCgAtomicOp,
+ Operand dst /*LOCAL: prior value*/, Operand addr,
+ Operand val, MemAccess, CfreeCgMemOrder);
void (*atomic_cas)(CgTarget*, Operand prior /*LOCAL*/,
Operand ok /*LOCAL, i1*/, Operand addr, Operand expected,
- Operand desired, MemAccess, MemOrder success,
- MemOrder failure);
- void (*fence)(CgTarget*, MemOrder);
+ Operand desired, MemAccess, CfreeCgMemOrder success,
+ CfreeCgMemOrder failure);
+ void (*fence)(CgTarget*, CfreeCgMemOrder);
/* ---- compiler intrinsics ----
* Typed dispatch for builtins whose lowering is backend-relevant
diff --git a/src/cg/internal.h b/src/cg/internal.h
@@ -428,8 +428,6 @@ UnOp api_map_int_unop(CfreeCgIntUnOp op);
CmpOp api_map_int_cmp(CfreeCgIntCmpOp op);
CmpOp api_map_fp_cmp(CfreeCgFpCmpOp op);
CmpOp api_invert_cmp(CmpOp op);
-AtomicOp api_map_atomic_op(CfreeCgAtomicOp op);
-MemOrder api_map_mem_order(CfreeCgMemOrder order);
u32 api_int_like_width(Compiler* c, CfreeCgTypeId id);
int api_type_is_bool(Compiler* c, CfreeCgTypeId id);
u64 api_width_mask(u32 width);
diff --git a/src/cg/ir.h b/src/cg/ir.h
@@ -153,9 +153,9 @@ typedef struct CgIrScopeAux {
typedef struct CgIrAtomicAux {
MemAccess mem;
- MemOrder order;
- AtomicOp op;
- MemOrder failure;
+ CfreeCgMemOrder order;
+ CfreeCgAtomicOp op;
+ CfreeCgMemOrder failure;
} CgIrAtomicAux;
typedef struct CgIrAsmAux {
diff --git a/src/cg/ir_recorder.c b/src/cg/ir_recorder.c
@@ -461,7 +461,7 @@ static void rec_va_copy(CgTarget* t, Operand dst_ap_addr, Operand src_ap_addr) {
}
static void rec_atomic_load(CgTarget* t, Operand dst, Operand addr,
- MemAccess mem, MemOrder order) {
+ MemAccess mem, CfreeCgMemOrder order) {
CgIrRecorder* r = rec_of(t);
CgIrInst* in = emit(r, CG_IR_ATOMIC_LOAD);
CgIrAtomicAux* aux = AUX_NEW(r, CgIrAtomicAux);
@@ -473,7 +473,7 @@ static void rec_atomic_load(CgTarget* t, Operand dst, Operand addr,
}
static void rec_atomic_store(CgTarget* t, Operand addr, Operand src,
- MemAccess mem, MemOrder order) {
+ MemAccess mem, CfreeCgMemOrder order) {
CgIrRecorder* r = rec_of(t);
CgIrInst* in = emit(r, CG_IR_ATOMIC_STORE);
CgIrAtomicAux* aux = AUX_NEW(r, CgIrAtomicAux);
@@ -484,8 +484,8 @@ static void rec_atomic_store(CgTarget* t, Operand addr, Operand src,
in->extra.aux = aux;
}
-static void rec_atomic_rmw(CgTarget* t, AtomicOp op, Operand dst, Operand addr,
- Operand val, MemAccess mem, MemOrder order) {
+static void rec_atomic_rmw(CgTarget* t, CfreeCgAtomicOp op, Operand dst, Operand addr,
+ Operand val, MemAccess mem, CfreeCgMemOrder order) {
CgIrRecorder* r = rec_of(t);
CgIrInst* in = emit(r, CG_IR_ATOMIC_RMW);
CgIrAtomicAux* aux = AUX_NEW(r, CgIrAtomicAux);
@@ -499,7 +499,7 @@ static void rec_atomic_rmw(CgTarget* t, AtomicOp op, Operand dst, Operand addr,
static void rec_atomic_cas(CgTarget* t, Operand prior, Operand ok, Operand addr,
Operand expected, Operand desired, MemAccess mem,
- MemOrder success, MemOrder failure) {
+ CfreeCgMemOrder success, CfreeCgMemOrder failure) {
CgIrRecorder* r = rec_of(t);
CgIrInst* in = emit(r, CG_IR_ATOMIC_CAS);
CgIrAtomicAux* aux = AUX_NEW(r, CgIrAtomicAux);
@@ -511,7 +511,7 @@ static void rec_atomic_cas(CgTarget* t, Operand prior, Operand ok, Operand addr,
in->extra.aux = aux;
}
-static void rec_fence(CgTarget* t, MemOrder order) {
+static void rec_fence(CgTarget* t, CfreeCgMemOrder order) {
CgIrInst* in = emit(rec_of(t), CG_IR_FENCE);
in->extra.imm = (i64)order;
}
diff --git a/src/cg/native_direct_target.c b/src/cg/native_direct_target.c
@@ -1580,7 +1580,7 @@ static void nd_va_copy(CgTarget* t, Operand dst_ap_addr, Operand src_ap_addr) {
}
static void nd_atomic_load(CgTarget* t, Operand dst, Operand addr,
- MemAccess mem, MemOrder order) {
+ MemAccess mem, CfreeCgMemOrder order) {
NativeDirectTarget* d = nd_of(t);
NdAddrTemps temps;
nd_flush_all(d);
@@ -1596,7 +1596,7 @@ static void nd_atomic_load(CgTarget* t, Operand dst, Operand addr,
}
static void nd_atomic_store(CgTarget* t, Operand addr, Operand src,
- MemAccess mem, MemOrder order) {
+ MemAccess mem, CfreeCgMemOrder order) {
NativeDirectTarget* d = nd_of(t);
NdAddrTemps temps;
nd_flush_all(d);
@@ -1610,8 +1610,8 @@ static void nd_atomic_store(CgTarget* t, Operand addr, Operand src,
nd_addr_temps_release(d, &temps);
}
-static void nd_atomic_rmw(CgTarget* t, AtomicOp op, Operand dst, Operand addr,
- Operand val, MemAccess mem, MemOrder order) {
+static void nd_atomic_rmw(CgTarget* t, CfreeCgAtomicOp op, Operand dst, Operand addr,
+ Operand val, MemAccess mem, CfreeCgMemOrder order) {
NativeDirectTarget* d = nd_of(t);
NdAddrTemps temps;
nd_flush_all(d);
@@ -1630,7 +1630,7 @@ static void nd_atomic_rmw(CgTarget* t, AtomicOp op, Operand dst, Operand addr,
static void nd_atomic_cas(CgTarget* t, Operand prior, Operand ok, Operand addr,
Operand expected, Operand desired, MemAccess mem,
- MemOrder success, MemOrder failure) {
+ CfreeCgMemOrder success, CfreeCgMemOrder failure) {
NativeDirectTarget* d = nd_of(t);
NdAddrTemps temps;
nd_flush_all(d);
@@ -1654,7 +1654,7 @@ static void nd_atomic_cas(CgTarget* t, Operand prior, Operand ok, Operand addr,
nd_addr_temps_release(d, &temps);
}
-static void nd_fence(CgTarget* t, MemOrder order) {
+static void nd_fence(CgTarget* t, CfreeCgMemOrder order) {
NativeDirectTarget* d = nd_of(t);
nd_flush_all(d);
ND_REQUIRE_NATIVE(d, fence, "target does not emit fences");
diff --git a/src/cg/value.c b/src/cg/value.c
@@ -701,43 +701,6 @@ CmpOp api_invert_cmp(CmpOp op) {
return CMP_EQ;
}
-AtomicOp api_map_atomic_op(CfreeCgAtomicOp op) {
- switch (op) {
- case CFREE_CG_ATOMIC_XCHG:
- return AO_XCHG;
- case CFREE_CG_ATOMIC_ADD:
- return AO_ADD;
- case CFREE_CG_ATOMIC_SUB:
- return AO_SUB;
- case CFREE_CG_ATOMIC_AND:
- return AO_AND;
- case CFREE_CG_ATOMIC_OR:
- return AO_OR;
- case CFREE_CG_ATOMIC_XOR:
- return AO_XOR;
- case CFREE_CG_ATOMIC_NAND:
- return AO_NAND;
- }
- return AO_XCHG;
-}
-
-MemOrder api_map_mem_order(CfreeCgMemOrder order) {
- switch (order) {
- case CFREE_CG_MO_RELAXED:
- return MO_RELAXED;
- case CFREE_CG_MO_CONSUME:
- return MO_CONSUME;
- case CFREE_CG_MO_ACQUIRE:
- return MO_ACQUIRE;
- case CFREE_CG_MO_RELEASE:
- return MO_RELEASE;
- case CFREE_CG_MO_ACQ_REL:
- return MO_ACQ_REL;
- case CFREE_CG_MO_SEQ_CST:
- return MO_SEQ_CST;
- }
- return MO_RELAXED;
-}
/* ---- immediate integer folding ---- */
diff --git a/src/interp/engine.c b/src/interp/engine.c
@@ -416,14 +416,14 @@ static u64 do_convert(InterpStack* st, InterpInsn* in, u64 v) {
}
static u64 do_rmw(u32 op, u64 old, u64 val, u32 w) {
- switch ((AtomicOp)op) {
- case AO_XCHG: return mask_w(val, w);
- case AO_ADD: return mask_w(old + val, w);
- case AO_SUB: return mask_w(old - val, w);
- case AO_AND: return mask_w(old & val, w);
- case AO_OR: return mask_w(old | val, w);
- case AO_XOR: return mask_w(old ^ val, w);
- case AO_NAND: return mask_w(~(old & val), w);
+ switch ((CfreeCgAtomicOp)op) {
+ case CFREE_CG_ATOMIC_XCHG: return mask_w(val, w);
+ case CFREE_CG_ATOMIC_ADD: return mask_w(old + val, w);
+ case CFREE_CG_ATOMIC_SUB: return mask_w(old - val, w);
+ case CFREE_CG_ATOMIC_AND: return mask_w(old & val, w);
+ case CFREE_CG_ATOMIC_OR: return mask_w(old | val, w);
+ case CFREE_CG_ATOMIC_XOR: return mask_w(old ^ val, w);
+ case CFREE_CG_ATOMIC_NAND: return mask_w(~(old & val), w);
default: return old;
}
}
diff --git a/src/interp/interp.h b/src/interp/interp.h
@@ -73,7 +73,7 @@ typedef struct InterpInsn {
void* handler; /* reserved: &&label for direct threading */
const Inst* inst; /* source instruction (arena-resident, c->tu lifetime) */
u32 op; /* InterpOp */
- u32 sub; /* sub-op tag: BinOp/UnOp/CmpOp/ConvKind/AtomicOp/MemOrder */
+ u32 sub; /* sub-op tag: BinOp/UnOp/CmpOp/ConvKind/CfreeCgAtomicOp/CfreeCgMemOrder */
u32 dst; /* dest PReg id (cache of opnds[0].v.reg); 0 if none */
u32 t0; /* resolved pc of succ[0] / switch-table index / src reg */
u32 t1; /* resolved pc of succ[1] */
diff --git a/src/opt/ir.h b/src/opt/ir.h
@@ -311,7 +311,7 @@ typedef enum IROp {
IR_ATOMIC_STORE, /* opnds = [addr, src]; extra.aux = IRAtomicAux */
IR_ATOMIC_RMW, /* opnds = [dst, addr, val]; extra.aux */
IR_ATOMIC_CAS, /* defs = [prior, ok] OPK_REG ids; extra.aux = IRCasAux */
- IR_FENCE, /* extra.imm = MemOrder */
+ IR_FENCE, /* extra.imm = CfreeCgMemOrder */
/* Inline asm. extra.aux = IRAsmAux. */
IR_ASM_BLOCK,
@@ -415,14 +415,14 @@ typedef struct IRScopeAux {
typedef struct IRAtomicAux {
MemAccess mem;
- MemOrder mo;
- u8 op; /* AtomicOp; valid for IR_ATOMIC_RMW */
+ CfreeCgMemOrder mo;
+ u8 op; /* CfreeCgAtomicOp; valid for IR_ATOMIC_RMW */
} IRAtomicAux;
typedef struct IRCasAux {
MemAccess mem;
- MemOrder success;
- MemOrder failure;
+ CfreeCgMemOrder success;
+ CfreeCgMemOrder failure;
} IRCasAux;
typedef struct IRAsmAux {
diff --git a/src/opt/pass_native_emit.c b/src/opt/pass_native_emit.c
@@ -1111,7 +1111,7 @@ static void emit_inst(NativeEmitCtx* e, u32 block, u32 order_index, Inst* in,
dst = scratch_loc(e, in->opnds[0].type,
class_for_type(e, in->opnds[0].type), src.v.reg,
REG_NONE, in->loc);
- e->target->atomic_rmw(e->target, (AtomicOp)aux->op, dst, addr, src,
+ e->target->atomic_rmw(e->target, (CfreeCgAtomicOp)aux->op, dst, addr, src,
aux->mem, aux->mo);
if (in->opnds[0].kind != OPK_REG)
write_loc(e, loc_from_operand(e, &in->opnds[0], in->loc), dst, aux->mem,
@@ -1217,7 +1217,7 @@ static void emit_inst(NativeEmitCtx* e, u32 block, u32 order_index, Inst* in,
case IR_CONTINUE_TO:
emit_panic(e, in->loc, "operation is not wired to NativeTarget yet");
case IR_FENCE:
- e->target->fence(e->target, (MemOrder)in->extra.imm);
+ e->target->fence(e->target, (CfreeCgMemOrder)in->extra.imm);
return;
case IR_INTRINSIC: {
IRIntrinAux* aux = (IRIntrinAux*)in->extra.aux;