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:
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) {