zig

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

commit 1ccc0e54d9cd80c7d17dd1ba82e9271090eba986 (tree)
parent 1a1a4d3d2558976232455614601a8b234f7c30cd
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sat,  7 Mar 2026 08:05:02 +0000

sema: add comptime folding to zirByteSwap

For comptime-known integer operands with bit-aligned widths, compute
the byte-swapped value at comptime rather than emitting AIR.
Matches src/Sema.zig zirByteSwap: arith.byteSwap() comptime path.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Mstage0/sema.c | 38++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+), 0 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -1311,6 +1311,44 @@ static AirInstRef zirByteSwap(Sema* sema, SemaBlock* block, uint32_t inst) { ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand; AirInstRef operand = resolveInst(sema, operand_ref); TypeIndex operand_ty = semaTypeOf(sema, operand); + + // Comptime folding: if operand is a comptime-known integer, compute + // the byte-swapped value at comptime. + // Ported from src/Sema.zig zirByteSwap: arith.byteSwap() call. + uint64_t val_lo, val_hi; + bool val_neg; + if (isComptimeIntWide(sema, operand, &val_lo, &val_hi, &val_neg)) { + uint16_t bits = 0; + if (sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE) + bits = sema->ip->items[operand_ty].data.int_type.bits; + if (bits > 0 && bits % 8 == 0) { + // Byte-swap: reverse the bytes. + uint64_t r_lo = 0, r_hi = 0; + if (bits <= 64) { + for (uint16_t b = 0; b < bits / 8; b++) { + uint16_t src_byte = (uint16_t)((bits / 8) - 1 - b); + uint8_t byte_val = (uint8_t)(val_lo >> (src_byte * 8)); + r_lo |= (uint64_t)byte_val << (b * 8); + } + } else { + // 128-bit case: lo holds bytes 0-7, hi holds bytes 8-15. + for (uint16_t b = 0; b < 8; b++) { + uint16_t src = (uint16_t)(15 - b); + uint8_t bv = (src < 8) + ? (uint8_t)(val_lo >> (src * 8)) + : (uint8_t)(val_hi >> ((src - 8) * 8)); + r_lo |= (uint64_t)bv << (b * 8); + } + for (uint16_t b = 0; b < 8; b++) { + uint16_t src = (uint16_t)(7 - b); + uint8_t bv = (uint8_t)(val_lo >> (src * 8)); + r_hi |= (uint64_t)bv << (b * 8); + } + } + return internComptimeInt(sema, operand_ty, r_lo, r_hi); + } + } + AirInstData data; memset(&data, 0, sizeof(data)); data.ty_op.ty_ref = AIR_REF_FROM_IP(operand_ty);