commit 1fd2451007ddd509ae18dbc6a23ca6bcd5542451 (tree)
parent 84a9758a49cbf9bd42e85231ffb83bd130b40db8
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Mon, 16 Feb 2026 10:12:29 +0000
port @atomicLoad, @atomicRmw, @atomicStore, @cmpxchgStrong, @cmpxchgWeak builtins to astgen.c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/stage0/astgen.c b/stage0/astgen.c
@@ -5195,6 +5195,104 @@ static uint32_t builtinCallMultiArg(GenZir* gz, Scope* scope, ResultLoc rl,
}
// clang-format on
+ // @atomicLoad — AstGen.zig:9555-9564.
+ // clang-format off
+ if (name_len == 10 && memcmp(source + name_start, "atomicLoad", 10) == 0
+ && param_count == 3) {
+ uint32_t atomic_order_type
+ = addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_ATOMIC_ORDER);
+ uint32_t elem_type = typeExpr(gz, scope, params[0]);
+ uint32_t ptr = expr(gz, scope, params[1]);
+ ResultLoc ord_rl = { .tag = RL_COERCED_TY,
+ .data = atomic_order_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t ordering = exprRl(gz, scope, ord_rl, params[2]);
+ uint32_t result = addPlNodeTriple(
+ gz, ZIR_INST_ATOMIC_LOAD, node, elem_type, ptr, ordering);
+ return rvalue(gz, rl, result, node);
+ }
+ // clang-format on
+
+ // @atomicRmw — AstGen.zig:9566-9578.
+ // clang-format off
+ if (name_len == 9 && memcmp(source + name_start, "atomicRmw", 9) == 0
+ && param_count == 5) {
+ uint32_t atomic_order_type
+ = addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_ATOMIC_ORDER);
+ uint32_t atomic_rmw_op_type
+ = addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_ATOMIC_RMW_OP);
+ uint32_t int_type = typeExpr(gz, scope, params[0]);
+ uint32_t ptr = expr(gz, scope, params[1]);
+ ResultLoc op_rl = { .tag = RL_COERCED_TY,
+ .data = atomic_rmw_op_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t operation = exprRl(gz, scope, op_rl, params[2]);
+ ResultLoc operand_rl = { .tag = RL_TY,
+ .data = int_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t operand = exprRl(gz, scope, operand_rl, params[3]);
+ ResultLoc ord_rl = { .tag = RL_COERCED_TY,
+ .data = atomic_order_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t ordering = exprRl(gz, scope, ord_rl, params[4]);
+ uint32_t result = addPlNodeQuad(
+ gz, ZIR_INST_ATOMIC_RMW, node, ptr, operation, operand, ordering);
+ return rvalue(gz, rl, result, node);
+ }
+ // clang-format on
+
+ // @atomicStore — AstGen.zig:9580-9591.
+ // clang-format off
+ if (name_len == 11 && memcmp(source + name_start, "atomicStore", 11) == 0
+ && param_count == 4) {
+ uint32_t atomic_order_type
+ = addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_ATOMIC_ORDER);
+ uint32_t int_type = typeExpr(gz, scope, params[0]);
+ uint32_t ptr = expr(gz, scope, params[1]);
+ ResultLoc operand_rl = { .tag = RL_TY,
+ .data = int_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t operand = exprRl(gz, scope, operand_rl, params[2]);
+ ResultLoc ord_rl = { .tag = RL_COERCED_TY,
+ .data = atomic_order_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t ordering = exprRl(gz, scope, ord_rl, params[3]);
+ addPlNodeTriple(
+ gz, ZIR_INST_ATOMIC_STORE, node, ptr, operand, ordering);
+ return rvalue(gz, rl, ZIR_REF_VOID_VALUE, node);
+ }
+ // clang-format on
+
+ // @cmpxchgStrong / @cmpxchgWeak — AstGen.zig:9496-9497, 9884-9905.
+ // clang-format off
+ if (param_count == 6
+ && ((name_len == 13 && memcmp(source + name_start, "cmpxchgStrong", 13) == 0)
+ || (name_len == 11 && memcmp(source + name_start, "cmpxchgWeak", 11) == 0))) {
+ uint16_t small = (name_len == 13) ? 1 : 0; // strong=1, weak=0
+ uint32_t int_type = typeExpr(gz, scope, params[0]);
+ uint32_t atomic_order_type
+ = addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_ATOMIC_ORDER);
+ uint32_t ptr = expr(gz, scope, params[1]);
+ ResultLoc ty_rl = { .tag = RL_TY,
+ .data = int_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t expected_value = exprRl(gz, scope, ty_rl, params[2]);
+ ResultLoc coerced_rl = { .tag = RL_COERCED_TY,
+ .data = int_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t new_value = exprRl(gz, scope, coerced_rl, params[3]);
+ ResultLoc ord_rl = { .tag = RL_COERCED_TY,
+ .data = atomic_order_type, .src_node = 0, .ctx = RI_CTX_NONE };
+ uint32_t success_order = exprRl(gz, scope, ord_rl, params[4]);
+ uint32_t failure_order = exprRl(gz, scope, ord_rl, params[5]);
+ // Cmpxchg payload: node_offset, ptr, expected, new, success, failure.
+ ensureExtraCapacity(ag, 6);
+ uint32_t payload_index = ag->extra_len;
+ ag->extra[ag->extra_len++]
+ = (uint32_t)((int32_t)node - (int32_t)gz->decl_node_index);
+ ag->extra[ag->extra_len++] = ptr;
+ ag->extra[ag->extra_len++] = expected_value;
+ ag->extra[ag->extra_len++] = new_value;
+ ag->extra[ag->extra_len++] = success_order;
+ ag->extra[ag->extra_len++] = failure_order;
+ uint32_t result = addExtendedPayloadSmall(
+ gz, (uint16_t)ZIR_EXT_CMPXCHG, small, payload_index);
+ return rvalue(gz, rl, result, node);
+ }
+ // clang-format on
+
// TODO: handle other multi-arg builtins.
SET_ERROR(ag);
return ZIR_REF_VOID_VALUE;
diff --git a/stage0/astgen_test.zig b/stage0/astgen_test.zig
@@ -1217,7 +1217,7 @@ const corpus_files = .{
.{ "align.zig", @embedFile("../test/behavior/align.zig") },
.{ "alignof.zig", @embedFile("../test/behavior/alignof.zig") },
.{ "asm.zig", @embedFile("../test/behavior/asm.zig") },
- //.{ "atomics.zig", @embedFile("../test/behavior/atomics.zig") },
+ .{ "atomics.zig", @embedFile("../test/behavior/atomics.zig") },
.{ "bitcast.zig", @embedFile("../test/behavior/bitcast.zig") },
.{ "bitreverse.zig", @embedFile("../test/behavior/bitreverse.zig") },
.{ "bit_shifting.zig", @embedFile("../test/behavior/bit_shifting.zig") },