port @atomicLoad, @atomicRmw, @atomicStore, @cmpxchgStrong, @cmpxchgWeak builtins to astgen.c

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 10:12:29 +00:00
parent 84a9758a49
commit 1fd2451007
2 changed files with 99 additions and 1 deletions

View File

@@ -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;

View File

@@ -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") },