kit

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

commit faf2962b92abeaaa068ef34fca5b3a1c9dfe85e1
parent 3d2eb21daf7ec352bb0d5c59715d12beed45d2e0
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 16 Jun 2026 19:27:12 -0700

arm32 Phase 2: split wide (8-byte) memory accesses into two 4-byte halves

A handful of cg paths (notably an i64 switch scrutinee) hand the backend a single
8-byte load/store into an even/odd register pair instead of pre-splitting to
lanes; rv32 splits these in its emit, arm panicked. arm_emit_mem now emits the
low lane at [base,off] and the high lane at [base,off+4] over (rt, rt+1). Fixes
i64 switch + i64 global-array/record accesses.

Diffstat:
Msrc/arch/arm32/native.c | 22+++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/arch/arm32/native.c b/src/arch/arm32/native.c @@ -393,7 +393,27 @@ static void arm_emit_mem(Arm32NativeTarget* a, int is_load, NativeLoc reg, u32 rt = loc_reg(reg); u32 size = mem.size ? mem.size : native_type_size(&a->base, reg.type); u32 t3hw1, t4hw1; - if (size >= 8u) arm_panic(a, "8-byte memory access not lowered (wide8 path)"); + if (size >= 8u) { + /* Split a wide (8-byte) access into two 4-byte halves over the consecutive + * register pair: low lane = rt at [base, off], high lane = rt+1 at + * [base, off+4] (little-endian). The cg hands a few paths — notably an i64 + * switch scrutinee — a single 8-byte access into an even/odd pair; rv32 + * splits identically. (Wider-than-8 is not produced by the C frontend.) */ + KitCgTypeId i32t = builtin_id(KIT_CG_BUILTIN_I32); + NativeLoc lo = reg, hi = reg; + NativeAddr addr_hi = addr; + MemAccess m = mem; + if (size != 8u) arm_panic(a, "memory access wider than 8 bytes"); + m.size = 4u; + m.type = i32t; + lo.type = i32t; + hi.type = i32t; + hi.v.reg = (rt + 1u) & 0xfu; + addr_hi.offset += 4; + arm_emit_mem(a, is_load, lo, addr, m); + arm_emit_mem(a, is_load, hi, addr_hi, m); + return; + } /* pick the op (T3 positive, T4 +/-) for this width. */ if (size == 1u) { t3hw1 = is_load ? 0xf890u : 0xf880u;