kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 78ec17447c5bd31bf94df1dcce31dd4975eda7f8
parent 5b6da982b55a6146cf7742d6254c6016fa8d2122
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 10 Jun 2026 18:07:35 -0700

fix(rv64): include arg reg a7/fa7 in the -O1 regalloc caller-saved/arg masks

The rv64 NativeAllocClassInfo masks (src/arch/riscv/native.c rv_classes)
dropped the 8th argument register (a7/fa7) and carried a spurious bit-18
(s2/fs2): arg_mask=0x0001fc00 covers only a0-a6, and caller_saved_mask
=0xf00400e0|0x0001fc00 sets bit 18 instead of bit 17. The -O1 register
allocator therefore never learned that a7 is caller-saved, so a parameter
delivered in a7 that is live across a call was left in a7 and never
evacuated to a callee-saved register; the call clobbered it, yielding a
garbage pointer and a SIGSEGV.

This broke the rv64 -O1 self-host: find_and_open_include (9 params; SrcLoc
takes two arg regs, so `resolved` lands in a7) crashes on every #include,
so stage2 SEGV'd compiling the first stage3 file (abi.c). Even
`#include "empty.h"` crashes the -O1-built kit. Pre-existing since the
original rv64 NativeTarget port (6eaf127a); latent because an 8th integer
arg live across a call is rare and -O0 has no register allocator.

Fix both INT and FP classes: arg_mask=0x0003fc00 (a0-a7/fa0-fa7) and
caller_saved_mask=0xf00000e0|0x0003fc00 (FP: 0xf00000ff|0x0003fc00),
matching the existing comments. Confirmed by disasm (a7 now homed to a
callee-saved reg), minimal int+fp 8-arg-live-across-call tests, and abi.c
/#include compiling cleanly with the -O1 rv64 kit.

Diffstat:
Msrc/arch/riscv/native.c | 8++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/arch/riscv/native.c b/src/arch/riscv/native.c @@ -480,10 +480,10 @@ static const NativeAllocClassInfo rv_classes[] = { .phys = rv_int_phys, .nphys = sizeof rv_int_phys / sizeof rv_int_phys[0], /* t0-t6 (5-7,28-31) + a0-a7 (10-17) */ - .caller_saved_mask = 0xf00400e0u | 0x0001fc00u, + .caller_saved_mask = 0xf00000e0u | 0x0003fc00u, /* s0-s11 (8,9,18-27) */ .callee_saved_mask = 0x0ffc0300u, - .arg_mask = 0x0001fc00u, + .arg_mask = 0x0003fc00u, .ret_mask = 0x00000c00u, /* zero,ra,sp,gp,tp,t0,t1,t2,s0 (bits 0-8) + t3 (bit 28). t4/t5 are the * driver scratch pool (reserved-from-alloc but listed in scratch[]). */ @@ -496,10 +496,10 @@ static const NativeAllocClassInfo rv_classes[] = { .phys = rv_fp_phys, .nphys = sizeof rv_fp_phys / sizeof rv_fp_phys[0], /* ft0-ft7 (0-7), fa0-fa7 (10-17), ft8-ft11 (28-31) */ - .caller_saved_mask = 0xf00400ffu | 0x0001fc00u, + .caller_saved_mask = 0xf00000ffu | 0x0003fc00u, /* fs0-fs11 (8,9,18-27) */ .callee_saved_mask = 0x0ffc0300u, - .arg_mask = 0x0001fc00u, + .arg_mask = 0x0003fc00u, .ret_mask = 0x00000c00u, .reserved_mask = 0x0000000fu /* ft0-ft3 */}, };