diff --git a/stage0/astgen.c b/stage0/astgen.c index 70857073ff..ec0db7b0d3 100644 --- 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 index f3dbd2207f..e0f8ab3c99 100644 --- 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") },