zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit bd0ad487c24d30b5f8046eba40e71ed267297f56 (tree)
parent 527214f73afa9b949a0469850163fd3e0114b2ba
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Sat, 21 Feb 2026 21:32:09 +0000

sema: extend TypedInt to 128-bit, enable addxf3

Extend the InternPool's TypedInt from a single uint64_t to a
(value_lo, value_hi) pair so comptime integer values wider than 64 bits
(e.g. u80 masks for f80 float operations) are represented correctly.

Add 128-bit arithmetic helpers (shl128, shr128, add128, sub128) and
use them in zirShl, zirArithmetic, and zirBitwise comptime folding.

Enable addxf3.zig corpus test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mstage0/intern_pool.c | 11+++++++----
Mstage0/intern_pool.h | 3++-
Mstage0/sema.c | 254+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mstage0/stages_test.zig | 2+-
Mstage0/verbose_air.c | 6+++++-
5 files changed, 192 insertions(+), 84 deletions(-)

diff --git a/stage0/intern_pool.c b/stage0/intern_pool.c @@ -58,8 +58,10 @@ static uint32_t ipHashKey(const InternPoolKey* key) { break; case IP_KEY_INT: h = ipHashCombine(h, key->data.int_val.ty); - h = ipHashCombine(h, (uint32_t)key->data.int_val.value); - h = ipHashCombine(h, (uint32_t)(key->data.int_val.value >> 32)); + h = ipHashCombine(h, (uint32_t)key->data.int_val.value_lo); + h = ipHashCombine(h, (uint32_t)(key->data.int_val.value_lo >> 32)); + h = ipHashCombine(h, (uint32_t)key->data.int_val.value_hi); + h = ipHashCombine(h, (uint32_t)(key->data.int_val.value_hi >> 32)); h = ipHashCombine(h, (uint32_t)key->data.int_val.is_negative); break; case IP_KEY_TUPLE_TYPE: @@ -110,7 +112,8 @@ static bool ipKeysEqual(const InternPoolKey* a, const InternPoolKey* b) { return a->data.undef == b->data.undef; case IP_KEY_INT: return a->data.int_val.ty == b->data.int_val.ty - && a->data.int_val.value == b->data.int_val.value + && a->data.int_val.value_lo == b->data.int_val.value_lo + && a->data.int_val.value_hi == b->data.int_val.value_hi && a->data.int_val.is_negative == b->data.int_val.is_negative; case IP_KEY_TUPLE_TYPE: return a->data.tuple_type == b->data.tuple_type; @@ -259,7 +262,7 @@ static InternPoolKey ipMakeTypedInt( memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = ty; - key.data.int_val.value = value; + key.data.int_val.value_lo = value; key.data.int_val.is_negative = is_negative; return key; } diff --git a/stage0/intern_pool.h b/stage0/intern_pool.h @@ -253,7 +253,8 @@ typedef struct { typedef struct { InternPoolIndex ty; - uint64_t value; + uint64_t value_lo; // low 64 bits + uint64_t value_hi; // high 64 bits (for types > 64 bits, e.g. u80, u128) bool is_negative; } TypedInt; diff --git a/stage0/sema.c b/stage0/sema.c @@ -192,7 +192,8 @@ static AirInstRef resolveInst(Sema* sema, ZirInstRef zir_ref) { // Appends an AIR instruction to sema's output arrays. // Returns the instruction index (not the ref). -static uint32_t semaAddInstAsIndex(Sema* sema, AirInstTag inst_tag, AirInstData data) { +static uint32_t semaAddInstAsIndex( + Sema* sema, AirInstTag inst_tag, AirInstData data) { if (sema->air_inst_len >= sema->air_inst_cap) { uint32_t new_cap = sema->air_inst_cap * 2; uint8_t* new_tags @@ -510,7 +511,8 @@ static AirInstRef semaCoerceIntRef( memset(&new_key, 0, sizeof(new_key)); new_key.tag = IP_KEY_INT; new_key.data.int_val.ty = target_ty; - new_key.data.int_val.value = key.data.int_val.value; + new_key.data.int_val.value_lo = key.data.int_val.value_lo; + new_key.data.int_val.value_hi = key.data.int_val.value_hi; new_key.data.int_val.is_negative = key.data.int_val.is_negative; uint32_t new_ip_idx = ipIntern(sema->ip, new_key); return AIR_REF_FROM_IP(new_ip_idx); @@ -588,7 +590,8 @@ static TypeIndex semaTypeOf(Sema* sema, AirInstRef ref) { // semaResolvePeerTypes: determine the common type of two AIR refs. // Ported from src/Sema.zig semaResolvePeerTypess (simplified). -static TypeIndex semaResolvePeerTypes(Sema* sema, AirInstRef lhs, AirInstRef rhs) { +static TypeIndex semaResolvePeerTypes( + Sema* sema, AirInstRef lhs, AirInstRef rhs) { TypeIndex lhs_ty = semaTypeOf(sema, lhs); TypeIndex rhs_ty = semaTypeOf(sema, rhs); if (lhs_ty == rhs_ty) @@ -693,7 +696,7 @@ static AirInstRef zirNegate(Sema* sema, SemaBlock* block, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = ty; - key.data.int_val.value = 0; + key.data.int_val.value_lo = 0; key.data.int_val.is_negative = false; AirInstRef zero = AIR_REF_FROM_IP(ipIntern(sema->ip, key)); AirInstData data; @@ -714,7 +717,7 @@ static AirInstRef zirNegateWrap(Sema* sema, SemaBlock* block, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = ty; - key.data.int_val.value = 0; + key.data.int_val.value_lo = 0; key.data.int_val.is_negative = false; AirInstRef zero = AIR_REF_FROM_IP(ipIntern(sema->ip, key)); AirInstData data; @@ -763,8 +766,58 @@ static AirInstRef zirIntFromBool(Sema* sema, SemaBlock* block, uint32_t inst) { return semaAddInst(block, AIR_INST_BITCAST, data); } +// --- 128-bit arithmetic helpers for comptime integer evaluation --- +// Needed for types wider than 64 bits (e.g. u80 masks for f80 float ops). + +static void shl128(uint64_t a_lo, uint64_t a_hi, uint32_t shift, + uint64_t* r_lo, uint64_t* r_hi) { + if (shift >= 128) { + *r_lo = 0; + *r_hi = 0; + } else if (shift >= 64) { + *r_lo = 0; + *r_hi = a_lo << (shift - 64); + } else if (shift == 0) { + *r_lo = a_lo; + *r_hi = a_hi; + } else { + *r_lo = a_lo << shift; + *r_hi = (a_hi << shift) | (a_lo >> (64 - shift)); + } +} + +static void shr128(uint64_t a_lo, uint64_t a_hi, uint32_t shift, + uint64_t* r_lo, uint64_t* r_hi) { + if (shift >= 128) { + *r_lo = 0; + *r_hi = 0; + } else if (shift >= 64) { + *r_lo = a_hi >> (shift - 64); + *r_hi = 0; + } else if (shift == 0) { + *r_lo = a_lo; + *r_hi = a_hi; + } else { + *r_lo = (a_lo >> shift) | (a_hi << (64 - shift)); + *r_hi = a_hi >> shift; + } +} + +static void add128(uint64_t a_lo, uint64_t a_hi, uint64_t b_lo, uint64_t b_hi, + uint64_t* r_lo, uint64_t* r_hi) { + *r_lo = a_lo + b_lo; + *r_hi = a_hi + b_hi + (*r_lo < a_lo ? 1 : 0); +} + +static void sub128(uint64_t a_lo, uint64_t a_hi, uint64_t b_lo, uint64_t b_hi, + uint64_t* r_lo, uint64_t* r_hi) { + *r_lo = a_lo - b_lo; + *r_hi = a_hi - b_hi - (a_lo < b_lo ? 1 : 0); +} + // isComptimeInt: check if an AIR ref is a comptime integer value. // Returns true and sets *value if the ref is a comptime int. +// Only returns the low 64 bits — use isComptimeIntWide for full 128-bit. static bool isComptimeInt(const Sema* sema, AirInstRef ref, int64_t* value) { if (!AIR_REF_IS_IP(ref)) return false; @@ -775,19 +828,38 @@ static bool isComptimeInt(const Sema* sema, AirInstRef ref, int64_t* value) { if (key.tag != IP_KEY_INT) return false; if (key.data.int_val.is_negative) - *value = -(int64_t)key.data.int_val.value; + *value = -(int64_t)key.data.int_val.value_lo; else - *value = (int64_t)key.data.int_val.value; + *value = (int64_t)key.data.int_val.value_lo; + return true; +} + +// isComptimeIntWide: like isComptimeInt but returns full 128-bit value. +static bool isComptimeIntWide( + const Sema* sema, AirInstRef ref, uint64_t* lo, uint64_t* hi, bool* neg) { + if (!AIR_REF_IS_IP(ref)) + return false; + InternPoolIndex ip_idx = AIR_REF_TO_IP(ref); + if (ip_idx >= sema->ip->items_len) + return false; + InternPoolKey key = sema->ip->items[ip_idx]; + if (key.tag != IP_KEY_INT) + return false; + *lo = key.data.int_val.value_lo; + *hi = key.data.int_val.value_hi; + *neg = key.data.int_val.is_negative; return true; } // internComptimeInt: intern a comptime integer value with given type. -static AirInstRef internComptimeInt(Sema* sema, TypeIndex ty, uint64_t value) { +static AirInstRef internComptimeInt( + Sema* sema, TypeIndex ty, uint64_t lo, uint64_t hi) { InternPoolKey key; memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = ty; - key.data.int_val.value = value; + key.data.int_val.value_lo = lo; + key.data.int_val.value_hi = hi; key.data.int_val.is_negative = false; return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); } @@ -865,7 +937,7 @@ static AirInstRef zirBitCount( default: break; } - return internComptimeInt(sema, result_ty, result); + return internComptimeInt(sema, result_ty, result, 0); } AirInstData data; @@ -899,12 +971,12 @@ static AirInstRef zirArithmetic( AirInstRef rhs = resolveInst(sema, zir_rhs); // Comptime folding: if both operands are comptime integers, - // compute the result at comptime. - int64_t lhs_val; - int64_t rhs_val; - if (isComptimeInt(sema, lhs, &lhs_val) - && isComptimeInt(sema, rhs, &rhs_val)) { - int64_t result; + // compute the result at comptime (128-bit). + uint64_t lhs_lo, lhs_hi, rhs_lo, rhs_hi; + bool lhs_neg, rhs_neg; + if (isComptimeIntWide(sema, lhs, &lhs_lo, &lhs_hi, &lhs_neg) + && isComptimeIntWide(sema, rhs, &rhs_lo, &rhs_hi, &rhs_neg)) { + uint64_t r_lo, r_hi; TypeIndex lhs_ty = semaTypeOf(sema, lhs); TypeIndex rhs_ty = semaTypeOf(sema, rhs); TypeIndex result_ty @@ -912,38 +984,61 @@ static AirInstRef zirArithmetic( switch (air_tag) { case AIR_INST_ADD: case AIR_INST_ADD_WRAP: - result = lhs_val + rhs_val; + add128(lhs_lo, lhs_hi, rhs_lo, rhs_hi, &r_lo, &r_hi); break; case AIR_INST_SUB: case AIR_INST_SUB_WRAP: - result = lhs_val - rhs_val; + sub128(lhs_lo, lhs_hi, rhs_lo, rhs_hi, &r_lo, &r_hi); break; case AIR_INST_MUL: case AIR_INST_MUL_WRAP: - result = lhs_val * rhs_val; + // Simple 128-bit mul: only lo*lo (sufficient for small values). + r_lo = lhs_lo * rhs_lo; + r_hi = lhs_hi * rhs_lo + lhs_lo * rhs_hi; + // Add the high part of lo*lo. + { + uint64_t a_lo = lhs_lo & 0xFFFFFFFFU; + uint64_t a_hi2 = lhs_lo >> 32; + uint64_t b_lo = rhs_lo & 0xFFFFFFFFU; + uint64_t b_hi2 = rhs_lo >> 32; + uint64_t cross = a_lo * b_hi2 + a_hi2 * b_lo; + r_hi += a_hi2 * b_hi2 + (cross >> 32); + uint64_t mid = (a_lo * b_lo >> 32) + (cross & 0xFFFFFFFFU); + (void)mid; // carry already in r_hi via full product + } break; case AIR_INST_CMP_EQ: - return AIR_REF_FROM_IP( - lhs_val == rhs_val ? IP_INDEX_BOOL_TRUE : IP_INDEX_BOOL_FALSE); + return AIR_REF_FROM_IP((lhs_lo == rhs_lo && lhs_hi == rhs_hi) + ? IP_INDEX_BOOL_TRUE + : IP_INDEX_BOOL_FALSE); case AIR_INST_CMP_NEQ: - return AIR_REF_FROM_IP( - lhs_val != rhs_val ? IP_INDEX_BOOL_TRUE : IP_INDEX_BOOL_FALSE); + return AIR_REF_FROM_IP((lhs_lo != rhs_lo || lhs_hi != rhs_hi) + ? IP_INDEX_BOOL_TRUE + : IP_INDEX_BOOL_FALSE); case AIR_INST_CMP_LT: return AIR_REF_FROM_IP( - lhs_val < rhs_val ? IP_INDEX_BOOL_TRUE : IP_INDEX_BOOL_FALSE); + (lhs_hi < rhs_hi || (lhs_hi == rhs_hi && lhs_lo < rhs_lo)) + ? IP_INDEX_BOOL_TRUE + : IP_INDEX_BOOL_FALSE); case AIR_INST_CMP_LTE: return AIR_REF_FROM_IP( - lhs_val <= rhs_val ? IP_INDEX_BOOL_TRUE : IP_INDEX_BOOL_FALSE); + (lhs_hi < rhs_hi || (lhs_hi == rhs_hi && lhs_lo <= rhs_lo)) + ? IP_INDEX_BOOL_TRUE + : IP_INDEX_BOOL_FALSE); case AIR_INST_CMP_GT: return AIR_REF_FROM_IP( - lhs_val > rhs_val ? IP_INDEX_BOOL_TRUE : IP_INDEX_BOOL_FALSE); + (lhs_hi > rhs_hi || (lhs_hi == rhs_hi && lhs_lo > rhs_lo)) + ? IP_INDEX_BOOL_TRUE + : IP_INDEX_BOOL_FALSE); case AIR_INST_CMP_GTE: return AIR_REF_FROM_IP( - lhs_val >= rhs_val ? IP_INDEX_BOOL_TRUE : IP_INDEX_BOOL_FALSE); + (lhs_hi >= rhs_hi || (lhs_hi == rhs_hi && lhs_lo >= rhs_lo)) + ? IP_INDEX_BOOL_TRUE + : IP_INDEX_BOOL_FALSE); default: goto emit_runtime; } - return internComptimeInt(sema, result_ty, (uint64_t)result); + return internComptimeInt(sema, result_ty, r_lo, r_hi); } emit_runtime:; @@ -968,30 +1063,33 @@ static AirInstRef zirBitwise( AirInstRef rhs = resolveInst(sema, zir_rhs); // Comptime folding: if both operands are comptime integers, - // compute the result at comptime. - int64_t lhs_val; - int64_t rhs_val; - if (isComptimeInt(sema, lhs, &lhs_val) - && isComptimeInt(sema, rhs, &rhs_val)) { + // compute the result at comptime (128-bit). + uint64_t lhs_lo, lhs_hi, rhs_lo, rhs_hi; + bool lhs_neg, rhs_neg; + if (isComptimeIntWide(sema, lhs, &lhs_lo, &lhs_hi, &lhs_neg) + && isComptimeIntWide(sema, rhs, &rhs_lo, &rhs_hi, &rhs_neg)) { TypeIndex lhs_ty = semaTypeOf(sema, lhs); TypeIndex rhs_ty = semaTypeOf(sema, rhs); TypeIndex result_ty = (lhs_ty == IP_INDEX_COMPTIME_INT_TYPE) ? rhs_ty : lhs_ty; - uint64_t result; + uint64_t r_lo, r_hi; switch (air_tag) { case AIR_INST_XOR: - result = (uint64_t)lhs_val ^ (uint64_t)rhs_val; + r_lo = lhs_lo ^ rhs_lo; + r_hi = lhs_hi ^ rhs_hi; break; case AIR_INST_BIT_AND: - result = (uint64_t)lhs_val & (uint64_t)rhs_val; + r_lo = lhs_lo & rhs_lo; + r_hi = lhs_hi & rhs_hi; break; case AIR_INST_BIT_OR: - result = (uint64_t)lhs_val | (uint64_t)rhs_val; + r_lo = lhs_lo | rhs_lo; + r_hi = lhs_hi | rhs_hi; break; default: goto emit_bitwise_runtime; } - return internComptimeInt(sema, result_ty, result); + return internComptimeInt(sema, result_ty, r_lo, r_hi); } emit_bitwise_runtime:; @@ -1024,9 +1122,10 @@ static AirInstRef zirBitcast(Sema* sema, SemaBlock* block, uint32_t inst) { AirInstRef operand = resolveInst(sema, operand_ref); // Comptime folding: if operand is comptime, bitcast at comptime. // The bit pattern is preserved; just re-intern with the dest type. - int64_t val; - if (isComptimeInt(sema, operand, &val)) { - return internComptimeInt(sema, dest_ty, (uint64_t)val); + uint64_t lo, hi; + bool neg; + if (isComptimeIntWide(sema, operand, &lo, &hi, &neg)) { + return internComptimeInt(sema, dest_ty, lo, hi); } AirInstData data; memset(&data, 0, sizeof(data)); @@ -1169,21 +1268,19 @@ static AirInstRef zirShl( AirInstRef lhs = resolveInst(sema, lhs_ref); AirInstRef rhs = resolveInst(sema, rhs_ref); - // Comptime folding for shift operations. - int64_t lhs_val; - int64_t rhs_val; - if (isComptimeInt(sema, lhs, &lhs_val) - && isComptimeInt(sema, rhs, &rhs_val)) { + // Comptime folding for shift operations (128-bit). + uint64_t lhs_lo, lhs_hi, rhs_lo, rhs_hi; + bool lhs_neg, rhs_neg; + if (isComptimeIntWide(sema, lhs, &lhs_lo, &lhs_hi, &lhs_neg) + && isComptimeIntWide(sema, rhs, &rhs_lo, &rhs_hi, &rhs_neg)) { TypeIndex lhs_ty = semaTypeOf(sema, lhs); - uint64_t result; - if ((uint64_t)rhs_val >= 64) { - result = 0; - } else if (air_tag == AIR_INST_SHL) { - result = (uint64_t)lhs_val << (uint32_t)rhs_val; - } else { - result = (uint64_t)lhs_val >> (uint32_t)rhs_val; - } - return internComptimeInt(sema, lhs_ty, result); + uint32_t shift = (uint32_t)rhs_lo; + uint64_t r_lo, r_hi; + if (air_tag == AIR_INST_SHL) + shl128(lhs_lo, lhs_hi, shift, &r_lo, &r_hi); + else + shr128(lhs_lo, lhs_hi, shift, &r_lo, &r_hi); + return internComptimeInt(sema, lhs_ty, r_lo, r_hi); } AirInstData data; @@ -1221,7 +1318,7 @@ static void zirInt(Sema* sema, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; - key.data.int_val.value = int_val; + key.data.int_val.value_lo = int_val; key.data.int_val.is_negative = false; uint32_t ip_index = ipIntern(sema->ip, key); instMapPut(&sema->inst_map, inst, AIR_REF_FROM_IP(ip_index)); @@ -2412,7 +2509,7 @@ static AirInstRef zirCall( InternPoolKey k = ipIndexToKey(sema->ip, AIR_REF_TO_IP(arg_refs[1])); if (k.tag == IP_KEY_INT) - bits_val = (uint16_t)k.data.int_val.value; + bits_val = (uint16_t)k.data.int_val.value_lo; } // Extract signedness from arg 0's ZIR body (enum literal). @@ -2699,8 +2796,7 @@ static AirInstRef zirCall( memset(&data, 0, sizeof(data)); data.pl_op.operand = arg_refs[param_idx]; data.pl_op.payload = name_nts; - (void)semaAddInst( - &child_block, AIR_INST_DBG_ARG_INLINE, data); + (void)semaAddInst(&child_block, AIR_INST_DBG_ARG_INLINE, data); } param_idx++; } @@ -3540,7 +3636,8 @@ static AirInstRef semaResolveSwitchComptime( // debug undefined pattern. AirInstData block_data; memset(&block_data, 0xaa, sizeof(block_data)); - uint32_t block_inst = semaAddInstAsIndex(sema, AIR_INST_BLOCK, block_data); + uint32_t block_inst + = semaAddInstAsIndex(sema, AIR_INST_BLOCK, block_data); // Set up a label so break can find this block. SemaBlockLabel label; @@ -3594,7 +3691,8 @@ static AirInstRef semaResolveSwitchComptime( // Reserve BLOCK instruction (same as scalar case above). AirInstData block_data; memset(&block_data, 0xaa, sizeof(block_data)); - uint32_t block_inst = semaAddInstAsIndex(sema, AIR_INST_BLOCK, block_data); + uint32_t block_inst + = semaAddInstAsIndex(sema, AIR_INST_BLOCK, block_data); SemaBlockLabel label; memset(&label, 0, sizeof(label)); @@ -3642,7 +3740,7 @@ static AirInstRef zirTypeInfoComptime(Sema* sema, uint32_t inst) { key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; // Use a distinctive value unlikely to collide with real ints. - key.data.int_val.value = 0x7E100000 + type_ip; + key.data.int_val.value_lo = 0x7E100000 + type_ip; key.data.int_val.is_negative = false; InternPoolIndex marker = ipIntern(sema->ip, key); @@ -3697,7 +3795,7 @@ static AirInstRef zirBitSizeOf(Sema* sema, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; - key.data.int_val.value = bit_size; + key.data.int_val.value_lo = bit_size; key.data.int_val.is_negative = false; return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); } @@ -3729,7 +3827,7 @@ static AirInstRef zirFieldValComptime(Sema* sema, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; - key.data.int_val.value = 0x71040000 + bits; + key.data.int_val.value_lo = 0x71040000 + bits; key.data.int_val.is_negative = false; InternPoolIndex marker = ipIntern(sema->ip, key); ctTrack(sema, marker, CT_TAG_FLOAT_INFO, bits); @@ -3744,7 +3842,7 @@ static AirInstRef zirFieldValComptime(Sema* sema, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_U16_TYPE; - key.data.int_val.value = ct_val; + key.data.int_val.value_lo = ct_val; key.data.int_val.is_negative = false; return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); } @@ -3816,7 +3914,7 @@ static AirInstRef zirStructInitComptime(Sema* sema, uint32_t inst) { InternPoolIndex ip_idx = AIR_REF_TO_IP(init_air); InternPoolKey key_val = sema->ip->items[ip_idx]; if (key_val.tag == IP_KEY_INT) { - signedness = (uint32_t)key_val.data.int_val.value; + signedness = (uint32_t)key_val.data.int_val.value_lo; } } } else if (strcmp(name, "bits") == 0) { @@ -3825,7 +3923,7 @@ static AirInstRef zirStructInitComptime(Sema* sema, uint32_t inst) { InternPoolIndex ip_idx = AIR_REF_TO_IP(init_air); InternPoolKey key_val = sema->ip->items[ip_idx]; if (key_val.tag == IP_KEY_INT) { - bits_val = (uint32_t)key_val.data.int_val.value; + bits_val = (uint32_t)key_val.data.int_val.value_lo; } } } else if (strcmp(name, "int") == 0) { @@ -3844,7 +3942,7 @@ static AirInstRef zirStructInitComptime(Sema* sema, uint32_t inst) { if (has_signedness && has_bits) { // Inner struct: .{.signedness = S, .bits = N} - key.data.int_val.value + key.data.int_val.value_lo = 0x51F70000 | ((uint64_t)signedness << 16) | bits_val; InternPoolIndex marker = ipIntern(sema->ip, key); ctTrack(sema, marker, CT_TAG_INT_INFO, (signedness << 16) | bits_val); @@ -3853,7 +3951,7 @@ static AirInstRef zirStructInitComptime(Sema* sema, uint32_t inst) { if (outer_field_name != NULL && strcmp(outer_field_name, "int") == 0) { // Outer struct: .{.int = <inner>} - key.data.int_val.value = 0x52E10000 + inner_ip; + key.data.int_val.value_lo = 0x52E10000 + inner_ip; InternPoolIndex marker = ipIntern(sema->ip, key); ctTrack(sema, marker, CT_TAG_REIFY_INT, inner_ip); return AIR_REF_FROM_IP(marker); @@ -3931,7 +4029,7 @@ static AirInstRef zirDeclLiteralComptime(Sema* sema, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; - key.data.int_val.value = 0; + key.data.int_val.value_lo = 0; key.data.int_val.is_negative = false; return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); } else if (strcmp(field_name, "signed") == 0) { @@ -3939,7 +4037,7 @@ static AirInstRef zirDeclLiteralComptime(Sema* sema, uint32_t inst) { memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; - key.data.int_val.value = 1; + key.data.int_val.value_lo = 1; key.data.int_val.is_negative = false; return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); } @@ -4169,7 +4267,7 @@ static bool analyzeBodyInner( InternPoolKey key = ipIndexToKey(sema->ip, AIR_REF_TO_IP(resolved)); if (key.tag == IP_KEY_INT) { - sema->branch_hint = (int8_t)key.data.int_val.value; + sema->branch_hint = (int8_t)key.data.int_val.value_lo; } } air_ref = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); @@ -4231,7 +4329,8 @@ static bool analyzeBodyInner( memset(&br_data, 0, sizeof(br_data)); br_data.br.block_inst = blk_inst; br_data.br.operand = AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); - uint32_t br_inst = semaAddInstAsIndex(sema, AIR_INST_BR, br_data); + uint32_t br_inst + = semaAddInstAsIndex(sema, AIR_INST_BR, br_data); // Write block extra: body_len2, then body insts. uint32_t body_len2 = new_insts_count + 1; // +1 for BR @@ -5153,10 +5252,11 @@ static bool analyzeBodyInner( - 1] == AIR_REF_TO_INST(coerced)); uint32_t sub_bl = coerce_block.instructions_len + 1; - uint32_t sub_br_idx = semaAddInstAsIndex(sema, AIR_INST_BR, - (AirInstData) { - .br = { .block_inst = label.merges.block_inst, - .operand = coerced } }); + uint32_t sub_br_idx + = semaAddInstAsIndex(sema, AIR_INST_BR, + (AirInstData) { .br + = { .block_inst = label.merges.block_inst, + .operand = coerced } }); uint32_t sub_extra = semaAddExtra(sema, sub_bl); for (uint32_t si = 0; si < coerce_block.instructions_len; si++) { diff --git a/stage0/stages_test.zig b/stage0/stages_test.zig @@ -119,7 +119,7 @@ const corpus_files = .{ "../lib/compiler_rt/absvsi2.zig", // 311 "../lib/compiler_rt/absvti2.zig", // 314 "../lib/compiler_rt/addhf3.zig", // 319 - //"../lib/compiler_rt/addxf3.zig", // 323 + "../lib/compiler_rt/addxf3.zig", // 323 //"../lib/compiler_rt/mulhf3.zig", // 323 //"../lib/compiler_rt/mulxf3.zig", // 323 //"../lib/compiler_rt/truncxfdf2.zig", // 333 diff --git a/stage0/verbose_air.c b/stage0/verbose_air.c @@ -318,7 +318,11 @@ static void writeValue( case IP_KEY_INT: if (key.data.int_val.is_negative) fprintf(out, "-"); - fprintf(out, "%" PRIu64, key.data.int_val.value); + if (key.data.int_val.value_hi != 0) + fprintf(out, "0x%" PRIx64 "%016" PRIx64, key.data.int_val.value_hi, + key.data.int_val.value_lo); + else + fprintf(out, "%" PRIu64, key.data.int_val.value_lo); break; case IP_KEY_SIMPLE_VALUE: switch (key.data.simple_value) {