<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>kit, branch HEAD</title>
<subtitle>kit
</subtitle>
<entry>
<id>128504789846f077dc83cd5a54b2d05dbf9083a0</id>
<published>2026-06-09T15:13:24Z</published>
<updated>2026-06-09T15:13:24Z</updated>
<title>windows: cross-compile kit + run cc/JIT natively on aarch64-windows</title>
<link rel="alternate" type="text/html" href="commit/128504789846f077dc83cd5a54b2d05dbf9083a0.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 128504789846f077dc83cd5a54b2d05dbf9083a0
parent f20d82f2139cc962ceffd8060d2e54b39e8c329f
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Tue,  9 Jun 2026 08:13:24 -0700

windows: cross-compile kit + run cc/JIT natively on aarch64-windows

Bring up kit as a self-hosted Windows toolchain: cross-compile the kit
binary on the dev host (build/kit cc -target aarch64-windows) into a
PE/COFF kit.exe, then run `kit cc` and `kit run` (JIT) on a Windows VM.
Verified on an aarch64 Windows 11 VM: kit.exe --help; `kit cc hello.c`
-&gt; a working hello.exe (correct stdout + exit code); and `kit run`
(JIT) of compute / data / extern-call / puts programs (libc I/O via
dlsym).

Fixes, each a real gap surfaced by the bring-up:

- c frontend: honor GCC asm-label symbol renames on declarations
  (`extern T f(...) __asm__(&quot;alt&quot;)`). Parsed before but ignored except
  for register locals; the emitted/referenced linkage symbol now uses
  the label (Decl.asm_name) while the C name stays for diagnostics.
  mingw&#39;s &lt;time.h&gt; redirects e.g. time-&gt;_time64 this way; without it
  the link had an undefined `time`.

- coff: honor the Microsoft short-import NameType field (was
  `(void)name_type`). NOPREFIX/UNDECORATE strip decoration; EXPORTAS
  carries the real DLL export name separately. The PE hint/name table
  now uses that import name, not the local symbol -- UCRT aliases e.g.
  local `__msvcrt_assert` onto export `_assert`; emitting the alias
  name made kit.exe fail to load (STATUS_ENTRYPOINT_NOT_FOUND).

- driver/lib/hosted.c: add libwinpthread to the Windows hosted link.
  &lt;time.h&gt;&#39;s pthread_time.h inline wrappers reference nanosleep64 /
  clock_*64, which live there (llvm-mingw ships it as a core lib);
  static archive, so it adds no runtime DLL dependency.

- rt/include/setjmp.h: on Windows, asm-rename setjmp/longjmp onto
  mingw&#39;s non-SEH __mingw_setjmp/__mingw_longjmp (libmingwex). kit&#39;s
  freestanding code wants pure register save/restore, and mingw exposes
  no bare `setjmp` symbol (it is a macro over _setjmpex/__mingw_setjmp).

- driver/env/windows.c:
  - gate the SEH __try guarded-copy under !defined(__kit__) (kit&#39;s C
    frontend implements no SEH); rely on the VEH backstop already there.
  - JIT dlsym fallback for the libucrt-static __local_stdio_{printf,
    scanf}_options helpers (referenced by mingw&#39;s printf/scanf inlines,
    not DLL-exported); hand JIT&#39;d code kit.exe&#39;s own copies.
  - map the JIT execmem dual-map&#39;s runtime/exec view FILE_MAP_WRITE so
    writable runtime segments (an import GOT, .data) can be
    VirtualProtect&#39;d PAGE_READWRITE. A FILE_MAP_EXECUTE-only view
    rejects RW (err 87), which broke `kit run` of any program with an
    external call or writable global.

- scripts/windows_cross.sh: reproducible cross-build harness (toolchain
  wrappers + the HOST_OS=windows make invocation).

Known gap: printf-family via `kit run` still needs libucrt&#39;s static
`printf` (not a DLL export) and the JIT links no static archives; AOT
`kit cc` printf works fully, as do JIT puts()/external calls.

Host regression: test-coff/link/elf/cg-api/parse/toy green. test-macho
36_tls_basic/J is a pre-existing JIT-TLS failure (confirmed failing at
HEAD via a clean worktree build).

</content>
</entry>
<entry>
<id>f20d82f2139cc962ceffd8060d2e54b39e8c329f</id>
<published>2026-06-09T06:27:59Z</published>
<updated>2026-06-09T06:27:59Z</updated>
<title>env/windows: include windows.h before psapi.h (mingw cross-build)</title>
<link rel="alternate" type="text/html" href="commit/f20d82f2139cc962ceffd8060d2e54b39e8c329f.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit f20d82f2139cc962ceffd8060d2e54b39e8c329f
parent ea01f03f2e47071ce36aae30a6de7f31bc5d9c8d
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 23:27:59 -0700

env/windows: include windows.h before psapi.h (mingw cross-build)

mingw&#39;s &lt;psapi.h&gt;/&lt;process.h&gt; use windows.h types (WINBOOL/DWORD/LPVOID)
and do not self-include it, so the alphabetized include order (psapi before
windows) failed to compile under the llvm-mingw cross-toolchain. Pull
windows.h into its own leading include group so a formatter sort cannot
reorder it. Surfaced while standing up an aarch64-windows cross-build of
kit; the remaining windows.c host-env build issues (SEH __try, attribute
thread, dllimport) are separate and pre-existing.

</content>
</entry>
<entry>
<id>ea01f03f2e47071ce36aae30a6de7f31bc5d9c8d</id>
<published>2026-06-09T05:54:07Z</published>
<updated>2026-06-09T05:54:07Z</updated>
<title>jit/tls: ELF Local-Exec relaxation via arch-abstracted hook</title>
<link rel="alternate" type="text/html" href="commit/ea01f03f2e47071ce36aae30a6de7f31bc5d9c8d.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit ea01f03f2e47071ce36aae30a6de7f31bc5d9c8d
parent d8d8209e1bd898acb3455608478a57b9d2ecfc57
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 22:54:07 -0700

jit/tls: ELF Local-Exec relaxation via arch-abstracted hook

Extend the uniform in-image JIT TLS model to ELF (Linux + FreeBSD), the
single-threaded JIT resolving each thread-local to its in-image .tdata/.tbss
instead of via the host thread pointer (mrs tpidr_el0 / add tp / mov fs:0),
which aliased into the host process&#39;s own TLS — wrong init and unsafe. This
was the documented bootstrap blocker (141_threadlocal_mutate returned 3
instead of 43 on the R lane).

Arch-abstracted through the existing relocation seam, no arch switch in
link_jit.c:
- RELOC_IS_TLS_LE flag on RelocDesc, set on each arch&#39;s Local-Exec reloc
  rows (aa64 TLSLE_ADD_TPREL_*, rv TPREL_HI20/LO12_*, x64 TPOFF32).
- LinkArchDesc.jit_tls_le_relax hook; per-arch idiom rewrite lives in each
  arch&#39;s reloc.c beside its reloc_apply_insn encoders:
    aa64: mrs/add/add        -&gt; adrp; add :lo12:; nop
    rv64: lui/add tp/addi    -&gt; auipc %pcrel_hi; nop; addi %pcrel_lo
    x64:  mov fs:0/lea       -&gt; nop...; lea rd,[rip+&amp;var]
- link_jit.c (initial + append reloc loops) classifies via
  reloc_kind_is_tls_le and delegates; the old reloc_is_tlsle /
  reloc_is_x64_tlsle / JIT_TLS_TCB_SIZE host-TP code is removed.

Verified on the arm64 host + containers: aa64-linux (native), x64-linux and
rv64-linux (podman) all return 141=43 / 142=134 on the R lane at -O0/1/2 and
the interp lane. macOS (Mach-O) unchanged: test-toy/test-link/test-opt green.

COFF/Windows TLS relaxation is a separate follow-up (different TEB idiom).

</content>
</entry>
<entry>
<id>d8d8209e1bd898acb3455608478a57b9d2ecfc57</id>
<published>2026-06-09T05:06:45Z</published>
<updated>2026-06-09T05:06:45Z</updated>
<title>jit/tls: uniform in-image thread-local storage; retire Mach-O TLV thunk</title>
<link rel="alternate" type="text/html" href="commit/d8d8209e1bd898acb3455608478a57b9d2ecfc57.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit d8d8209e1bd898acb3455608478a57b9d2ecfc57
parent 70592470957e05df49ed33592c6f9fd68f8c3421
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 22:06:45 -0700

jit/tls: uniform in-image thread-local storage; retire Mach-O TLV thunk

Single-threaded JIT collapses thread-local to a single in-image instance:
the image&#39;s .tdata/.tbss IS the storage. Resolve every TLS access to that
storage without touching the host thread pointer (reading host tpidr/fs/tp
aliases into the host process&#39;s own TLS — wrong init and unsafe).

- link_jit: map the TLS segment RW in the JIT (AOT keeps it as the RO init
  template). Relax the Mach-O TLV access to read storage straight from the
  descriptor&#39;s +16 slot (ldr xN,[xN,#16]; blr -&gt; nop) — no thunk, no
  descriptor patching, no per-thread block. Init comes free from the
  copied .tdata.
- kit_jit_tls_addr (replaces kit_jit_tlv_resolve): format-aware,
  range-checked resolution for the interpreter/host (Mach-O reads
  descriptor[+16]; ELF/COFF the symbol is the storage).
- opt: model IR_TLS_ADDR_OF&#39;s clobber set via NATIVE_MOP_TLS_ADDR. The
  Mach-O TLV sequence clobbers x0/x16/x17/lr; the optimizer only modeled
  its dest, corrupting a value left live in x0 across a second TLS access
  at -O1+ (multi-var TLS returned 204 instead of 134). Fixes AOT macOS too.
- Retire the dead machinery: src/jit/ (tlv thunk asm/stub/header),
  driver/env/jit_tls_posix.c, the KitJitTls public type + KitJitHost.tls,
  Windows FLS-backed TLS, and all wiring (~600 lines removed).
- test/toy 142_threadlocal_multi: multi-var TLS R/I-lane coverage.
- doc/JIT.md: document the uniform model.

ELF Local-Exec is not yet converted (still TP-relative; Step 6).
Verified green on macOS arm64: test-toy 1388/0/39, test-link 122/0,
test-opt, test-cg-api, test-isa, test-aa64-inline, test-smoke-{x64,rv64}.

</content>
</entry>
<entry>
<id>70592470957e05df49ed33592c6f9fd68f8c3421</id>
<published>2026-06-09T01:44:57Z</published>
<updated>2026-06-09T01:44:57Z</updated>
<title>link: root DSO back-referenced symbols under --gc-sections (freebsd -O1 fixed point)</title>
<link rel="alternate" type="text/html" href="commit/70592470957e05df49ed33592c6f9fd68f8c3421.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 70592470957e05df49ed33592c6f9fd68f8c3421
parent 4e590650228592d27104243d8512af3ed0cb0c18
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 18:44:57 -0700

link: root DSO back-referenced symbols under --gc-sections (freebsd -O1 fixed point)

A dynamic executable defines symbols its shared libraries reference back into it
— on FreeBSD, the crt defines `__progname`/`environ` and libc.so.7 has undefined
references to them. kit&#39;s --gc-sections liveness pass only rooted the entry,
init/fini, and retained sections, so when nothing in the executable referenced
those crt symbols they were garbage-collected out of the dynsym, and the
resulting `-O1` kit failed to load:

    ld-elf.so.1: /lib/libc.so.7: Undefined symbol &quot;__progname&quot;

read_elf_dso now records each DSO&#39;s undefined-symbol names on its ObjImage
(obj_image_add_undef), and link_gc_compute roots the executable&#39;s definitions of
them — GNU ld&#39;s default &quot;keep what shared libraries need&quot; behaviour, surgical
(only DSO-referenced symbols, not all globals, so GC stays effective) and
monotonic (only adds roots). The DSO ObjImage is now always created (previously
only when versioned) so undef refs are captured for unversioned DSOs (musl) too;
versioning is unchanged (musl still emits no .gnu.version_r, glibc still does).

With this, the **aarch64-freebsd `-O1` (release) self-build reaches the
byte-identical fixed point** — FreeBSD now self-hosts at both -O0 and -O1
(Toy 1378/2/39 through stage3; the 2 fails are the pre-existing JIT-TLS .tdata
R-lane gap). test-link/test-elf/test-asm green; musl/glibc --gc-sections links
unaffected. Builds on the deferred-tombstone fix in the previous commit.

</content>
</entry>
<entry>
<id>4e590650228592d27104243d8512af3ed0cb0c18</id>
<published>2026-06-09T01:22:39Z</published>
<updated>2026-06-09T01:22:39Z</updated>
<title>asm: don&#39;t globalize deferred-symbol tombstones in promote_undef_externs</title>
<link rel="alternate" type="text/html" href="commit/4e590650228592d27104243d8512af3ed0cb0c18.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 4e590650228592d27104243d8512af3ed0cb0c18
parent 246df83a668460fbe7e2b598a23614ebe68c9c11
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 18:22:39 -0700

asm: don&#39;t globalize deferred-symbol tombstones in promote_undef_externs

promote_undef_externs (the `as` pass that turns referenced-but-undefined LOCAL
symbols into undefined GLOBALs, matching GNU as) iterated every symbol slot —
including `removed=1` tombstones — and so flipped the binding of deferred
anonymous const-data / jump-table symbols (`.Lkit_ro.N` / `.Lkit_jt.N`) that
were still tombstoned awaiting materialization at opt_whole_module_finalize.
It was the only obj_symiter consumer not honoring the `removed` contract
documented in obj.h.

This bit the aarch64-freebsd `-O1` self-build: FreeBSD&#39;s &lt;stdlib.h&gt; injects a
file-scope `__asm__(&quot;.symver ...&quot;)` (via __sym_compat) whose replay runs this
pass *before* the deferred data is materialized, so the four hosted
driver/env/*.o each surfaced a defined global `.Lkit_ro.0` and the stage2 link
aborted with `duplicate definition of global symbol &#39;.Lkit_ro.0&#39;`. Not
FreeBSD-codegen-specific — any TU with a file-scope asm plus a deferred
const-data symbol at -O1 reproduces it on any target (e.g. aarch64-linux-musl).

Fix: skip tombstones in the loop. The four env objects now show zero global
.Lkit symbols and the stage2 link succeeds. test-asm/test-link/test-elf green;
-O0 is provably unaffected (deferral, hence tombstones, only exist at -O1).

The freebsd -O1 chain now gets past the stage2 link but hits a separate,
pre-existing blocker — `-Wl,--gc-sections` drops crt `__progname`/`environ`
that libc.so.7 needs — documented in doc/plan/BOOTSTRAP.md as the next fix.

</content>
</entry>
<entry>
<id>246df83a668460fbe7e2b598a23614ebe68c9c11</id>
<published>2026-06-09T00:18:13Z</published>
<updated>2026-06-09T00:18:13Z</updated>
<title>doc/bootstrap: record aarch64-linux and aarch64-freebsd bootstrap state</title>
<link rel="alternate" type="text/html" href="commit/246df83a668460fbe7e2b598a23614ebe68c9c11.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 246df83a668460fbe7e2b598a23614ebe68c9c11
parent ad732e4b9733ddb81da3f861b595c7e1e6bd1388
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 17:18:13 -0700

doc/bootstrap: record aarch64-linux and aarch64-freebsd bootstrap state

- aarch64-linux (musl + glibc) baseline: both -O0/-O1 reach the fixed point,
  via the Linux-container path; notes the JIT-TLS / objdump-golden / C-backend
  Toy gaps that are not bootstrap blockers.
- aarch64-freebsd: -O0 chain reaches the byte-identical fixed point (Toy
  1371/9/39); needed -rdynamic acceptance + ELF Verneed/Versym emission (the
  fstat INO64 FBSD_1.0-vs-1.5 mis-bind). The -O1 release chain is blocked by a
  pre-existing FreeBSD-target deferred-const-data GLOBAL-binding bug
  (.Lkit_ro/.Lkit_jt); gate on bootstrap-debug until fixed.

</content>
</entry>
<entry>
<id>ad732e4b9733ddb81da3f861b595c7e1e6bd1388</id>
<published>2026-06-09T00:17:37Z</published>
<updated>2026-06-09T00:17:37Z</updated>
<title>elf: emit symbol-version (Verneed/Versym) requirements; freebsd -rdynamic + bootstrap shipping</title>
<link rel="alternate" type="text/html" href="commit/ad732e4b9733ddb81da3f861b595c7e1e6bd1388.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit ad732e4b9733ddb81da3f861b595c7e1e6bd1388
parent 704d2a298814839a5fdc17620b078f5e12dc34e3
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 17:17:37 -0700

elf: emit symbol-version (Verneed/Versym) requirements; freebsd -rdynamic + bootstrap shipping

kit&#39;s linker emitted unversioned undefined references (`UND fstat`), so on
FreeBSD the runtime bound the hidden compat `fstat@FBSD_1.0` (pre-INO64
`struct stat`) instead of the default `fstat@@FBSD_1.5`, reading `st_size` at
the wrong offset. A kit-built stage2 then failed to read its own source files,
blocking the aarch64-freebsd self-build at the stage3 compile.

The ELF linker now reads each DSO&#39;s `.gnu.version_d`/`.gnu.version` and emits a
matching `.gnu.version_r` + `.gnu.version` + DT_VERSYM/VERNEED/VERNEEDNUM,
selecting each import&#39;s default (non-hidden) version. Gated on the DSO carrying
versions, so musl/static links stay byte-identical; glibc links now also carry
correct GLIBC_* requirements (verified: glibc/musl/freebsd binaries run; host
test-link/elf/smoke/cg-api/ar/debug/dwarf green). With this the aarch64-freebsd
-O0 chain reaches the byte-identical fixed point and the Toy corpus runs
1371/9/39 through the bootstrapped stage3.

- src/obj/obj.h: ObjImageSym.version (a DSO export&#39;s default-version name)
- src/obj/elf/elf.h: DT_VER* tags, Verdef/Verneed wire sizes, VERSYM_* flags
- src/obj/elf/read.c: read_elf_verdefs() + versym parse in read_elf_image AND
  read_elf_dso (the linker&#39;s DSO reader now builds an ObjImage to carry versions)
- src/obj/elf/link_dyn.c: build_versions() — per-import requirements, versym +
  verneed bytes (only .dynstr offsets/indices, final at layout time)
- src/obj/elf/link.c: emit DT_VER* + SHT_GNU_VERSYM/VERNEED section types
- driver/cmd/cc.c: accept -rdynamic/-export-dynamic (FreeBSD&#39;s HOST_ENV_LDFLAGS
  passes -rdynamic; kit&#39;s ELF linker already exports DSO-referenced symbols)
- scripts/freebsd_bootstrap.sh: ship working-tree content of all tracked files
  with COPYFILE_DISABLE=1 (drops macOS AppleDouble `._*` xattr sidecars that
  FreeBSD tar would extract as bogus `._*.c` sources); Toy hook uses bash and
  no longer aborts before Toy when a chain fails

The -O1 release chain is still blocked, before the fixed-point check, by a
pre-existing FreeBSD-target codegen bug (deferred const-data .Lkit_ro/.Lkit_jt
symbols emitted GLOBAL instead of LOCAL; LOCAL on linux/macos). Not addressed here.

</content>
</entry>
<entry>
<id>704d2a298814839a5fdc17620b078f5e12dc34e3</id>
<published>2026-06-09T00:12:08Z</published>
<updated>2026-06-09T00:12:08Z</updated>
<title>bootstrap: aarch64-linux self-host (musl + glibc) + Toy ELF fixes</title>
<link rel="alternate" type="text/html" href="commit/704d2a298814839a5fdc17620b078f5e12dc34e3.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 704d2a298814839a5fdc17620b078f5e12dc34e3
parent 632517297055ab3a43bccd588d04211a315c97d1
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 17:12:08 -0700

bootstrap: aarch64-linux self-host (musl + glibc) + Toy ELF fixes

Reach the byte-identical bootstrap fixed point on aarch64-linux at -O0 and -O1
for both musl and glibc, run natively inside an arm64 Linux container
(scripts/linux_bootstrap.sh; make bootstrap-linux[-glibc]).

Build:
- bootstrap.mk: drive kit-as-compiler (stages 2/3) with -lc on every host, so
  kit resolves its hosted libc/sysroot via its own profile + host probe
  (replaces Darwin&#39;s -isysroot; unifies linux/freebsd/macos).
- scripts/linux_bootstrap.sh: container runner (alpine=musl, debian=glibc).

C frontend / preprocessor (glibc + Linux-UAPI headers; musl&#39;s ISO-C headers
never exercised these):
- pp: predefine __{INT,UINT}{64,MAX}_C_SUFFIX__ so kit-compiled TUs get
  correctly-typed 64-bit constants from rt/include/stdint.h.
- pp: erase __extension__ and map __signed__/__volatile__/__const__ to the
  canonical keywords (unconditional; were Windows-only).
- pp: support GNU named variadic macro params `args...` (&lt;linux/stddef.h&gt;).
- pp_directive: parse_pp_int accumulates in u64 (signed overflow was UB).
- cg_adapter: fix a 1-byte OOB write in pcg_aux_clear (pad[5] on u8 pad[5]).

C backend + Toy harness (ELF / host-cc portability):
- c_target: emit `va_list x = {0}`, not `= 0` (va_list is a struct/array on
  aarch64 / x86-64 Linux).
- toy/run.sh: L lane links hosted (kit cc -lc) on non-Darwin (ELF needs a crt
  _start); prefer .objdump.elf goldens on non-Darwin; skip musttail+sret C
  cases on gcc hosts (gcc rejects musttail on sret returns; clang accepts);
  add -Wno-tentative-definition-incomplete-type (valid C; clang-14 pedantry).
- new fixtures: 3 .objdump.elf goldens + 2 .cbackend.gcc.skip.

Verified: glibc(clang) Toy 1378/2/39, musl(gcc) 1375/3/41. Remaining fails are
the tracked JIT-TLS .tdata-init (141_threadlocal_mutate) and a rare
archive-iterator heisenbug; both deliberately left as follow-ups.

</content>
</entry>
<entry>
<id>632517297055ab3a43bccd588d04211a315c97d1</id>
<published>2026-06-08T22:00:13Z</published>
<updated>2026-06-08T22:00:13Z</updated>
<title>freebsd: bootstrap support + portable stdint.h INT64_C</title>
<link rel="alternate" type="text/html" href="commit/632517297055ab3a43bccd588d04211a315c97d1.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 632517297055ab3a43bccd588d04211a315c97d1
parent 2a2dc7af1f422ffa8f7bf62f229b9f448f65a380
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 15:00:13 -0700

freebsd: bootstrap support + portable stdint.h INT64_C

rt/include/stdint.h: replace __INT64_C(c)/__UINT64_C(c) direct calls
with __KIT_XPASTE(c, __INT64_C_SUFFIX__) suffix-paste approach.
FreeBSD clang 19 (aarch64-freebsd15, LP64) does not predefine the
function-like __INT64_C/__UINT64_C macros, causing &quot;call to undeclared
function&quot; errors on any translation unit that uses UINT64_C(). All
supported compilers (clang 14+, GCC 8+) predefine __*_C_SUFFIX__
tokens, making the paste approach portable and unambiguous.

mk/bootstrap.mk: add FreeBSD to BOOTSTRAP_KIT_TOOLCHAIN_FLAGS (-lc
needed to wire hosted includes, same as Linux); portable BOOTSTRAP_SHASUM
(sha256sum on Linux/FreeBSD, shasum on macOS); bootstrap-freebsd target.

scripts/freebsd_bootstrap.sh: new -- native three-stage self-build via
the running FreeBSD aarch64 VM (mirrors linux_bootstrap.sh but SSHes
into the VM instead of using podman). Requires gmake on the VM.

</content>
</entry>
<entry>
<id>2a2dc7af1f422ffa8f7bf62f229b9f448f65a380</id>
<published>2026-06-08T21:13:57Z</published>
<updated>2026-06-08T21:13:57Z</updated>
<title>freebsd: x64/rv64 cross-compile, -lm/-lpthread, hosted lib search</title>
<link rel="alternate" type="text/html" href="commit/2a2dc7af1f422ffa8f7bf62f229b9f448f65a380.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 2a2dc7af1f422ffa8f7bf62f229b9f448f65a380
parent 28f2a06838d8f794b707e3e6dd2f70eadd14fc02
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 14:13:57 -0700

freebsd: x64/rv64 cross-compile, -lm/-lpthread, hosted lib search

1. Fix cross-compile for non-aarch64 hosts: gate LIB_SRCS_JIT_ASM on
   HOST_ARCH==aarch64 in mk/lib_srcs.mk; add LIB_SRCS_JIT_STUB
   (src/jit/tlv_thunk_stub.c) for other hosts, with a matching compile
   rule in Makefile.

2. Fix -lm / -lpthread / other user-specified -l flags not found when
   using the hosted profile:
   - Add lib_search_dirs[] to DriverHostedPlan so the resolved hosted
     lib dirs (e.g. /usr/lib, /lib on FreeBSD) are exposed to callers.
   - driver_hosted_resolve: transfer libdir ownership from DriverHostedDirs
     into the plan; driver_hosted_plan_fini frees them.
   - cc.c: populate lib_search_paths from plan lib_search_dirs in
     cc_apply_hosted_profile; move cc_resolve_pending_libs to after
     cc_apply_hosted_profile so hosted dirs are present when -l flags
     are resolved.
   - ld.c: pre-scan for -lc in ld_parse first pass and call
     driver_hosted_dirs_resolve to pre-populate o-&gt;lib_dirs before the
     inline -l resolution loop; also add hosted lib_search_dirs in
     ld_apply_hosted_before_after.

3. Mark RELEASE.md items done: FreeBSD target parsing/serialization,
   FreeBSD hosted profiles (arm64/x64/rv64 cross-compiled + VM-verified),
   and FreeBSD ucontext/register marshalling.

Verified on FreeBSD 15 VMs (aarch64, amd64, riscv64):
  kit cc -c / kit cc / kit ld -lc / kit cc -lm / kit cc -lpthread /
  kit ld -lm / kit cc -static all pass.
test-freebsd: 6/6 pass (static+dynamic metadata for all three arches).

</content>
</entry>
<entry>
<id>28f2a06838d8f794b707e3e6dd2f70eadd14fc02</id>
<published>2026-06-08T20:40:41Z</published>
<updated>2026-06-08T20:40:41Z</updated>
<title>ld: default to PIE for hosted dynamic links (-lc without -static)</title>
<link rel="alternate" type="text/html" href="commit/28f2a06838d8f794b707e3e6dd2f70eadd14fc02.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 28f2a06838d8f794b707e3e6dd2f70eadd14fc02
parent f082bcd0c6e5cfd8f98e04e80dec19f6a388f65b
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 13:40:41 -0700

ld: default to PIE for hosted dynamic links (-lc without -static)

kit ld -lc produced &quot;imported sym has no PLT entry (CALL26)&quot; because
the link_dyn path (PLT/GOT/.rela.plt) is only entered when lopts.pie
is set, and kit ld intentionally does not default to PIE the way
kit cc does.

Fix: when the hosted profile is active (-lc) and the link is dynamic
(not -static, not -shared, not -r), implicitly set pie=1 — matching
what kit cc does. Explicit -no-pie with -lc is rejected with a clear
error since non-PIE ET_EXEC dynamic linking is not yet supported.

</content>
</entry>
<entry>
<id>f082bcd0c6e5cfd8f98e04e80dec19f6a388f65b</id>
<published>2026-06-08T20:28:43Z</published>
<updated>2026-06-08T20:28:43Z</updated>
<title>freebsd: thread OS version, add cross-compile + VM verification</title>
<link rel="alternate" type="text/html" href="commit/f082bcd0c6e5cfd8f98e04e80dec19f6a388f65b.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit f082bcd0c6e5cfd8f98e04e80dec19f6a388f65b
parent 32b0908794ee78d4cfd76dea8a2856b6c45d6fe4
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 13:28:43 -0700

freebsd: thread OS version, add cross-compile + VM verification

- KitTargetSpec gains os_version_major (parsed from triple e.g. freebsd15.0→15)
  so hosted_add_freebsd_defines emits the real __FreeBSD_version instead of
  hardcoded 14.
- Add ucontext_t &lt;-&gt; KitUnwindFrame marshallers for all three arches
  (aarch64, x86_64, rv64) and wire them into mk/env.mk.
- mk/env.mk: add HOST_ENV_LDFLAGS (FreeBSD: -rdynamic so libc.so can
  resolve `environ` from the exe); mk/flags.mk splices it into HOST_LDFLAGS.
- scripts/freebsd_sysroot.sh: pull libthr.a/.so.3 and libpthread.so.3 from
  base.txz and create the libpthread → libthr symlinks that -lpthread needs.
- scripts/kit_freebsd.sh: cross-compile kit for a FreeBSD target arch via
  a wrapper script (avoids GNU make CC whitespace-split bug), auto-fetches
  the sysroot, supports `scp` and `run` to deploy via the FreeBSD VM.
- scripts/freebsd_vm.sh: add `scp &lt;arch&gt; &lt;src&gt; &lt;dst&gt;` subcommand.
- driver/env/freebsd.c: remove UNTESTED markers (verified on FreeBSD 15 aarch64 VM).
- doc/plan/FREEBSD.md: deleted (all work complete).

</content>
</entry>
<entry>
<id>32b0908794ee78d4cfd76dea8a2856b6c45d6fe4</id>
<published>2026-06-08T20:13:46Z</published>
<updated>2026-06-08T20:15:16Z</updated>
<title>docs: close out and remove the CODEGEN plan doc</title>
<link rel="alternate" type="text/html" href="commit/32b0908794ee78d4cfd76dea8a2856b6c45d6fe4.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 32b0908794ee78d4cfd76dea8a2856b6c45d6fe4
parent f5a4f04e3bf6b4fd9bd8929bfc657c3bf7be9e28
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 13:13:46 -0700

docs: close out and remove the CODEGEN plan doc

The CG API interface-cleanup roadmap is closed: PLACE/VALUE (Track 7),
op/intrinsic taxonomy (Track 4), atomic/order/AsmDir + fold isolation (Tracks
2-partial/6), and bitfields-as-place (3b) had landed; this pass removed
multi-value from the API (single result), added the conditional control-op tests
+ block-continue guard (Track 1c), and dropped the dead INTRIN_MEMCPY/MEMSET
(Track 4 tidy).

Track 2&#39;s remaining binop/cmp internal-enum dedup is intentionally not done: its
only behavioral win (lossy ordered/unordered FP compare) already landed, and the
merged internal BinOp/CmpOp/UnOp + the single isolated api_map_* is a defensible
normalized internal vocabulary woven through the i128/wide64/fold/delayed-arith
lowering. Remaining = zero-behavior churn, so the doc is retired rather than kept
open for it.

</content>
</entry>
<entry>
<id>f5a4f04e3bf6b4fd9bd8929bfc657c3bf7be9e28</id>
<published>2026-06-08T20:03:23Z</published>
<updated>2026-06-08T20:03:23Z</updated>
<title>Track 4: drop dead INTRIN_MEMCPY/INTRIN_MEMSET intrinsics</title>
<link rel="alternate" type="text/html" href="commit/f5a4f04e3bf6b4fd9bd8929bfc657c3bf7be9e28.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit f5a4f04e3bf6b4fd9bd8929bfc657c3bf7be9e28
parent 80ba21ae01667332bf937b70d209a0e73d690938
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 13:03:23 -0700

Track 4: drop dead INTRIN_MEMCPY/INTRIN_MEMSET intrinsics

memcpy/memset are dedicated public ops (kit_cg_memcpy/_memset) that lower to the
copy_bytes/set_bytes CgTarget hooks -&gt; CG_IR_AGG_COPY/AGG_SET -&gt; the backends&#39;
agg-copy/set paths (and IOP_AGG_COPY/SET in the interpreter). Only kit_cg_memmove
flows through the generic intrinsic hook (INTRIN_MEMMOVE). So the internal
IntrinKind values INTRIN_MEMCPY and INTRIN_MEMSET were never emitted anywhere —
&quot;two spellings of one behavior&quot; (CODEGEN.md Principle 7). Remove them and the dead
switch arms across all six backends (x64/aa64/riscv native, wasm, c_target, interp);
the memmove-only shapes that shared an arm keep their overlap-safe path.

(The C frontend&#39;s private cg_adapter.h INTRIN_MEM* enum is a separate namespace,
left untouched.)

Green: lib/bin/rt, cg-api (interp memmove), libc 9/0, parse + parse-err 128/0,
smoke x64/rv64.

</content>
</entry>
<entry>
<id>80ba21ae01667332bf937b70d209a0e73d690938</id>
<published>2026-06-08T19:52:35Z</published>
<updated>2026-06-08T19:52:35Z</updated>
<title>Track 1c: test conditional control ops + reject continue on block scope</title>
<link rel="alternate" type="text/html" href="commit/80ba21ae01667332bf937b70d209a0e73d690938.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 80ba21ae01667332bf937b70d209a0e73d690938
parent 106b8cb6c48dabf72df6804e4900cbdb39e836ca
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 12:52:35 -0700

Track 1c: test conditional control ops + reject continue on block scope

break_true / continue_true / continue_false have zero callers in any frontend
(toy uses only break / break_false / continue), so they were unexercised. Add
test/api/cg_control_test.c: builds `int f(int n)` returning sum(0..n-1) via each
conditional break/continue, runs all four through the in-process interpreter
across a spread of n, emits each across aa64/x64/rv64 at -O0/-O1, and checks the
new block-scope rejection.

Audit fix: kit_cg_continue/_true/_false jumped to s-&gt;continue_lbl unconditionally,
which is LABEL_NONE for a forward-only block scope (no loop header) — a jump to a
nonexistent label. Now rejected with a clean diagnostic via api_require_loop_scope.

Green: test-cg-api (cg_control_test 85/0), toy 1382/0, parse + parse-err.

</content>
</entry>
<entry>
<id>106b8cb6c48dabf72df6804e4900cbdb39e836ca</id>
<published>2026-06-08T19:39:29Z</published>
<updated>2026-06-08T19:39:29Z</updated>
<title>Remove multi-value from the CG API (single result)</title>
<link rel="alternate" type="text/html" href="commit/106b8cb6c48dabf72df6804e4900cbdb39e836ca.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 106b8cb6c48dabf72df6804e4900cbdb39e836ca
parent 1541d1cfc7b9638a91946f78a7d4ccae1630b644
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 12:39:29 -0700

Remove multi-value from the CG API (single result)

Multi-result functions (KitCgFuncSig.results[]/nresults, nresults&gt;1) were an
advertise-but-ignore facade: the public API accepted up to 16 results, but no
frontend produced more than one, there were zero tests, and every native
backend panicked (&quot;multiple returns unsupported&quot;) while the -O1 opt path and
wasm silently dropped extras. Per CODEGEN.md Principles 2/3, collapse the whole
surface to a single optional result (void == KIT_CG_TYPE_NONE) instead of
implementing ~1000 LOC nothing uses.

- Public: KitCgFuncSig.result (was results[]/nresults); kit_cg_type_func_result
  drops its index; removed kit_cg_type_func_nresults.
- Type system stores a single KitCgFuncResult; cg_type_func_result_id returns
  the raw result type (NONE for void) alongside cg_type_func_ret_id.
- CGFuncDesc.result_type / CGCallDesc.result (single CGLocal, CG_LOCAL_NONE =
  void); CgIrRetAux/value+present; OptCGFuncDesc.result_type. Removed
  API_CG_MAX_RESULTS, fn_result_types[], the call/ret loops.
- ret hooks collapse to a single value: CgTarget.ret(CGLocal),
  NativeTarget.plan_ret(value), NativeDirectTarget.emit_ret(CGLocal). Backend
  &quot;multiple returns unsupported&quot; panics removed. NativeCallDesc kept as a
  bounded (&lt;=1) array internally.
- c_target: dropped the tuple typedef machinery; single-result signatures/calls.
- Frontends (c/toy/wasm) build a single sig.result; wasm-spec multi-value
  (src/wasm, WasmType) is untouched.

Green: lib/bin/rt, cg-api, opt, toy 1382/0, parse 3784 + parse-err 128/0,
interp, abi-classify, ir-recorder, native-direct-target, tiny-inline, isa,
link, elf, smoke x64/rv64; bootstrap reproduces byte-identical (stage2==stage3).

</content>
</entry>
<entry>
<id>1541d1cfc7b9638a91946f78a7d4ccae1630b644</id>
<published>2026-06-08T18:42:52Z</published>
<updated>2026-06-08T18:42:52Z</updated>
<title>reloc: shrink reloc enum; neutral R_ABS8/16, R_PREL16, R_TPOFF64; rename R_RV_ADD*/SUB*/SET* to arch-neutral</title>
<link rel="alternate" type="text/html" href="commit/1541d1cfc7b9638a91946f78a7d4ccae1630b644.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 1541d1cfc7b9638a91946f78a7d4ccae1630b644
parent 47cede9aca1511ee8a697c37bbf98aab26bb4ee3
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 11:42:52 -0700

reloc: shrink reloc enum; neutral R_ABS8/16, R_PREL16, R_TPOFF64; rename R_RV_ADD*/SUB*/SET* to arch-neutral

</content>
</entry>
<entry>
<id>47cede9aca1511ee8a697c37bbf98aab26bb4ee3</id>
<published>2026-06-08T18:39:35Z</published>
<updated>2026-06-08T18:39:35Z</updated>
<title>plan: clean out completed plans</title>
<link rel="alternate" type="text/html" href="commit/47cede9aca1511ee8a697c37bbf98aab26bb4ee3.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 47cede9aca1511ee8a697c37bbf98aab26bb4ee3
parent 0ae44208d15bba91c4d3a9188848cb3871bf02bd
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 11:39:35 -0700

plan: clean out completed plans

</content>
</entry>
<entry>
<id>0ae44208d15bba91c4d3a9188848cb3871bf02bd</id>
<published>2026-06-08T18:32:25Z</published>
<updated>2026-06-08T18:32:25Z</updated>
<title>rv32: close out riscv32-none-elf; remove completed plan doc</title>
<link rel="alternate" type="text/html" href="commit/0ae44208d15bba91c4d3a9188848cb3871bf02bd.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 0ae44208d15bba91c4d3a9188848cb3871bf02bd
parent be9be587a0b6e6599ed17c6764e1da2d93f042ec
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 11:32:25 -0700

rv32: close out riscv32-none-elf; remove completed plan doc

The riscv32-none-elf backend is complete — all cross lanes pass at O0+O1
(test-asm-rv32 16/0, test-toy-rv32 421/0, test-parse-rv32 906/0, smoke
hardfloat green under qemu-system-riscv32). The forward-looking plan in
doc/plan/RV32.md is fully realized, so remove it and its index row (per
convention, completed plans are removed, not checked off), and move the
two durable contracts it tracked into user-facing docs:

- doc/RUNTIME.md: the freestanding TLS thread-pointer contract
  ([TCB(16)|.tdata|.tbss], tp-&gt;TCB base, Local-Exec only; linker bias via
  ObjElfArchOps.tls_tp_bias) and the i64-atomics-as-libcall note (8-byte
  _Atomic -&gt; spinlock __atomic_*_8, correct but not lock-free).
- mk/test.mk: refresh the rv32 lane comments (corpus green; opt-in like
  the rv64 cross lanes, kept out of DEFAULT_TEST_TARGETS because they
  need the qemu-system-riscv32 toolchain).

Docs and comments only; no code change.

</content>
</entry>
<entry>
<id>be9be587a0b6e6599ed17c6764e1da2d93f042ec</id>
<published>2026-06-08T18:15:00Z</published>
<updated>2026-06-08T18:15:00Z</updated>
<title>plan: refresh doc index</title>
<link rel="alternate" type="text/html" href="commit/be9be587a0b6e6599ed17c6764e1da2d93f042ec.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit be9be587a0b6e6599ed17c6764e1da2d93f042ec
parent 86d3164a20fead7c9b3e92932a861a271d915e42
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Mon,  8 Jun 2026 11:15:00 -0700

plan: refresh doc index

</content>
</entry>
<entry>
<id>86d3164a20fead7c9b3e92932a861a271d915e42</id>
<published>2026-06-06T12:17:20Z</published>
<updated>2026-06-08T17:55:16Z</updated>
<title>docs: plan llgen import</title>
<link rel="alternate" type="text/html" href="commit/86d3164a20fead7c9b3e92932a861a271d915e42.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 86d3164a20fead7c9b3e92932a861a271d915e42
parent 9fd3adda7106605e23b78d7c85f1237f1ea67801
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 05:17:20 -0700

docs: plan llgen import

</content>
</entry>
<entry>
<id>9fd3adda7106605e23b78d7c85f1237f1ea67801</id>
<published>2026-06-06T11:53:54Z</published>
<updated>2026-06-06T11:53:54Z</updated>
<title>Fix nested panic recovery</title>
<link rel="alternate" type="text/html" href="commit/9fd3adda7106605e23b78d7c85f1237f1ea67801.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 9fd3adda7106605e23b78d7c85f1237f1ea67801
parent cb8e08d7d89c0ce544883b60d2d04a5c883df51e
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 04:53:54 -0700

Fix nested panic recovery

</content>
</entry>
<entry>
<id>cb8e08d7d89c0ce544883b60d2d04a5c883df51e</id>
<published>2026-06-06T11:41:35Z</published>
<updated>2026-06-06T11:41:35Z</updated>
<title>Fix -no-pie overriding explicit PIE</title>
<link rel="alternate" type="text/html" href="commit/cb8e08d7d89c0ce544883b60d2d04a5c883df51e.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit cb8e08d7d89c0ce544883b60d2d04a5c883df51e
parent 8b8960344ffcc9a12161a218fece7e8bf2beaf8b
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 04:41:35 -0700

Fix -no-pie overriding explicit PIE

</content>
</entry>
<entry>
<id>8b8960344ffcc9a12161a218fece7e8bf2beaf8b</id>
<published>2026-06-06T11:33:21Z</published>
<updated>2026-06-06T11:33:21Z</updated>
<title>Keep volatile locals memory resident</title>
<link rel="alternate" type="text/html" href="commit/8b8960344ffcc9a12161a218fece7e8bf2beaf8b.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 8b8960344ffcc9a12161a218fece7e8bf2beaf8b
parent c8b9d53d52c4d396b6caed50da9e576413595199
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 04:33:21 -0700

Keep volatile locals memory resident

</content>
</entry>
<entry>
<id>c8b9d53d52c4d396b6caed50da9e576413595199</id>
<published>2026-06-06T11:15:28Z</published>
<updated>2026-06-06T11:15:28Z</updated>
<title>Fix hard-pinned native inline asm staging</title>
<link rel="alternate" type="text/html" href="commit/c8b9d53d52c4d396b6caed50da9e576413595199.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit c8b9d53d52c4d396b6caed50da9e576413595199
parent 96de8d734d0490c3e537ec6950c325e51015df59
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 04:15:28 -0700

Fix hard-pinned native inline asm staging

</content>
</entry>
<entry>
<id>96de8d734d0490c3e537ec6950c325e51015df59</id>
<published>2026-06-06T10:52:37Z</published>
<updated>2026-06-06T10:52:37Z</updated>
<title>Fix C inline asm output type stack</title>
<link rel="alternate" type="text/html" href="commit/96de8d734d0490c3e537ec6950c325e51015df59.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 96de8d734d0490c3e537ec6950c325e51015df59
parent 44b5521e6ab0bdb348582ec7fe080e7ff6e36704
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 03:52:37 -0700

Fix C inline asm output type stack

</content>
</entry>
<entry>
<id>44b5521e6ab0bdb348582ec7fe080e7ff6e36704</id>
<published>2026-06-06T10:34:19Z</published>
<updated>2026-06-06T10:34:19Z</updated>
<title>Support arch inline asm machine constraints</title>
<link rel="alternate" type="text/html" href="commit/44b5521e6ab0bdb348582ec7fe080e7ff6e36704.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 44b5521e6ab0bdb348582ec7fe080e7ff6e36704
parent 69d47850d76ff863e4493092346bd41f5c1f6574
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Sat,  6 Jun 2026 03:34:19 -0700

Support arch inline asm machine constraints

</content>
</entry>
<entry>
<id>69d47850d76ff863e4493092346bd41f5c1f6574</id>
<published>2026-06-06T05:20:17Z</published>
<updated>2026-06-06T05:20:17Z</updated>
<title>Implement raw syscall intrinsic lowering</title>
<link rel="alternate" type="text/html" href="commit/69d47850d76ff863e4493092346bd41f5c1f6574.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 69d47850d76ff863e4493092346bd41f5c1f6574
parent e55665b3c5ce178b17e7838c903429bf62eaf2cc
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 22:20:17 -0700

Implement raw syscall intrinsic lowering

</content>
</entry>
<entry>
<id>e55665b3c5ce178b17e7838c903429bf62eaf2cc</id>
<published>2026-06-06T04:34:21Z</published>
<updated>2026-06-06T04:34:21Z</updated>
<title>Fix O1 label-address block liveness</title>
<link rel="alternate" type="text/html" href="commit/e55665b3c5ce178b17e7838c903429bf62eaf2cc.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit e55665b3c5ce178b17e7838c903429bf62eaf2cc
parent 09bf3f299ea580495f0b4ce4a88dcacfe7a10f31
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 21:34:21 -0700

Fix O1 label-address block liveness

</content>
</entry>
<entry>
<id>09bf3f299ea580495f0b4ce4a88dcacfe7a10f31</id>
<published>2026-06-06T04:12:01Z</published>
<updated>2026-06-06T04:12:01Z</updated>
<title>Fix tail sret forwarding</title>
<link rel="alternate" type="text/html" href="commit/09bf3f299ea580495f0b4ce4a88dcacfe7a10f31.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 09bf3f299ea580495f0b4ce4a88dcacfe7a10f31
parent d11c5c90c2371c2d260a161f8f7d61fc30824615
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 21:12:01 -0700

Fix tail sret forwarding

</content>
</entry>
<entry>
<id>d11c5c90c2371c2d260a161f8f7d61fc30824615</id>
<published>2026-06-06T04:01:51Z</published>
<updated>2026-06-06T04:01:51Z</updated>
<title>Teach ld -lc to use hosted libc</title>
<link rel="alternate" type="text/html" href="commit/d11c5c90c2371c2d260a161f8f7d61fc30824615.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit d11c5c90c2371c2d260a161f8f7d61fc30824615
parent 809a8e5e87c71ee3f3213e7e6f1f31eb972b70da
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 21:01:51 -0700

Teach ld -lc to use hosted libc

</content>
</entry>
<entry>
<id>809a8e5e87c71ee3f3213e7e6f1f31eb972b70da</id>
<published>2026-06-06T04:00:54Z</published>
<updated>2026-06-06T04:00:54Z</updated>
<title>Fix aarch64 COFF weak-null ADRP relocation</title>
<link rel="alternate" type="text/html" href="commit/809a8e5e87c71ee3f3213e7e6f1f31eb972b70da.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 809a8e5e87c71ee3f3213e7e6f1f31eb972b70da
parent e87c69019725a0c08d8a1329614ac3e519758d9e
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 21:00:54 -0700

Fix aarch64 COFF weak-null ADRP relocation

</content>
</entry>
<entry>
<id>e87c69019725a0c08d8a1329614ac3e519758d9e</id>
<published>2026-06-06T02:39:59Z</published>
<updated>2026-06-06T02:39:59Z</updated>
<title>Add freestanding runtime ctype</title>
<link rel="alternate" type="text/html" href="commit/e87c69019725a0c08d8a1329614ac3e519758d9e.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit e87c69019725a0c08d8a1329614ac3e519758d9e
parent 85ca53b7d3dfe775399b30f30a1531c64d6c4726
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 19:39:59 -0700

Add freestanding runtime ctype

</content>
</entry>
<entry>
<id>85ca53b7d3dfe775399b30f30a1531c64d6c4726</id>
<published>2026-06-06T02:26:02Z</published>
<updated>2026-06-06T02:26:02Z</updated>
<title>Fix rv64 toy TLS cross startup</title>
<link rel="alternate" type="text/html" href="commit/85ca53b7d3dfe775399b30f30a1531c64d6c4726.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 85ca53b7d3dfe775399b30f30a1531c64d6c4726
parent 0493f0042030ecca28f7d0d67039372cf165a4b8
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 19:26:02 -0700

Fix rv64 toy TLS cross startup

</content>
</entry>
<entry>
<id>0493f0042030ecca28f7d0d67039372cf165a4b8</id>
<published>2026-06-06T02:04:57Z</published>
<updated>2026-06-06T02:04:57Z</updated>
<title>Partition the relocation byte-patcher per-arch (RELOC WS-C)</title>
<link rel="alternate" type="text/html" href="commit/0493f0042030ecca28f7d0d67039372cf165a4b8.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 0493f0042030ecca28f7d0d67039372cf165a4b8
parent 65545dc2cc2be1f6fb2de2149e2702a267aa7960
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 19:04:57 -0700

Partition the relocation byte-patcher per-arch (RELOC WS-C)

Move the per-arch instruction-immediate relocation byte encoders out of the
format-neutral src/obj/reloc_apply.c into each backend&#39;s reloc.c, reached
through a new LinkArchDesc.reloc_apply_insn hook, while keeping
link_reloc_apply as the single public byte-patcher entry. Adding an arch&#39;s
relocation is now arch-local: one RelocDesc row (WS-B) + one reloc_apply_insn
arm + one wire-translator entry, no generic src/link or src/obj edit.

- src/arch/{aa64,x64,riscv}/reloc.c: *_reloc_apply_insn — the imm19/imm26/
  ADRP-page (aa64), U/I/S/B/J + RVC scatter &amp; +0x800 bias (rv), and rel8 (x64)
  encoders, moved verbatim. Wired into each LinkArchDesc in link.c.
- src/obj/reloc_apply.c: reloc_apply_neutral() keeps the arch-neutral data-word
  + ULEB128 arms (R_ABS/REL/PC/TPOFF writes, x64 GOT/dynamic slots, RISC-V data
  ADD/SUB/SET). Pure obj-core, no link/arch dependency.
- src/link/link_reloc_apply.c (new): link_reloc_apply() dispatcher, neutral-
  then-arch. Lives in src/link (not obj-core) because resolving the per-arch
  slice needs link_arch_desc_for() — same boundary reason WS-B placed
  reloc_desc() in src/link. The dispatcher enumerates no kinds:
  `rg &quot;case R_(AARCH64|X64|RV)_&quot; src/link` is empty.

R_PLT32&#39;s apply is the RISC-V AUIPC+JALR pair (x64 emits R_X64_PLT32 on read,
never canonical R_PLT32), so it lives in the rv hook beside R_RV_CALL — not
neutral, despite its neutral name. x64 owns only R_X64_PC8; the wider x64
GOT/PLT/TPOFF data slots stay neutral.

Migration guard: test/link/reloc_apply_test.c (test-link-reloc-apply, 50 frozen
pre-WS-C byte checks across aa64/x64/rv). Verified byte-identical: full
link/elf/macho/ar/asm/isa/opt/coff/smoke matrix + bootstrap-debug (stage2 ==
stage3). reloc_uleb128_unit&#39;s c=NULL path still works (neutral never touches the
compiler).

Also refresh test/smoke/rv64_tls_link.sh&#39;s reloc grep (RV_TPREL_HI20 -&gt;
R_RISCV_TPREL_HI20): WS-E.3 switched ELF reloc records to binutils spellings but
missed this script, and R_RISCV_TPREL_HI20 doesn&#39;t contain the old substring.

</content>
</entry>
<entry>
<id>65545dc2cc2be1f6fb2de2149e2702a267aa7960</id>
<published>2026-06-05T23:31:53Z</published>
<updated>2026-06-05T23:31:53Z</updated>
<title>Implement per-arch RelocDesc table + residual gates (RELOC WS-B, WS-E.2/E.3)</title>
<link rel="alternate" type="text/html" href="commit/65545dc2cc2be1f6fb2de2149e2702a267aa7960.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 65545dc2cc2be1f6fb2de2149e2702a267aa7960
parent 7a985cce08172385f81d3fa7e74540ffc3ed037a
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 16:31:53 -0700

Implement per-arch RelocDesc table + residual gates (RELOC WS-B, WS-E.2/E.3)

WS-B — make the canonical-RelocKind half of the relocation subsystem as
modular as the wire half. Replace the generic reloc_width / reloc_uses_got /
reloc_is_tls_got switches in link_reloc_layout.c, link_jit&#39;s
jit_reloc_width_local, and the five per-arch LinkArchDesc.is_* hooks with a
single per-arch RelocDesc {u8 width; u8 flags} resolved arch-aware by
reloc_desc(c, k):
  - neutral data-word kinds in src/obj/reloc.{h,c} (pure obj-core);
  - per-arch slices in src/arch/{aa64,x64,riscv}/reloc.c via a new
    LinkArchDesc.reloc_desc hook;
  - dispatcher + reloc_kind_* predicates in src/link/link_reloc_desc.{h,c}
    (kept in src/link, not obj-core, since resolving the slice needs
    link_arch_desc_for()).
All consumers (the GOT / JIT-stub / width passes and the nine Mach-O is_*
call sites) now read one descriptor flag. Adding an arch&#39;s relocation is one
row in that arch&#39;s slice. Migration guard: test/link/reloc_desc_test.c pins
behavioural equivalence to frozen oracle_* snapshots of the deleted code
across every kind x every backend arch (3016 checks).

WS-E.2 — the static-IFUNC __rela_iplt IRELATIVE wire type no longer names a
literal KIT_OBJ_ELF: link_elf_irelative_type is gone, replaced by
obj_format_static_ifunc_irelative_type(c) (sibling of the WS-E.1 predicate),
which resolves through the target object format.

WS-E.3 — drop the arch axis from kit_obj_reloc_kind_name&#39;s gate
(fmt != KIT_OBJ_ELF only), so aarch64/riscv ELF relocs print via their
ObjElfArchOps.reloc_name tables (binutils-faithful: R_AARCH64_CALL26,
R_RISCV_CALL). One objdump golden refreshed; the -d disasm annotation keeps
the arch-neutral spelling (separate disassembler path).

rg &quot;case R_(AARCH64|X64|RV)_&quot; src/link is now empty. Verified: reloc_desc
parity 3016/0, test-link/elf/macho/ar/isa/aa64-inline/driver-objdump pass,
make bootstrap-debug byte-identical.

</content>
</entry>
<entry>
<id>7a985cce08172385f81d3fa7e74540ffc3ed037a</id>
<published>2026-06-05T23:30:15Z</published>
<updated>2026-06-05T23:30:15Z</updated>
<title>Defer O1 local static data symbols</title>
<link rel="alternate" type="text/html" href="commit/7a985cce08172385f81d3fa7e74540ffc3ed037a.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 7a985cce08172385f81d3fa7e74540ffc3ed037a
parent 81d88fcf49dea5f3f1d389ac360bf7c588c9d3ff
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 16:30:15 -0700

Defer O1 local static data symbols

</content>
</entry>
<entry>
<id>81d88fcf49dea5f3f1d389ac360bf7c588c9d3ff</id>
<published>2026-06-05T22:10:41Z</published>
<updated>2026-06-05T22:10:41Z</updated>
<title>Add stack backtrace sources to driver rt manifest</title>
<link rel="alternate" type="text/html" href="commit/81d88fcf49dea5f3f1d389ac360bf7c588c9d3ff.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 81d88fcf49dea5f3f1d389ac360bf7c588c9d3ff
parent bad3d6b438f65e991b1aaa1845c0aeb7651158a0
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 15:10:41 -0700

Add stack backtrace sources to driver rt manifest

The backtrace work (b3f14e4e) made rt/lib/assert/assert.c call
__kit_print_backtrace() and added stack/{backtrace,print_backtrace}.c,
updating the Makefile rt build (RT_BASE_SRCS) but not the driver&#39;s
on-demand rt manifest in driver/lib/runtime.c. So `kit cc`&#39;s auto-built
rt archive carried assert.c without the two sources it now needs,
producing &quot;undefined reference to &#39;__kit_print_backtrace&#39;&quot; whenever a
link pulled assert.c (e.g. test-driver&#39;s cc-auto-builds-and-links-
libkit-rt-x64).

Add stack/backtrace.c + stack/print_backtrace.c to every full-libc
driver list (x64, aarch64-elf/darwin, rv64-elf, rv32-elf), realigning
with RT_BASE_SRCS. The compiler-rt-only Windows lists omit assert.c, so
they stay unchanged.

</content>
</entry>
<entry>
<id>bad3d6b438f65e991b1aaa1845c0aeb7651158a0</id>
<published>2026-06-05T22:03:38Z</published>
<updated>2026-06-05T22:03:38Z</updated>
<title>doc/plan: rescope RELOC.md after the modularity waves landed</title>
<link rel="alternate" type="text/html" href="commit/bad3d6b438f65e991b1aaa1845c0aeb7651158a0.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit bad3d6b438f65e991b1aaa1845c0aeb7651158a0
parent b499c2351e3bc118a107a8693d35413c6e8e0db3
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 15:03:38 -0700

doc/plan: rescope RELOC.md after the modularity waves landed

The reloc-path identity switches are already gone (LinkArchDesc.tpoff64_reloc
for #25, obj_format_static_ifunc_via_rela_iplt for #18) and the reloc-name
table moved onto ObjElfArchOps.reloc_name (#24, still x86_64-ELF-gated for
objdump golden compat). Mark those as landed and rescope the open work to the
structural denormalization that remains: a per-arch RelocDesc {width, flags}
table replacing the generic reloc_width / reloc_uses_got / reloc_is_tls_got
switches (and the duplicating LinkArchDesc.is_* hooks), and partitioning
link_reloc_apply&#39;s encoders into the arch backends behind the single entry.

</content>
</entry>
<entry>
<id>b499c2351e3bc118a107a8693d35413c6e8e0db3</id>
<published>2026-06-05T21:45:54Z</published>
<updated>2026-06-05T21:49:14Z</updated>
<title>Implement tool-side auto-backtrace for run &amp; dbg (BACKTRACE L3c/WS5)</title>
<link rel="alternate" type="text/html" href="commit/b499c2351e3bc118a107a8693d35413c6e8e0db3.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit b499c2351e3bc118a107a8693d35413c6e8e0db3
parent 21ac717e705ac204fb507e83fa04f467397a494a
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 14:45:54 -0700

Implement tool-side auto-backtrace for run &amp; dbg (BACKTRACE L3c/WS5)

`kit run` and `kit dbg` now print a symbolized backtrace automatically when a
program faults or traps, reusing the hosted DWARF reader and never crossing into
rt/.

The CFI stepper kit_dwarf_unwind_step takes no memory provider, so it returns
pc=0 once a return address is spilled to the stack (the common case) — the old
`dbg bt` was effectively single-frame. Replace the unwind with a frame-pointer
chain walk: kit keeps a frame pointer on every backend with a uniform record
(fp[0]=caller fp, fp[1]=saved ra), the same walk __kit_backtrace does, lifted
tool-side with a memory-read callback.

- driver/lib/backtrace.{c,h}: shared FP-step kernel (with __kit_backtrace&#39;s
  guards), arch FP-reg/ptr-size helpers, and a PC-list symbolized printer. The
  walk stops at the kit-image boundary (kit_jit_runtime_to_image==0) so output
  ends at main and is host-independent (no libc/dyld trampoline noise).
- dbg (driver/cmd/dbg.c): dbg_cmd_bt advances via the FP kernel over
  kit_jit_session_read_mem (walks the whole stack), and dbg_render_stop
  auto-invokes it on KIT_STOP_SIGNAL (faults + __builtin_trap/assert, not
  breakpoints/steps).
- run (driver/cmd/run.c + driver/env/posix_dbg.c): a lightweight crash guard
  installs SIGSEGV/SIGBUS/SIGILL/SIGFPE/SIGABRT/SIGTRAP handlers around the
  in-process entry_fn call, reusing dbg_ucontext_to_frame. Because run shares
  its stack with the program, the chain is captured inside the handler (before
  the post-siglongjmp stack is reused) and symbolized afterward in normal
  context; the process exits 128+signo. Windows has a no-op stub.
- backtrace.c is compiled unconditionally: posix_dbg.c&#39;s crash guard references
  it on every POSIX build regardless of tool selection.

Tests: test/dbg/cases/toy-trap-backtrace (multi-frame trap -&gt; auto-bt + bt),
updated toy-trap-stop golden, and run-backtrace-* checks in test/driver/run.sh.

kit emu auto-backtrace is out of scope (it doesn&#39;t retain the guest DWARF);
deferred alongside L3b.

</content>
</entry>
<entry>
<id>21ac717e705ac204fb507e83fa04f467397a494a</id>
<published>2026-06-05T16:49:29Z</published>
<updated>2026-06-05T21:49:14Z</updated>
<title>Implement kit symbolize (BACKTRACE L3a/WS5)</title>
<link rel="alternate" type="text/html" href="commit/21ac717e705ac204fb507e83fa04f467397a494a.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 21ac717e705ac204fb507e83fa04f467397a494a
parent b3f14e4ecb76fed2930be28041e7e68a692b073f
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 09:49:29 -0700

Implement kit symbolize (BACKTRACE L3a/WS5)

Add `kit symbolize`, the hosted batching symbolizer that matches kit&#39;s
actual backtrace artifact: it reads the raw &quot;#N 0x&lt;hex&gt;&quot; stream that
__kit_print_backtrace emits, finds the address on each line, resolves it
through the existing DWARF reader, and rewrites the line in place as

    #0 0x401136 bt_leaf at addr2line_prog.c:51:3

preserving the &quot;#N&quot; framing that addr2line structurally can&#39;t keep.
Lines with no 0x&lt;hex&gt; token pass through verbatim, so a mixed panic log
(banner + frames + register dump) survives unharmed.

addr2line stays a faithful GNU/LLVM clone (bare addresses in, file:line
out); its output contract is unchanged. The DWARF-open + func/line core
is factored into driver/lib/dwarfsym.c, shared by both tools, which now
differ only in formatting. symbolize is a non-default (GROUP_OTHER) tool
like mc/disas; a single -e today, with multi--e/module-map (for libc.so
frames that need their own load slide) as the natural extension.

Testing: test/rt/addr2line.sh (make target test-rt-backtrace) grows a
second lane per arch/opt — it pipes the captured stream into
`kit symbolize -e &lt;exe&gt;` and asserts each frame keeps its &quot;#N 0x..&quot; form
with &quot;&lt;func&gt; at file:line&quot; appended. aa64/x64/rv64 at O0/O1; the x64/O1
lane stays the documented pre-existing -g -O1 compiler red (cc aborts
before producing a binary, so it never reaches symbolization).

</content>
</entry>
<entry>
<id>b3f14e4ecb76fed2930be28041e7e68a692b073f</id>
<published>2026-06-05T16:26:10Z</published>
<updated>2026-06-05T21:49:14Z</updated>
<title>Implement __kit_print_backtrace &amp; assert hook (BACKTRACE L3a/WS4)</title>
<link rel="alternate" type="text/html" href="commit/b3f14e4ecb76fed2930be28041e7e68a692b073f.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit b3f14e4ecb76fed2930be28041e7e68a692b073f
parent 5a7a304b5a1d6dd328cc662759c895feebb5340c
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 09:26:10 -0700

Implement __kit_print_backtrace &amp; assert hook (BACKTRACE L3a/WS4)

Ship L3a of the backtrace roadmap: raw backtrace print + out-of-process
symbolization, plus the deferred assert-path hook.

- rt/lib/stack/print_backtrace.c: __kit_print_backtrace walks via
  __kit_backtrace(skip=1) and writes &quot;#N 0x&lt;hex&gt;&quot; lines (hand-rolled
  fmt, no printf) to the weak no-op __kit_backtrace_write sink. Both
  decls in rt/include/kit/backtrace.h; added to RT_BASE_SRCS.
- rt/lib/assert/assert.c: __kit_assert_fail emits a banner +
  __kit_print_backtrace() before __builtin_trap(), via the same sink.
- Resolves the L3a open question: weak no-op sink default (host/_start
  overrides to write(2)), so freestanding images still link.

Tests (aa64/x64/rv64, O0 + O1):
- test/rt/cases/print_backtrace.c: in-process parse of the emitted lines.
- test/rt/addr2line.sh + addr2line_prog.c: kit addr2line round-trip
  (make target test-rt-backtrace).
- test/rt/run.sh now sweeps O0+O1 (KIT_RT_OPT_LEVELS); smoke.c includes
  &lt;kit/backtrace.h&gt;.

The backtrace path passes at O0 and O1 on all three arches. Sweeping O1
surfaced two unrelated pre-existing bugs, left RED (not skipped) and
logged in doc/plan/TODO.md:
- x86-64 -g -O1 + 4-operand register-pinned syscall asm aborts the
  compiler (too many memory asm operands); fails test-rt-backtrace x64/O1.
- setjmp/longjmp miscompiled at -O1 on every arch (second-return value
  not observed); fails test-rt-runtime setjmp_runtime/O1.

</content>
</entry>
<entry>
<id>5a7a304b5a1d6dd328cc662759c895feebb5340c</id>
<published>2026-06-05T15:38:50Z</published>
<updated>2026-06-05T21:49:14Z</updated>
<title>Implement stack-trace builtins &amp; __kit_backtrace (BACKTRACE L1+L2)</title>
<link rel="alternate" type="text/html" href="commit/5a7a304b5a1d6dd328cc662759c895feebb5340c.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 5a7a304b5a1d6dd328cc662759c895feebb5340c
parent 14e3792d88237772be6076f14a77103d5ea746f8
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 08:38:50 -0700

Implement stack-trace builtins &amp; __kit_backtrace (BACKTRACE L1+L2)

L1 — __builtin_frame_address / __builtin_return_address: two CG intrinsics
(KIT_CG_INTRIN_FRAME_ADDRESS/_RETURN_ADDRESS) carrying the constant level as
an IMM operand, lowered as an unrolled frame-pointer walk on aarch64/x86-64/
riscv (O0 and O1, shared backend handler). C target forwards __builtin_* to
the host; wasm reports unsupported; the C frontend validates the level via
eval_const_int. IR_INTRINSIC is already conservatively side-effecting in opt,
so no new effect modeling was needed; the one O1 hazard — riscv&#39;s frameless-
leaf tier omitting the frame record — is handled by a new
NativeKnownFrameDesc.reads_frame flag (aarch64/x64 always keep the record).

L2 — __kit_backtrace(void**, int, int): freestanding FP-walk capture in
rt/lib/stack/backtrace.c + rt/include/kit/backtrace.h, added to RT_BASE_SRCS.
kit&#39;s frame layout is uniform across targets (fp[0]=caller fp, fp[1]=saved
ra in void* units), so no per-arch offset table — the psABI rv64 layout in
the plan sketch was wrong; verified against the actual prologue.

Tests: test/rt/cases/backtrace_capture.c (aa64/x64/rv64 under exec),
test/parse builtin_29..31 + cases_err/..._nonconst (D/R/E/J/C lanes, O0/O1),
test/toy 154_frame_return_address. Verified end-to-end through kit addr2line
on static-freestanding and dynamic-musl binaries across all three arches.

doc/plan/BACKTRACE.md updated (L1+L2 done, L3 remaining). doc/plan/TODO.md
records four pre-existing gaps found while building/verifying: &amp;&amp;label-as-value
broken at O1, __kit_syscallN declared-but-unimplemented, -no-pie not producing
ET_EXEC, and kit cc/ld dynamic-libc link ergonomics.

</content>
</entry>
<entry>
<id>14e3792d88237772be6076f14a77103d5ea746f8</id>
<published>2026-06-05T21:47:44Z</published>
<updated>2026-06-05T21:47:44Z</updated>
<title>modularity: gate COFF weak-extern underscore alias on a vtable capability + fix stale objdump golden</title>
<link rel="alternate" type="text/html" href="commit/14e3792d88237772be6076f14a77103d5ea746f8.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 14e3792d88237772be6076f14a77103d5ea746f8
parent 769d6ae1ab02a5531923e468ed1a64d69cc3456d
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 14:47:44 -0700

modularity: gate COFF weak-extern underscore alias on a vtable capability + fix stale objdump golden

- src/link/link_resolve.c: the mingw single-underscore weak-external alias recovery now gates on a
  new ObjFormatImpl.weak_extern_underscore_alias (COFF=1) via obj_format_weak_extern_underscore_alias(),
  replacing the last  identity switch in generic link code. The PE-specific
  de/re-underscore mechanism stays, but only formats that declare the capability run it. Provably
  equivalent (1 for COFF, 0 elsewhere).
- test/objdump/aarch64/cases/04-disasm-stripped-segment.expected: refresh the stale golden to the
  disassembler&#39;s canonical alias output (sxtw x8, w9) for bytes 28 7d 40 93; sbfm xd,xn,#0,#31 IS SXTW,
  matching binutils/LLVM. (Was failing identically on baseline 30367860 — a pre-existing stale golden,
  not a regression.)

test-driver-objdump 14/0 (was 13/1); test-link 122/0, elf 41/0, ar 20/20, smoke x64+rv64 green.

</content>
</entry>
<entry>
<id>769d6ae1ab02a5531923e468ed1a64d69cc3456d</id>
<published>2026-06-05T18:51:56Z</published>
<updated>2026-06-05T18:51:56Z</updated>
<title>modularity wave 4: compiler-free language resolution + obj-owned fmt names + jit TLS hook</title>
<link rel="alternate" type="text/html" href="commit/769d6ae1ab02a5531923e468ed1a64d69cc3456d.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 769d6ae1ab02a5531923e468ed1a64d69cc3456d
parent 757fa31e7ccda6059b00c27ab30ee4e9b56881b3
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 11:51:56 -0700

modularity wave 4: compiler-free language resolution + obj-owned fmt names + jit TLS hook

Closes the last residuals from the audit:
- #6/#7: kit_language_for_name/_for_path/_name + new kit_language_default_extension now accept a
  NULL compiler and resolve against the compile-time default frontend set via a new
  lang_registry_vtable() (kept in lang_registry.c, the one place that checks KIT_LANG_*_ENABLED).
  This unblocks arg-parse-time use. A single driver_path_is_source() authority (registry lookup
  minus C headers) now backs cc/build/run-dbg source classification, replacing four hand-rolled
  extension unions; fixes the latent .S-misclassification bug and keeps the documented
  &#39;.h is a header, not a source&#39; rule in one place. -x names + dbg REPL filenames route through
  the resolvers (driver/cmd/{cc,build,dbg,emu}.c).
- #35: objcopy/objdump get canonical format names from the obj layer (kit_obj_fmt_from_name/_name),
  keeping only the binutils BFD-alias prefix matching + bitwidth suffix as documented tool presentation.
- Beyond the 36 findings, in the same spirit: src/link/link_jit.c Mach-O TLV JIT bootstrap now gates on
  obj_format_tls_via_descriptor instead of target.obj==KIT_OBJ_MACHO.

Build + tests green: link 122, driver-cc 98, build 56, tools 45, objcopy 5, ar 6, toy 1378,
smoke x64+rv64. (Pre-existing, unrelated: objdump aarch64/04-disasm-stripped-segment stale golden —
fails identically on baseline 30367860; untouched disassembler, fixed fixture.)

</content>
</entry>
<entry>
<id>757fa31e7ccda6059b00c27ab30ee4e9b56881b3</id>
<published>2026-06-05T18:13:53Z</published>
<updated>2026-06-05T18:13:53Z</updated>
<title>modularity wave 3: route frontend/driver/backend consumers through hooks</title>
<link rel="alternate" type="text/html" href="commit/757fa31e7ccda6059b00c27ab30ee4e9b56881b3.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 757fa31e7ccda6059b00c27ab30ee4e9b56881b3
parent c9c1495aa91c311d916704f17cd3c9f0a79079af
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 11:13:53 -0700

modularity wave 3: route frontend/driver/backend consumers through hooks

C frontend + preprocessor (P2): c_abi_va_list_type -&gt; kit_cg_target_va_list_kind (#1, also
fixes a latent win64 va_list-type bug); __builtin___clear_cache -&gt; backend ICACHE_COHERENT
feature (#5); kit_target_uses_lp64/long_double_is_binary128/ty_wchar -&gt; resolved spec fields
(#33,#3,#32); pp.c Windows/_M_* predefines consolidated into one os-keyed function reading
spec.wchar_size/long_size + kit_cg_target_c_label_prefix (#20).

Driver (P3): HostedProfile (os,obj) registry replaces the if/else+switch dispatch (#19); new
driver_default_exe_name/obj_ext/needs_sysroot_libdir/default_hosted_profile helpers replace the
os==WINDOWS forks in cc.c/build.c (#34); emu arch via driver_arch_from_name single authority
(#22); dbg REPL caching via frontend caps (#8); build.c lang-&gt;name reverse maps via
kit_language_name (#26).

Backend: x64/aa64 TEB-TLS selection via obj_format_tls_model (#15); aa64 variadic FP class via
ABIFuncInfo.vararg_fp_via_int (#16); mc.c .eh_frame via spec.emits_eh_frame (#17); c_target
underscore strip via obj_format_demangle_c (#10); c_target alias/weak/TLS spellings via new
ObjFormatImpl.alias_via_thunk/weak_undef_attr + obj_format_tls_via_descriptor (#27).

Residual (tracked): parse-time -x/source-ext classifiers (#6/#7) need compiler-free resolvers;
objcopy/objdump (#35) need BFD-alias fmt names — both addressed next.

Full suite green: parse/pp/toy/cg-api/opt/isa/aa64-inline/link/elf/ar/driver-ar/debug/dwarf/
lib-deps/libc(musl+glibc)/smoke-x64/smoke-rv64.

</content>
</entry>
<entry>
<id>c9c1495aa91c311d916704f17cd3c9f0a79079af</id>
<published>2026-06-05T17:51:12Z</published>
<updated>2026-06-05T17:51:12Z</updated>
<title>modularity wave 2: route obj/link/cg/api/asm/dwarf through capability hooks</title>
<link rel="alternate" type="text/html" href="commit/c9c1495aa91c311d916704f17cd3c9f0a79079af.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit c9c1495aa91c311d916704f17cd3c9f0a79079af
parent e5603fea9e7ddce3fdff1427bbf18ddab1ea87d1
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 10:51:12 -0700

modularity wave 2: route obj/link/cg/api/asm/dwarf through capability hooks

Removes identity switches from generic consumers by reading the wave-1 hooks:
- src/api/core.c: KitTargetSpec gains resolved props (long_size #33, wchar_size #32,
  long_double_format #3, emits_eh_frame #17) computed once in kit_target_new; RISC-V
  float-abi gate replaced by arch_resolve_float_abi (#2).
- src/cg/type.c: supports_symbol_feature -&gt; obj_format_supports_symbol_feature (#14);
  add public kit_cg_target_va_list_kind + kit_cg_target_c_label_prefix.
- src/api/object_detect.c/object_file.c: machine-&gt;arch via fmt reverse maps + kit_arch_ptr_size
  (#4), float-abi via ObjElfArchOps.float_abi_from_e_flags (#23), reloc names via ELF arch ops
  (#24); public kit_obj_fmt_from_name/kit_obj_fmt_name (#35 impl).
- src/link: tpoff64 via LinkArchDesc (#25), COFF synth via obj_format_synth_inputs (#13),
  boundary syms via obj_format_boundary_sym_kind (#12), static-ifunc/debug/got/weak-pull via
  obj_format_* predicates (#18,#28,#29); 9 target.obj/os switches removed.
- src/asm/asm.c: macho seckind via obj_macho_seckind_for_secname (#21).
- src/debug/dwarf_open.c: macho section spelling via obj_macho_native_secname (#36).

Gatekeeper fix: supports_symbol_feature TLS arm now reads a per-format ObjFormatImpl
.tls_symbol_features field (ELF/Mach-O=1, COFF/Wasm=0) instead of deriving from tls_model,
which wrongly returned 1 for Wasm. Build + targeted tests (link/elf/ar/debug/dwarf/asm/
driver-ar/toy/parse/pp/cg-api/smoke-x64/smoke-rv64) green.

</content>
</entry>
<entry>
<id>e5603fea9e7ddce3fdff1427bbf18ddab1ea87d1</id>
<published>2026-06-05T17:29:07Z</published>
<updated>2026-06-05T17:29:07Z</updated>
<title>modularity wave 1: add pluggable-axis capability hooks (additive infra)</title>
<link rel="alternate" type="text/html" href="commit/e5603fea9e7ddce3fdff1427bbf18ddab1ea87d1.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit e5603fea9e7ddce3fdff1427bbf18ddab1ea87d1
parent 9d905b3c414afa1ee34e1825d62000f9acfda660
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 10:29:07 -0700

modularity wave 1: add pluggable-axis capability hooks (additive infra)

Adds the abstraction hooks that wave 2/3 consumers will route through, all additive
(0/NULL defaults preserve existing behavior; old fns kept as thin wrappers):

ObjFormat (src/obj): obj_format_tls_model {ELF_LE,MACHO_DESCRIPTOR,WINDOWS_TEB} (tls_via_descriptor
now wraps it), c_label_prefix, default_entry_name, carries_file_only_debug, builds_own_static_got,
supports_symbol_feature, weak_undef_pulls_archive_member, static_ifunc_via_rela_iplt,
boundary_sym_kind, synth_inputs hook; ObjElfArchOps reloc_name/float_abi_from_e_flags/tls_tp_bias;
obj_macho_seckind_for_secname + obj_macho_native_secname; obj/public name&lt;-&gt;fmt.
ABI (src/abi): ABIFuncInfo.vararg_fp_via_int (set by aapcs64_windows).
ArchImpl (src/arch): resolve_float_abi hook + riscv body; KIT_CG_BACKEND_ICACHE_COHERENT (x64,wasm);
kit_arch_ptr_size.
Frontend (src/api,lang): KitFrontendVTable names/nnames + kit_language_for_name/kit_language_name;
KitFrontendCaps.cache_repl_toplevel_source (toy).

Internal obj helpers (c_mangle, default_entry, extern_via_got, tls bias) migrated to read the new
vtable fields. Build + targeted tests (cg-api,isa,link,elf,debug,dwarf,parse,smoke-x64,smoke-rv64) green.

</content>
</entry>
<entry>
<id>9d905b3c414afa1ee34e1825d62000f9acfda660</id>
<published>2026-06-05T17:06:36Z</published>
<updated>2026-06-05T17:06:36Z</updated>
<title>modularity #9: move wasm_imports to src/obj, drop cg cross-boundary leak</title>
<link rel="alternate" type="text/html" href="commit/9d905b3c414afa1ee34e1825d62000f9acfda660.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 9d905b3c414afa1ee34e1825d62000f9acfda660
parent 30367860c674c288dc894fe10c8595aa40519149
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 10:06:36 -0700

modularity #9: move wasm_imports to src/obj, drop cg cross-boundary leak

src/cg/session.c (the frontend-agnostic KitCg entry) no longer #includes a
backend-private header (arch/wasm/wasm_imports.h) behind #if KIT_ARCH_WASM_ENABLED.
wasm_imports.{c,h} is pure obj-layer code (only touches the generic
obj_ext_set(OBJ_EXT_WASM_IMPORTS) side-table), so it moves to src/obj/ where it is
always compiled; session.c calls wasm_imports_set unconditionally. Behavior-identical.
Removes the only cross-boundary include and behavior-forking #if KIT_ARCH_* in src/cg.

</content>
</entry>
<entry>
<id>30367860c674c288dc894fe10c8595aa40519149</id>
<published>2026-06-05T16:35:39Z</published>
<updated>2026-06-05T16:35:39Z</updated>
<title>Generalize VM execution into the shared exec seam + a hosted test suite</title>
<link rel="alternate" type="text/html" href="commit/30367860c674c288dc894fe10c8595aa40519149.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 30367860c674c288dc894fe10c8595aa40519149
parent 040f0c2838b6b40acd1c3f38b981cc7efedadd2d
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 09:35:39 -0700

Generalize VM execution into the shared exec seam + a hosted test suite

Lift hosted-VM execution out of test/toy/vm.sh into the shared runner
test/lib/exec_target.sh, and build a unified cross-OS hosted test suite on top
of it (test/hosted), green across the full support set.

Shared exec seam (test/lib/exec_target.sh + new test/lib/exec_vm.sh):
- Add &lt;arch&gt;-freebsd / &lt;arch&gt;-windows tags whose runner is a VM. A VM is
  expensive + stateful, so add lifecycle hooks the stateless podman/qemu runners
  don&#39;t need: exec_target_setup boots the VM lazily and once (one Windows VM
  serves both arches), keeps it warm across flushes, and exec_target_teardown_all
  (trap ... EXIT) stops only VMs we booted.
- Add &lt;arch&gt;-linux-glibc tags routing to per-arch Debian images, so glibc and
  musl (&lt;arch&gt;-linux -&gt; alpine) both run through one flush; _exec_target_arch
  now takes the first field for 3-part tags and image-present memoizes per image.
- scripts/{freebsd,windows}_vm.sh run-batch gains a results contract: ship a
  staging dir in, run a generated run-remote.{sh,ps1}, bring each binary&#39;s
  rc/out/err back (FreeBSD bidirectional tar; Windows scp-back + Defender
  exclusion + Start-Process capture). Windows rc masked to 8 bits.
- Repoint test/toy/vm.sh at the seam (compile + queue only; ~140 lines lighter).

Hosted suite (scripts/hosted.sh + test/hosted):
- scripts/hosted.sh: one front-end to provision sysroots and cross-compile+link
  across the support set (&lt;os&gt;[-&lt;libc&gt;]-&lt;arch&gt;): prepare/path/triple/tag/cc/doctor,
  wrapping freebsd_sysroot.sh / llvm_mingw_sysroot.sh / the libc extract.sh; macOS
  uses the Xcode SDK via -isysroot.
- test/hosted: seed case hello.c built via hosted.sh and run via exec_target,
  checking exit code + stdout. make test-hosted (Linux+macOS) / test-hosted-vm
  (adds FreeBSD+Windows). 15-config matrix verified green (30 pass/0 fail):
  Linux {aa64,x64,rv64} x {musl-static,musl-dynamic,glibc} + macos-arm64 +
  windows {x64,aarch64} + freebsd {amd64,aarch64,riscv64}.

C frontend (lang/c/parse): recognize __restrict / __restrict__ as keyword
aliases of `restrict`. glibc headers use them as bare GCC keywords and #undef
the fallback macro under __GNUC__, so the preprocessor-macro approach was not
enough; this unblocks compiling against glibc headers on all arches.

No regression: existing exec_target consumers (test-parse 3840/0) still pass;
test/toy/run.sh and the corpus engine are untouched.

</content>
</entry>
<entry>
<id>040f0c2838b6b40acd1c3f38b981cc7efedadd2d</id>
<published>2026-06-05T14:54:39Z</published>
<updated>2026-06-05T14:54:39Z</updated>
<title>test-toy: run the Toy corpus hosted in the FreeBSD/Windows VMs</title>
<link rel="alternate" type="text/html" href="commit/040f0c2838b6b40acd1c3f38b981cc7efedadd2d.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 040f0c2838b6b40acd1c3f38b981cc7efedadd2d
parent dc1fabbf4cea6f8570680c2365efc94d2cbf4a09
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 07:54:39 -0700

test-toy: run the Toy corpus hosted in the FreeBSD/Windows VMs

Add test/toy/vm.sh, the hosted-VM counterpart to run.sh&#39;s freestanding-Linux
X lane: compile each Toy case against a real OS sysroot (FreeBSD base.txz extract
or the llvm-mingw UCRT sysroot) and execute it on the genuine OS in a VM,
asserting the same .expected exit-code oracle. Per (os,arch) it stages every
applicable case x opt x link-mode into one dir and drains it in a single VM
session via a new `run-batch &lt;arch&gt; &lt;dir&gt;` subcommand added to both
scripts/freebsd_vm.sh (tar-pipe over ssh) and scripts/windows_vm.sh (scp +
run-remote.ps1). Opt-in targets: test-toy-{freebsd,windows}-vm, test-toy-vm.

Verified full corpus O0+O1: fbsd-aarch64 652/0/1 (static+dynamic),
fbsd-riscv64 648/0/5, win-aarch64 324/2/1, win-x64 322/2/2, fbsd-amd64 648/0/2
(after the cpu fix below).

Windows specifics: Defender blocks some kit exes as PUA and PowerShell&#39;s
$LASTEXITCODE keeps a neighbor&#39;s code on a blocked launch, so run-batch adds a
temp-dir Defender exclusion and run-remote.ps1 captures via
Start-Process -PassThru .ExitCode. Exit codes are masked to 8 bits since the
oracle is a POSIX exit status (Windows does not truncate).

freebsd_vm.sh amd64: default qemu64 lacks POPCNT (kit emits popcnt for
@popcount) -&gt; SIGILL; boot with -cpu qemu64,+popcnt,+sse4.1,+sse4.2 (-cpu max
breaks the FreeBSD/EDK2 TCG boot).

The lanes surfaced two genuine kit bugs, filed in doc/plan/TODO.md:
aarch64-windows link ADRP-out-of-range (118_decl_extra_attrs) and x86_64-windows
tail-call+sret O1 access violation (36_musttail_sret/37_tail_sret).

run.sh and the corpus engine are untouched; default test-toy is unaffected.

</content>
</entry>
<entry>
<id>dc1fabbf4cea6f8570680c2365efc94d2cbf4a09</id>
<published>2026-06-05T13:40:34Z</published>
<updated>2026-06-05T13:40:34Z</updated>
<title>doc/plan: add stack-trace builtins &amp; runtime backtrace roadmap</title>
<link rel="alternate" type="text/html" href="commit/dc1fabbf4cea6f8570680c2365efc94d2cbf4a09.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit dc1fabbf4cea6f8570680c2365efc94d2cbf4a09
parent 0a2faa92c8f3b6a302e7f621f78a92ba4b4180c7
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Fri,  5 Jun 2026 06:40:34 -0700

doc/plan: add stack-trace builtins &amp; runtime backtrace roadmap

Proposes a three-layer design: GCC-compatible __builtin_return_address /
__builtin_frame_address primitives (FP-chain lowering, enabled by kit always
keeping a frame pointer), a freestanding __kit_backtrace capture helper, and a
symbolizing __kit_print_backtrace print path that keeps the DWARF reader on the
hosted side of the freestanding boundary.

</content>
</entry>
<entry>
<id>0a2faa92c8f3b6a302e7f621f78a92ba4b4180c7</id>
<published>2026-06-04T21:01:26Z</published>
<updated>2026-06-05T04:51:39Z</updated>
<title>Implement whole-program optimization (LTO Phase 0 + Phase 1)</title>
<link rel="alternate" type="text/html" href="commit/0a2faa92c8f3b6a302e7f621f78a92ba4b4180c7.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 0a2faa92c8f3b6a302e7f621f78a92ba4b4180c7
parent 61a4a4c6f662dced2a9394cb09ee41c1bca529c2
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 14:01:26 -0700

Implement whole-program optimization (LTO Phase 0 + Phase 1)

Make a library or executable look like a single translation unit to the
optimizer so inlining, dead-code elimination, and internalization cross TU
boundaries, for invocations that provide all sources up front
(kit cc *.c -flto -o prog and the build-exe/lib/obj verbs). Whole-program
optimization runs whenever the optimizer runs (-O1+). See doc/plan/LTO.md.

Phase 0 — whole-translation-unit optimization:
- Generalize the ARM64-only finalize sweep to opt_whole_module_finalize for
  every arch; x86-64/riscv64 defer per-function emit to finalize under the
  whole-program path. -O0 and the JIT/interp/run paths stay on eager emit.
- Wire opt_inline over the reachable FuncSet (the previously unreached
  whole-program inliner); weak/interposable callees are kept out-of-line.
- Decide cg/link capabilities via the arch vtable rather than arch identity,
  so src/opt carries no arch == KIT_ARCH_* checks.

Phase 1 — shared-context, all-sources-up-front LTO:
- Stage N semantic frontends (C, Toy, Wasm) into one borrowed KitCg over a
  caller-owned ObjBuilder via an explicit begin/begin_unit/end_unit/finish/
  detach lifecycle; asm participates as an opaque object. Drivers
  (build_compile_all, cc_run_link_exe) collect inputs and do not own
  definition selection or finalization.
- Extract symresolve (src/obj/symresolve.{h,c}); refactor
  link_resolve_symbols onto it and reuse it for the recording-time merge so
  cross-TU ODR/weak/common/COMDAT resolution matches the linker exactly.
- Give ObjBuilder an O(1) name-&gt;id index; skip-intern LOCAL symbols so
  per-TU statics stay distinct in the shared builder.
- Compute the preserved/export set from the assembled link (entry, opaque
  undef refs, intrinsic/IFUNC roots, retain/init-array/address-significant)
  and feed it to kit_cg_finish; executable links internalize the rest before
  the reachability sweep. Relocatable/archive/shared stay conservative and
  cc -shared -flto is rejected until shared output is exercised.

Fixes found completing the work:
- opt_set_finish_policy was called unconditionally from kit_cg_finish and
  casts the recorder&#39;s user to OptImpl*, but the C-source backend&#39;s recorder
  user is a CTarget; the stray write corrupted it and crashed every --emit=c
  run. Guard it behind opt_level &gt; 0, like opt_set_dump_writer.
- The recording-time symresolve_merge fired on same-TU re-emission, so legal
  C tentative definitions (int g; int g;) were rejected as duplicates in
  every path, not just LTO. Track the defining source unit per ObjSymId and
  merge only across units; same-TU re-emission keeps last-writer-wins,
  matching the non-LTO linker. kit stays -fno-common.

Tests: test/opt/whole_program_inline.sh and test/opt/lto_phase1.sh cover
cross-TU fusion, internalization, weak/strong, ODR, tentative resolution
fidelity (-flto == linker), multi-frontend staging, and opaque asm.
asm_04_register_callee_saved is skipped on Mach-O hosts (verbatim file-scope
asm defines bare names the underscored C refs cannot reach, like asm_02).

</content>
</entry>
<entry>
<id>61a4a4c6f662dced2a9394cb09ee41c1bca529c2</id>
<published>2026-06-05T04:51:14Z</published>
<updated>2026-06-05T04:51:14Z</updated>
<title>Fix Windows x64/arm64 variadic ABI at O0 and O1</title>
<link rel="alternate" type="text/html" href="commit/61a4a4c6f662dced2a9394cb09ee41c1bca529c2.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 61a4a4c6f662dced2a9394cb09ee41c1bca529c2
parent 4c4f1db31be66b1fab039b0a1fa8c4f8ab2bdd6f
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 21:51:14 -0700

Fix Windows x64/arm64 variadic ABI at O0 and O1

aarch64-windows variadics were broken in both the direct (O0) and
optimizer (O1) paths, and x64 Win64 va_start miscompiled at O1. The
no-VM smoke (build + objdump) hid all of it; these are runtime bugs.

- aarch64-windows: route variadic FP args through GP registers (the
  classifier already remapped named params; aa_param_abi now does the
  same for trailing `...` args) and home x0..x7 into a GP &quot;home area&quot;
  at the top of the frame, contiguous with the incoming stack args, so
  the plain-pointer va_list walks register- then stack-passed varargs
  as one block. Driven by ABIVaListInfo.gp_reg_count; forces the fat
  top-record frame for Windows variadic functions only (non-variadic
  and non-Windows codegen is untouched).
- x64 Win64: declare RAX clobbered by va_start via the machine-op
  clobber mechanism (new NATIVE_MOP_VA_START), so the allocator stops
  keeping a live value (e.g. a return-coalesced loop accumulator) in
  RAX across the op.

Verified on the Win11 ARM64 VM (aarch64 native + x64 emulated) at O0
and O1: all three COFF Windows smokes pass, plus new coverage for
loop/overflow varargs, named-FP varargs, va_copy, and RSI/RDI +
XMM6-15 preservation. No regressions across cg/opt/isa/parse/asm/pp/
debug/dwarf/smoke/libc, Apple-ARM64, or SysV varargs.

Also fold in the in-flight frontend cleanups owned by this change
(extern-inline suppressed-parse dummy labels; drop the bogus
local-const memory boundary on file-scope asm) and add their missing
test coverage.

</content>
</entry>
<entry>
<id>4c4f1db31be66b1fab039b0a1fa8c4f8ab2bdd6f</id>
<published>2026-06-05T02:00:38Z</published>
<updated>2026-06-05T02:00:38Z</updated>
<title>Fix Windows PE x64 startup and callback ABI</title>
<link rel="alternate" type="text/html" href="commit/4c4f1db31be66b1fab039b0a1fa8c4f8ab2bdd6f.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 4c4f1db31be66b1fab039b0a1fa8c4f8ab2bdd6f
parent eff11e543f602e9bccfb86bdd2e446271957de85
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 19:00:38 -0700

Fix Windows PE x64 startup and callback ABI

</content>
</entry>
<entry>
<id>eff11e543f602e9bccfb86bdd2e446271957de85</id>
<published>2026-06-05T00:12:47Z</published>
<updated>2026-06-05T00:12:47Z</updated>
<title>Add release runtime variants</title>
<link rel="alternate" type="text/html" href="commit/eff11e543f602e9bccfb86bdd2e446271957de85.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit eff11e543f602e9bccfb86bdd2e446271957de85
parent b8dcd8a7bdd3f2ce01756fd8ce410d64786424de
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 17:12:47 -0700

Add release runtime variants

Fill the release runtime variant tables for FreeBSD and freestanding targets, brand FreeBSD ELF objects so ld can select the FreeBSD runtime, and mark the release checklist items complete.

</content>
</entry>
<entry>
<id>b8dcd8a7bdd3f2ce01756fd8ce410d64786424de</id>
<published>2026-06-04T23:41:30Z</published>
<updated>2026-06-04T23:41:30Z</updated>
<title>coff: emit PE exception directory metadata</title>
<link rel="alternate" type="text/html" href="commit/b8dcd8a7bdd3f2ce01756fd8ce410d64786424de.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit b8dcd8a7bdd3f2ce01756fd8ce410d64786424de
parent 11895ae0ea7cc7f8fc16664bae5d2fff4aa87c1d
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 16:41:30 -0700

coff: emit PE exception directory metadata

</content>
</entry>
<entry>
<id>11895ae0ea7cc7f8fc16664bae5d2fff4aa87c1d</id>
<published>2026-06-04T23:41:00Z</published>
<updated>2026-06-04T23:41:00Z</updated>
<title>windows: add ARM64 VM runner for COFF smoke tests</title>
<link rel="alternate" type="text/html" href="commit/11895ae0ea7cc7f8fc16664bae5d2fff4aa87c1d.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 11895ae0ea7cc7f8fc16664bae5d2fff4aa87c1d
parent 60e7c4ca59b86810a9103da2e217a85aa0bd3134
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 16:41:00 -0700

windows: add ARM64 VM runner for COFF smoke tests

</content>
</entry>
<entry>
<id>60e7c4ca59b86810a9103da2e217a85aa0bd3134</id>
<published>2026-06-04T23:40:32Z</published>
<updated>2026-06-04T23:40:32Z</updated>
<title>test: add FreeBSD hosted link VM smoke</title>
<link rel="alternate" type="text/html" href="commit/60e7c4ca59b86810a9103da2e217a85aa0bd3134.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 60e7c4ca59b86810a9103da2e217a85aa0bd3134
parent 7cb63a5b610c688fbf2705c7ad21ce4cabd1de41
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 16:40:32 -0700

test: add FreeBSD hosted link VM smoke

</content>
</entry>
<entry>
<id>7cb63a5b610c688fbf2705c7ad21ce4cabd1de41</id>
<published>2026-06-04T23:39:18Z</published>
<updated>2026-06-04T23:39:18Z</updated>
<title>link: emit FreeBSD PIE metadata for rtld</title>
<link rel="alternate" type="text/html" href="commit/7cb63a5b610c688fbf2705c7ad21ce4cabd1de41.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 7cb63a5b610c688fbf2705c7ad21ce4cabd1de41
parent f80b5dd6d6c855d8baa47ce108d2e859564354fc
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 16:39:18 -0700

link: emit FreeBSD PIE metadata for rtld

</content>
</entry>
<entry>
<id>f80b5dd6d6c855d8baa47ce108d2e859564354fc</id>
<published>2026-06-04T23:39:01Z</published>
<updated>2026-06-04T23:39:01Z</updated>
<title>link: fix FreeBSD hosted static executables</title>
<link rel="alternate" type="text/html" href="commit/f80b5dd6d6c855d8baa47ce108d2e859564354fc.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit f80b5dd6d6c855d8baa47ce108d2e859564354fc
parent 516e7b47cb094dd0efd52a836af95a5a45672102
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 16:39:01 -0700

link: fix FreeBSD hosted static executables

</content>
</entry>
<entry>
<id>516e7b47cb094dd0efd52a836af95a5a45672102</id>
<published>2026-06-04T23:37:08Z</published>
<updated>2026-06-04T23:37:08Z</updated>
<title>elf: add hosted FreeBSD relocation primitives</title>
<link rel="alternate" type="text/html" href="commit/516e7b47cb094dd0efd52a836af95a5a45672102.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 516e7b47cb094dd0efd52a836af95a5a45672102
parent 3e9ce3177b318a8cf1e867589ab9f7a4628715fc
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 16:37:08 -0700

elf: add hosted FreeBSD relocation primitives

</content>
</entry>
<entry>
<id>3e9ce3177b318a8cf1e867589ab9f7a4628715fc</id>
<published>2026-06-04T20:57:12Z</published>
<updated>2026-06-04T20:57:12Z</updated>
<title>freebsd: VM execution harness for amd64/aarch64/rv64</title>
<link rel="alternate" type="text/html" href="commit/3e9ce3177b318a8cf1e867589ab9f7a4628715fc.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 3e9ce3177b318a8cf1e867589ab9f7a4628715fc
parent f2fa4890b0f5a8f2789856784b845889b4692c18
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 13:57:12 -0700

freebsd: VM execution harness for amd64/aarch64/rv64

scripts/freebsd_vm.sh provisions and runs FreeBSD VMs as kit execution
targets, plus doc/plan/FREEBSD.md.

- Provision once, cache a compressed &quot;golden&quot; disk in the download cache
  (survives `make clean`); restore in seconds thereafter.
- amd64: reset EDK2 NVRAM vars each run (else the firmware boots its UEFI
  Shell instead of the disk -- the &quot;hang&quot;) and -vga none so the serial
  console is primary.
- aarch64: virt + HVF (fast).
- rv64: -machine virt,acpi=off (FreeBSD/riscv64 is FDT-only) plus an
  expect-driven serial bootstrap, since FreeBSD publishes no cloud-init
  riscv64 image.
- cloud-init arches provision offline (restrict=on) so the first-boot
  freebsd-update fast-fails instead of running a slow networked update
  and forcing a reboot.

All three boot and are SSH-reachable as the `kit` user.

</content>
</entry>
<entry>
<id>f2fa4890b0f5a8f2789856784b845889b4692c18</id>
<published>2026-06-04T20:57:00Z</published>
<updated>2026-06-04T20:57:00Z</updated>
<title>freebsd: cross-compile target, runtime, and link support</title>
<link rel="alternate" type="text/html" href="commit/f2fa4890b0f5a8f2789856784b845889b4692c18.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit f2fa4890b0f5a8f2789856784b845889b4692c18
parent a292100f526e3ee83fd6f4e76eee1eb3a4694559
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 13:57:00 -0700

freebsd: cross-compile target, runtime, and link support

Make `kit cc --target=&lt;arch&gt;-freebsd` actually produce FreeBSD ELF for
aarch64/x64/rv64:

- target.c: parse the `freebsd` OS token (with version suffix, e.g.
  freebsd15.0) -&gt; KIT_OS_FREEBSD/ELF. It previously fell through to
  freestanding.
- runtime.c: add {x86_64,aarch64,riscv64}-freebsd runtime variants (ELF,
  mirroring the Linux runtime) so cc finds libkit_rt.
- obj/elf: read ELF COMDAT groups -- record an SHT_GROUP section&#39;s
  signature symbol as absolute-defined instead of orphaning it into a
  phantom undef. FreeBSD&#39;s crt1.o brands the binary via a `.freebsd.note`
  COMDAT group. Also map STB_GNU_UNIQUE to a global binding.
- hosted.c: link FreeBSD 15&#39;s libsys (split out of libc) when present.

Linking a static hosted executable still hits the libc/libsys weak-alias
archive cycle (undefined `openat`); see doc/plan/FREEBSD.md.

test-elf/test-link/test-ar remain green.

</content>
</entry>
<entry>
<id>a292100f526e3ee83fd6f4e76eee1eb3a4694559</id>
<published>2026-06-04T18:36:24Z</published>
<updated>2026-06-04T18:36:24Z</updated>
<title>windows: provision llvm-mingw UCRT sysroots for kit-only cross-compile</title>
<link rel="alternate" type="text/html" href="commit/a292100f526e3ee83fd6f4e76eee1eb3a4694559.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit a292100f526e3ee83fd6f4e76eee1eb3a4694559
parent 296361e67f879675a2e8f178cf6f9850a1a3e5ce
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 11:36:24 -0700

windows: provision llvm-mingw UCRT sysroots for kit-only cross-compile

Add scripts/llvm_mingw_sysroot.sh to download the pinned mstorsjo/llvm-mingw
UCRT release and extract only each target&#39;s include/ and lib/ (headers, CRT
objects, import archives) — never the bundled clang/gcc/ld/lld tools. kit
cross-compiles and links x86_64-windows and aarch64-windows entirely on its
own against these sysroots.

- hosted Windows-mingw profile links libucrt.a (UCRT) instead of libmsvcrt.a
  and is renamed windows-mingw-ucrt; cc.c sysroot comment follows suit
- mk/rt.mk wires the x86_64 __chkstk stack-probe into the windows runtime
- mk/test.mk adds a windows-ucrt-sysroots target (provenance-marker driven)
  and points test-coff-windows-ucrt at both runtimes + both smoke scripts
- COFF smokes discover sysroots under build/llvm-mingw/*/ucrt, validate via
  libucrt.a, and gain an optional Windows-VM execution path (scripts/
  windows_vm.sh over SSH); they remain self-skipping with no sysroot
- doc/WINDOWS.md documents provisioning + VM execution

test-coff smokes use kit exclusively (kit cc to compile+link, kit objdump -p
to inspect): 78 + 126 link-level asserts pass for both arches; VM/Wine exec
paths self-skip when unconfigured.

</content>
</entry>
<entry>
<id>296361e67f879675a2e8f178cf6f9850a1a3e5ce</id>
<published>2026-06-04T17:49:40Z</published>
<updated>2026-06-04T17:49:40Z</updated>
<title>test: add freestanding qemu-system smoke</title>
<link rel="alternate" type="text/html" href="commit/296361e67f879675a2e8f178cf6f9850a1a3e5ce.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 296361e67f879675a2e8f178cf6f9850a1a3e5ce
parent a8052633f6775e1cba26a4b7a6db19f237e98c22
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 10:49:40 -0700

test: add freestanding qemu-system smoke

</content>
</entry>
<entry>
<id>a8052633f6775e1cba26a4b7a6db19f237e98c22</id>
<published>2026-06-04T17:45:21Z</published>
<updated>2026-06-04T17:45:21Z</updated>
<title>aa64: support bitfield extension aliases</title>
<link rel="alternate" type="text/html" href="commit/a8052633f6775e1cba26a4b7a6db19f237e98c22.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit a8052633f6775e1cba26a4b7a6db19f237e98c22
parent f7fbbc9db78d92ef2796ccc4def521332e77e50e
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 10:45:21 -0700

aa64: support bitfield extension aliases

</content>
</entry>
<entry>
<id>f7fbbc9db78d92ef2796ccc4def521332e77e50e</id>
<published>2026-06-04T16:59:48Z</published>
<updated>2026-06-04T17:02:39Z</updated>
<title>Add initial release punchlist</title>
<link rel="alternate" type="text/html" href="commit/f7fbbc9db78d92ef2796ccc4def521332e77e50e.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit f7fbbc9db78d92ef2796ccc4def521332e77e50e
parent a89695e3122b7a118a91d8828d350e2ffc18409c
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 09:59:48 -0700

Add initial release punchlist

</content>
</entry>
<entry>
<id>a89695e3122b7a118a91d8828d350e2ffc18409c</id>
<published>2026-06-04T15:43:13Z</published>
<updated>2026-06-04T15:43:13Z</updated>
<title>Drain driver TODO backlog</title>
<link rel="alternate" type="text/html" href="commit/a89695e3122b7a118a91d8828d350e2ffc18409c.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit a89695e3122b7a118a91d8828d350e2ffc18409c
parent 58a41780a77ed786a88361881b40d8059cc29a94
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 08:43:13 -0700

Drain driver TODO backlog

</content>
</entry>
<entry>
<id>58a41780a77ed786a88361881b40d8059cc29a94</id>
<published>2026-06-04T15:18:05Z</published>
<updated>2026-06-04T15:18:09Z</updated>
<title>driver: add build-exe/build-lib/build-obj, retire compile</title>
<link rel="alternate" type="text/html" href="commit/58a41780a77ed786a88361881b40d8059cc29a94.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 58a41780a77ed786a88361881b40d8059cc29a94
parent 438e6b094ea31ed5ec9787d451e59ddc9a7770f9
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 08:18:05 -0700

driver: add build-exe/build-lib/build-obj, retire compile

Kit-native build verbs that compile a polyglot source set (C/asm/toy/wasm,
resolved per file) entirely in memory and produce the final artifact in one
invocation:

  build-exe  link an executable
  build-lib  static .a (dynamic/shared not yet supported)
  build-obj  one object, --emit=asm|c|ir, -fsyntax-only, or an `ld -r` combine
             of N sources; full replacement for the retired `compile` tool

Flags split into global/per-output and a scopable set (-I/-isystem/-D/-U, -x,
-X&lt;lang&gt;) overridable per source group via `--group [flags] -- sources`.
Per-language frontend flags route through -X&lt;lang&gt;.

Factoring:
  - driver/lib/link_engine: build-session/add-in-order/emit step; cc&#39;s link
    path now routes through it (no behavior change).
  - driver/lib/archive_engine: in-memory object serialize + ar symbol index.
  build-obj&#39;s multi-source combine matches `ld -r` symbol-for-symbol.

Register the tools (config gate, main table, default install group), remove
compile.c + its test, migrate test/compile -&gt; test/buildcmds, update
doc/DRIVER.md, and add doc/plan/TODO.md cataloguing pre-existing issues found
along the way.

</content>
</entry>
<entry>
<id>438e6b094ea31ed5ec9787d451e59ddc9a7770f9</id>
<published>2026-06-04T13:56:18Z</published>
<updated>2026-06-04T13:56:18Z</updated>
<title>doc/plan: add LTO / whole-program optimization plan</title>
<link rel="alternate" type="text/html" href="commit/438e6b094ea31ed5ec9787d451e59ddc9a7770f9.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 438e6b094ea31ed5ec9787d451e59ddc9a7770f9
parent bde9b5848be4f7d9b2587abaaf7c4ad02417143c
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 06:56:18 -0700

doc/plan: add LTO / whole-program optimization plan

Forward-looking design for making a library/executable look like a single
TU to the optimizer. Chooses shared-context recording (all sources record
into one session/ObjBuilder/CgIrModule) over clone-and-merge, since globals
already intern by name, the recorder already accumulates a whole module, and
the finalize sweep + unreached opt_inline already exist. Centers the work on
factoring the linker&#39;s resolution policy into a shared symresolve module
usable at merge time. Phased: whole-TU opt, all-sources LTO, serialized
.kit.ir objects.

</content>
</entry>
<entry>
<id>bde9b5848be4f7d9b2587abaaf7c4ad02417143c</id>
<published>2026-06-04T13:49:20Z</published>
<updated>2026-06-04T13:49:20Z</updated>
<title>doc/plan: design for build-exe/build-lib/build-obj (replacing compile)</title>
<link rel="alternate" type="text/html" href="commit/bde9b5848be4f7d9b2587abaaf7c4ad02417143c.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit bde9b5848be4f7d9b2587abaaf7c4ad02417143c
parent 8d3bb285e71aed150d99db5019df5876c1f245a0
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 06:49:20 -0700

doc/plan: design for build-exe/build-lib/build-obj (replacing compile)

Kit-native build verbs that compile a mixed-language source set in memory
and link/archive in one shot, replacing the no-link &#39;compile&#39; tool. Captures
the --group flag-scoping grammar, the global-vs-scopable taxonomy, -X&lt;lang&gt;
frontend-flag routing, hybrid naming (kit --emit/-o + Zig -static/-dynamic),
the link_engine/archive_engine extraction plan, migration, and the resolved
design decisions.

</content>
</entry>
<entry>
<id>8d3bb285e71aed150d99db5019df5876c1f245a0</id>
<published>2026-06-04T09:24:24Z</published>
<updated>2026-06-04T09:24:24Z</updated>
<title>wasm: tighten shared-memory max to min pages so atomics modules load</title>
<link rel="alternate" type="text/html" href="commit/8d3bb285e71aed150d99db5019df5876c1f245a0.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 8d3bb285e71aed150d99db5019df5876c1f245a0
parent 3a93557bc838c194609de1e670e7f831f74fb61e
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 02:24:24 -0700

wasm: tighten shared-memory max to min pages so atomics modules load

ensure_shared_memory promotes the module memory to shared (required for
wasm atomic ops) with a provisional 4 GiB cap (65536 pages). The comment
claimed wasm_materialize_data tightens that to the real size, but the code
only ever raised min toward max -- never lowered max -- so atomics modules
shipped a 4 GiB declared maximum. `kit run` reserves the declared maximum
and caps total linear memory at 1 GiB, so every such module was rejected at
load (&quot;wasm linear memory reservation exceeds 1073741824 bytes&quot;).

Tighten max_pages down to min_pages for shared memory once the final layout
is known. The backend never emits memory.grow, so a fixed shared memory is
correct, and embedders now reserve a snug arena. Fixes the 8 toy atomics
cases on lane W (124/17/22/59/73/74/75/77) and lets the C-frontend wasm
atomics cases run instead of failing at load.

</content>
</entry>
<entry>
<id>3a93557bc838c194609de1e670e7f831f74fb61e</id>
<published>2026-06-04T08:58:34Z</published>
<updated>2026-06-04T08:58:34Z</updated>
<title>cg/asm: reject 64-bit values in register asm constraints on 32-bit targets</title>
<link rel="alternate" type="text/html" href="commit/3a93557bc838c194609de1e670e7f831f74fb61e.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 3a93557bc838c194609de1e670e7f831f74fb61e
parent a7a3338d08760d46faf61a0fc6f82f01b62c8cc1
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 01:58:34 -0700

cg/asm: reject 64-bit values in register asm constraints on 32-bit targets

A 64-bit scalar bound to a register constraint (&quot;r&quot;/&quot;f&quot;/&quot;x&quot;/&quot;w&quot;) needs a
register pair on a 32-bit target, which the inline-asm lowering does not
model -- it would bind the value to a single GPR and silently truncate to
the low word. Reject it up front in kit_cg_inline_asm at all three operand
sites (output, input, early-clobber output) via api_is_wide8_scalar_type;
the source can use a memory (&quot;m&quot;) constraint or split into two 32-bit
operands instead.

Add a red-green err test (invalid_asm_wide_reg_rv32) compiled for rv32 via
a new err/&lt;name&gt;.ccargs sidecar in the toy ERR lane (per-case cc flags).

Convert the toy asm fixtures that fed a 64-bit value to a register operand
(19, 102, 105, 110) to isize so the operand fits one GPR on every target;
they keep exercising register asm operands and now pass on the rv32 exec
lane without a skip. Same conversion fixes 20_cg_api_inline_asm_full, which
was already red on native after integer-literal widening made bare
inout(&quot;+r&quot;, 7) an i8 that no longer matched its @asm&lt;i64&gt; result; with empty
templates it now also passes on rv32, so its stale .rv32.skip is dropped.

</content>
</entry>
<entry>
<id>a7a3338d08760d46faf61a0fc6f82f01b62c8cc1</id>
<published>2026-06-04T08:39:37Z</published>
<updated>2026-06-04T08:39:37Z</updated>
<title>rv32 parse: resolve LP64-assumption corpus failures</title>
<link rel="alternate" type="text/html" href="commit/a7a3338d08760d46faf61a0fc6f82f01b62c8cc1.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit a7a3338d08760d46faf61a0fc6f82f01b62c8cc1
parent c5166d0e42265a19c8f18223e0cb43bb35497e5b
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Thu,  4 Jun 2026 01:39:37 -0700

rv32 parse: resolve LP64-assumption corpus failures

The rv32 (ilp32) parse lane had 3 cases failing because they bake in
LP64 (64-bit long/size_t) assumptions. kit&#39;s rv32 codegen is correct —
clang as an independent ilp32 oracle returns the identical values
(10, 16, 9), confirming the test expectations, not the codegen, are
target-specific.

- builtin_26_sadd_overflow: gate the long-width (*l_overflow) assertions
  behind #if __SIZEOF_LONG__ == 8. They hard-code 64-bit long boundary
  constants; under ilp32 `long` is a 32-bit width-duplicate of the int
  builtins. The case previously bailed in this block, so the 64-bit
  long long overflow builtins were never reached on rv32 — they now run
  and pass, adding real 64-bit-overflow-on-32-bit-target coverage.
  Unchanged on LP64 (verified 42 on rv32 kit+clang and native LP64).

- 6_5_64_unsigned_size_division.rv32.skip: the 64-bit size_t
  overflow-check idiom; the clamp legitimately fires under ilp32.

- rv64_atomic_widths_orders.rv32.skip: rv64-named 64-bit atomics via
  64-bit long; rv32&#39;s 32-bit atomics stay covered by builtin_06..25.

- test/parse/run.sh: set KIT_SKIP_IS_FAILURE=0 to match the toy runner,
  so the corpus&#39;s permanent ilp32 skip floor (i128_*/ldbl128_*, ...) no
  longer gates the exit; only a real FAIL or XPASS does.

</content>
</entry>
<entry>
<id>c5166d0e42265a19c8f18223e0cb43bb35497e5b</id>
<published>2026-06-04T05:15:10Z</published>
<updated>2026-06-04T05:15:10Z</updated>
<title>test/rv32: drop clang gate from bare-metal toy/parse lanes</title>
<link rel="alternate" type="text/html" href="commit/c5166d0e42265a19c8f18223e0cb43bb35497e5b.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit c5166d0e42265a19c8f18223e0cb43bb35497e5b
parent 4931d48851d32a219a48d75854daf88be384e4e1
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 22:15:10 -0700

test/rv32: drop clang gate from bare-metal toy/parse lanes

The rv32 toy/parse exec lanes build the entire image with kit (kit cc /
kit as / kit ld) and the runtime archive via kit cc (RT_CC), then run
under qemu-system-riscv32. clang is never invoked on this path, yet
rv32_bare_setup refused to run unless the clang riscv32 target probe
passed. Gate on qemu-system-riscv32 alone and update the skip messages.

</content>
</entry>
<entry>
<id>4931d48851d32a219a48d75854daf88be384e4e1</id>
<published>2026-06-04T05:01:49Z</published>
<updated>2026-06-04T05:04:12Z</updated>
<title>rv32 lowering fixes</title>
<link rel="alternate" type="text/html" href="commit/4931d48851d32a219a48d75854daf88be384e4e1.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 4931d48851d32a219a48d75854daf88be384e4e1
parent 056fc9ea14811f46112837b87a5a7de5630bce80
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 22:01:49 -0700

rv32 lowering fixes

</content>
</entry>
<entry>
<id>056fc9ea14811f46112837b87a5a7de5630bce80</id>
<published>2026-06-04T05:01:27Z</published>
<updated>2026-06-04T05:04:12Z</updated>
<title>toy: pointer-width isize/usize, int widening</title>
<link rel="alternate" type="text/html" href="commit/056fc9ea14811f46112837b87a5a7de5630bce80.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 056fc9ea14811f46112837b87a5a7de5630bce80
parent 87ffbeeee00a842e9209d9665120e25ce814e3d4
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 22:01:27 -0700

toy: pointer-width isize/usize, int widening

</content>
</entry>
<entry>
<id>87ffbeeee00a842e9209d9665120e25ce814e3d4</id>
<published>2026-06-04T04:27:16Z</published>
<updated>2026-06-04T05:04:12Z</updated>
<title>Test ABI split-lane scalar query</title>
<link rel="alternate" type="text/html" href="commit/87ffbeeee00a842e9209d9665120e25ce814e3d4.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 87ffbeeee00a842e9209d9665120e25ce814e3d4
parent e4a333278d9c614276c265232293826e26aa3b63
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 21:27:16 -0700

Test ABI split-lane scalar query

</content>
</entry>
<entry>
<id>e4a333278d9c614276c265232293826e26aa3b63</id>
<published>2026-06-04T04:22:40Z</published>
<updated>2026-06-04T05:03:51Z</updated>
<title>rv32: use ABI split-lane scalar metadata</title>
<link rel="alternate" type="text/html" href="commit/e4a333278d9c614276c265232293826e26aa3b63.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit e4a333278d9c614276c265232293826e26aa3b63
parent ea0e478e0cdbf5187b454ea2844b83a9e12e2964
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 21:22:40 -0700

rv32: use ABI split-lane scalar metadata

Add target data-model width selection for C long/size_t spellings, expose ABI scalar split-lane metadata, and use it to gate wide8 lowering/backend guards. Also fix frame-backed indirect index materialization to load the pointer-width value and add an RV32 parser fixture for data-model widths.

</content>
</entry>
<entry>
<id>ea0e478e0cdbf5187b454ea2844b83a9e12e2964</id>
<published>2026-06-04T03:55:10Z</published>
<updated>2026-06-04T05:03:51Z</updated>
<title>Fix rv32 toy target arch and wide intrinsics</title>
<link rel="alternate" type="text/html" href="commit/ea0e478e0cdbf5187b454ea2844b83a9e12e2964.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit ea0e478e0cdbf5187b454ea2844b83a9e12e2964
parent 1576564d10ca3d46a2d2b708384883adcda9270c
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 20:55:10 -0700

Fix rv32 toy target arch and wide intrinsics

</content>
</entry>
<entry>
<id>1576564d10ca3d46a2d2b708384883adcda9270c</id>
<published>2026-06-04T03:37:25Z</published>
<updated>2026-06-04T05:03:51Z</updated>
<title>rv32: fix 8-byte variadic high-word drop, O1 label-addr width, long double, atomics</title>
<link rel="alternate" type="text/html" href="commit/1576564d10ca3d46a2d2b708384883adcda9270c.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 1576564d10ca3d46a2d2b708384883adcda9270c
parent 86a819d3f72a1da40cc323e83bc411fefd5fea50
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 20:37:25 -0700

rv32: fix 8-byte variadic high-word drop, O1 label-addr width, long double, atomics

Variadic 8-byte args (i64 / soft-double) were dropping their high 32 bits on
rv32. The caller synthesized a single 8-byte ABI part for an unnamed arg, which
the per-part marshaller loaded into one GPR (low word only); the callee va_arg
fetched 4 bytes and advanced the cursor by one slot.

- rv_param_abi: split a variadic scalar wider than one GPR into one INT part per
  word (low word in the lower-numbered reg), matching the named-arg classifier.
- rv_va_arg_wide: new helper that copies the full value out of the (contiguous)
  save area and advances the cursor by the whole span; used by both the -O0
  direct and -O1 native-emit paths for any value too wide for one GPR.
- pass_native_emit IR_VA_ARG: route aggregate/oversized va_arg through its memory
  destination instead of a scratch register. rv64/aa64/x64 unaffected (no test
  passes an 8-byte value as wide there).

O1 static-data label addresses (jump tables, &amp;&amp;label-in-data) panicked with
&quot;unsupported local static label width&quot; on rv32: the native-emit path hardcoded
R_ABS64. Make it width-aware (R_ABS32 for 4-byte slots), mirroring the -O0
direct path. This also fixes the gnu_label_addr_* parse cases.

long double on rv32 is a double alias (8-byte), not IEEE-754 binary128, so the
ldbl128_* cases (which assert sizeof==16 / MANT_DIG==113) can&#39;t hold there; add
.rv32.skip sidecars. Generic long-double use (6_7_2_12) keeps working as double.

builtin_24_atomic_lock_free: size the lock-free checks against the native word
(sizeof(void*)) instead of a fixed 8 bytes, and drop the __int128 dead code, so
the same .expected (42) holds on ilp32 and lp64. rv32 has no 64-bit AMO, so an
8-byte atomic is correctly not lock-free there.

</content>
</entry>
<entry>
<id>86a819d3f72a1da40cc323e83bc411fefd5fea50</id>
<published>2026-06-04T02:37:22Z</published>
<updated>2026-06-04T05:03:51Z</updated>
<title>rv32: close most remaining cross-target reds (atomics, overflow, soft-fp, TLS, __int128, CSR, asm goldens)</title>
<link rel="alternate" type="text/html" href="commit/86a819d3f72a1da40cc323e83bc411fefd5fea50.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 86a819d3f72a1da40cc323e83bc411fefd5fea50
parent 01252f062d3256bf8804f706e0226db5be82efcd
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 19:37:22 -0700

rv32: close most remaining cross-target reds (atomics, overflow, soft-fp, TLS, __int128, CSR, asm goldens)

Closes the bulk of the deliberately-red rv32 gaps from doc/plan/RV32.md.
rv64/x64/aa64 non-regressed (isa rv32 90/rv64 79/aa64 43, asm-rv64 43/0 +
asm-rv32 16/0, elf 41/0, link 122/0, smoke-rv64 3/0 + smoke-rv32 7/0,
cg-api, abi-classify 367/0).

- i64 atomics: route 8-byte atomics to the existing __atomic_*_8 rt libcalls
  on rv32 (is_lock_free/is_legal made target+size-aware). Fixes the
  123_spec_demo hang + 7 toy atomic cases. New 124_atomic_word_ops covers
  word atomics on all lanes.
- i64 overflow intrinsics: inline 2-lane lowering in kit_cg_intrinsic
  (uadd/usub carry/borrow, sadd/ssub sign formula, umul/smul 128-bit product).
- soft-fp compare: api_wide8_addr materializes a delayed wide8 operand before
  taking its address (fixes toy 153 at -O0).
- TLS: rv32 bare-metal startup stub sets up a static-TLS block + tp. Needed
  and adds a kit-ld linker-script fix: accept the 1-arg ALIGN(align) GNU form.
- __int128: rejected on rv32 with a target-gated diagnostic (matches gcc/clang
  64-bit-only); 14 i128_* cases skipped via .rv32.skip sidecars.
- CSR pseudo-ops: csrr/csrw/csrs/csrc/csrwi/csrsi/csrci + CSR-name table
  (benefits rv64 too); both rv32 startup stubs now kit-assembled (clang stub
  dependency dropped).
- asm goldens: rv32 byte-golden lane + regen-rv32.sh + corpus; opt-in
  test-asm-rv32/test-toy-rv32/test-parse-rv32 targets. Also fixes a real
  assembler bug: bare fcvt.w.s defaulted rm to RTZ, now dyn (gas/clang);
  stale rv64 fp goldens regenerated.
- test-env skip sidecars for arch-specific toy/C cases (145/20/47, asm_01).

Still red (follow-up): i64/double varargs (high 32 bits of an 8-byte vararg
are dropped — caller/callee ABI), 123_spec_demo -O1 (switch-table label
width), and the pre-existing rv32 -O1 cluster + ldbl128.

</content>
</entry>
<entry>
<id>01252f062d3256bf8804f706e0226db5be82efcd</id>
<published>2026-06-04T00:25:51Z</published>
<updated>2026-06-04T05:03:51Z</updated>
<title>rv32: auto-build and auto-link the freestanding runtime like any target</title>
<link rel="alternate" type="text/html" href="commit/01252f062d3256bf8804f706e0226db5be82efcd.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 01252f062d3256bf8804f706e0226db5be82efcd
parent bf5b73bcb4b8e9cffd12aa173a5a5759cbe71381
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 17:25:51 -0700

rv32: auto-build and auto-link the freestanding runtime like any target

riscv32-none-elf was the only freestanding target without a driver
RuntimeVariant, so kit cc/ld could not auto-build or auto-link
libkit_rt.a for it — the smoke test had to `make rt` and pass the
archive explicitly. The blocker was that rv32 has two float ABIs
sharing one arch+pointer-width (ilp32 soft, ilp32f single) and the
runtime must match, but RuntimeVariant could not distinguish them and
target detection did not recover the float ABI.

- driver/lib/runtime.c: add a float_abi axis (+ isa/abi march strings)
  to RuntimeVariant and two rv32 entries (riscv32-elf soft,
  riscv32-elf-hardfloat single). The matcher keys on float_abi with
  DEFAULT as a wildcard, so every existing variant is unchanged; the
  on-demand build passes each variant&#39;s -march/-mabi via topts.isa/abi.
- src/api/object_detect.c: recover the float ABI from RISC-V ELF
  e_flags (offset 36/48; soft/single/double bits) so a detected target
  selects the matching runtime.
- driver/cmd/ld.c: reconcile float_abi across all link inputs,
  preferring a hardware ABI, so a foreign (clang-assembled) startup
  stub lacking the flag never mis-selects the soft runtime.
- test/smoke/rv32.sh: two kit-ld auto-rt lanes (ilp32f + ilp32) that
  link with no runtime archive named.

Verified: smoke-rv32 7/7 under qemu; no regressions (elf 41/0,
link 122/0, abi-classify 367/0, cg-api 0 failures, driver-cc 98/0,
smoke-rv64 3/0); riscv64-none-elf auto-link still works.

</content>
</entry>
<entry>
<id>bf5b73bcb4b8e9cffd12aa173a5a5759cbe71381</id>
<published>2026-06-04T00:02:26Z</published>
<updated>2026-06-04T05:03:51Z</updated>
<title>rv32: bring up and complete riscv32-none-elf cross target</title>
<link rel="alternate" type="text/html" href="commit/bf5b73bcb4b8e9cffd12aa173a5a5759cbe71381.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit bf5b73bcb4b8e9cffd12aa173a5a5759cbe71381
parent 6ea2c9a48aa1a8670eb9a9005cd63d8b7c002a28
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 17:02:26 -0700

rv32: bring up and complete riscv32-none-elf cross target

Refactor src/arch/rv64 -&gt; src/arch/riscv as one XLEN-parameterized RISC-V
backend (RiscvVariant descriptor) and wire riscv32-none-elf end to end. RV64 /
x64 / aa64 are fully non-regressed.

Backend bring-up:
- WS0  RiscvVariant (src/arch/riscv/variant.{h,c}) + KIT_ARCH_RV32_ENABLED.
- WS1  rv64-&gt;riscv rename; variant threaded through native.c (rv64 byte-identical).
- WS2  ISA availability-mask (RV_AV_RV32/RV64) + asm/disasm/link/dbg XLEN param;
       link_arch_rv32 (lw stubs), rv32_dbg_ops (min=2/max=4, RVC-&gt;step-over).
- WS3  arch_impl_rv32 + registry; -march via variant-&gt;isa_prefix; rv32 default
       rv32imafc_zicsr_zifencei (D cleared); ilp32f predefined macros.
- WS4a KitFloatAbi + KitTargetSpec.float_abi + KitTargetOptions.abi; -mabi
       parse/resolve/validate (ilp32d-without-D and width-mismatch rejected);
       medlow/medany mcmodel aliases.
- WS4b shared RISC-V ABI classifier (descriptor {gpr_bytes,aggregate,flen,
       float_abi}) + rv32_vtable + registry.
- WS5  ELFCLASS32 emit/read/link + reloc_riscv32.c + EI_CLASS machine
       disambiguation (obj_elf_machine_class); width-aware jump-table label
       relocs (R_ABS32 on rv32); layout_dyn clean-panics on an ELF32 dynamic/PIE
       link (was an ELF64 SEGV).
- WS7  mk/rt.mk variants fixed (riscv32-elf=ilp32/rv32imac, +riscv32-elf-hardfloat
       =ilp32f/rv32imafc); mk/lib_srcs.mk ABI guard widened. RT_CFLAGS/RT_ASFLAGS
       now include ARCH_FLAGS (the -mabi/-march were silently dropped). ELF
       e_flags float-ABI derived from target.float_abi (was hardcoded SINGLE,
       mislabelling ilp32 soft).

WS6 64-bit-value legalization (the blocker): rv32 8-byte scalars (long long/i64
AND soft double) are now memory-resident and legalized to 2-word lane ops --
inline add/sub/and/or/xor/neg/bnot/compare (carry/borrow via sltu; no compiler-rt
64-bit add exists), __*di3 for mul/div/rem/shift, __*df*/__*sf* for soft
double/single, i64&lt;-&gt;float via __floatdisf/__fixsfdi, __*di2 for
clz/ctz/popcount/bswap, 2-lane 64-bit consts. The allocator binds one register
per value, so memory residence + the multi-part ABI path is the only correct
representation. nd_* guards panic on any 8-byte value reaching a single-register
op. Verified under qemu-system-riscv32 at -O0/-O1 for both ilp32f and ilp32.

Freestanding link policy is target-derived, host-irrelevant: kit stamps
EI_OSABI=ELFOSABI_STANDALONE on *-none-elf objects (fixes &quot;none decodes as
Linux&quot;), kit ld derives the PIC default via driver_default_pic (hosted PIE /
freestanding no-PIE) scanning all inputs, and auto-links a runtime only when one
exists (driver_runtime_has_variant) -- so a freestanding rv32 link needs no
-no-pie / -nostdlib. .eh_frame suppressed for KIT_OS_FREESTANDING; new -Ttext /
-nostdlib flags.

Tests: rv32_decode_test (test-isa, 31 checks), rv32_jit_test (test-rv32-jit),
rv32_class32 ELFCLASS32 round-trip (test-elf), test/smoke/rv32.sh
(test-smoke-rv32, 6 lanes incl. a kit-ld end-to-end lane), and rv32 wired as a
cross arch in the Toy (test/toy/run.sh path X, 240/15) and C (test/parse/run.sh
path E, 439/36) corpus lanes via the shared test/lib/exec_rv32_bare.sh. Reds are
left red on purpose -- real remaining gaps (i128, i64 atomics/overflow/varargs,
TLS) are tracked in doc/plan/RV32.md. RV64/x64/aa64 fully non-regressed.

</content>
</entry>
<entry>
<id>6ea2c9a48aa1a8670eb9a9005cd63d8b7c002a28</id>
<published>2026-06-04T03:38:12Z</published>
<updated>2026-06-04T03:38:12Z</updated>
<title>Fix Apple ARM64 variadic stack slots</title>
<link rel="alternate" type="text/html" href="commit/6ea2c9a48aa1a8670eb9a9005cd63d8b7c002a28.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 6ea2c9a48aa1a8670eb9a9005cd63d8b7c002a28
parent 6ccc62a9ce1e2feed3f6d085b011571cccfc8447
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 20:38:12 -0700

Fix Apple ARM64 variadic stack slots

</content>
</entry>
<entry>
<id>6ccc62a9ce1e2feed3f6d085b011571cccfc8447</id>
<published>2026-06-04T03:28:36Z</published>
<updated>2026-06-04T03:28:36Z</updated>
<title>Implement wasm sandbox host shim</title>
<link rel="alternate" type="text/html" href="commit/6ccc62a9ce1e2feed3f6d085b011571cccfc8447.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 6ccc62a9ce1e2feed3f6d085b011571cccfc8447
parent 9bd665b95d72f696db659675bf3c85367e1b8cf1
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 20:28:36 -0700

Implement wasm sandbox host shim

</content>
</entry>
<entry>
<id>9bd665b95d72f696db659675bf3c85367e1b8cf1</id>
<published>2026-06-04T02:18:22Z</published>
<updated>2026-06-04T02:18:22Z</updated>
<title>Harden wasm runtime import handling</title>
<link rel="alternate" type="text/html" href="commit/9bd665b95d72f696db659675bf3c85367e1b8cf1.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 9bd665b95d72f696db659675bf3c85367e1b8cf1
parent 5bd8de1ceeabdaef0abc018ea94891371381655d
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 19:18:22 -0700

Harden wasm runtime import handling

</content>
</entry>
<entry>
<id>5bd8de1ceeabdaef0abc018ea94891371381655d</id>
<published>2026-06-03T23:00:03Z</published>
<updated>2026-06-03T23:00:03Z</updated>
<title>aa64 asm: parse logical-immediate and lsl/lsr/asr aliases</title>
<link rel="alternate" type="text/html" href="commit/5bd8de1ceeabdaef0abc018ea94891371381655d.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 5bd8de1ceeabdaef0abc018ea94891371381655d
parent e156c02981eb92a6d0f9303fbde37ed4e6b83615
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 16:00:03 -0700

aa64 asm: parse logical-immediate and lsl/lsr/asr aliases

The disassembler (driving `cc -S`) emits AArch64 forms the assembler
couldn&#39;t parse back, breaking the `cc -c` == `cc -S | as` round-trip for
48 cases (all the L1 lane). Two gaps, both exposed once codegen started
using immediate operand forms at -O0 (dc1854de):

- Logical bitmask-immediate `and/orr/eor/ands Rd, Rn, #imm`: p_log_sr
  parsed the third operand strictly as a register (&quot;expected register&quot;).
- Shift aliases `lsl/lsr/asr Rd, Rn, #imm`: the mnemonics weren&#39;t in the
  table at all, only the variable-shift lslv/lsrv/asrv (&quot;unknown
  mnemonic&quot;).

Add a peek_is_reg lookahead, extend p_log_sr with the bitmask-immediate
form (via aa64_logimm_encode), and add p_shift handling both the register
(LSLV/LSRV/ASRV) and immediate (UBFM/SBFM) forms. ror/EXTR is left out:
the disassembler doesn&#39;t decode EXTR, so adding it would introduce a new
encode-only asymmetry; rorv already covers the register rotate.

Every new encoding cross-checked byte-for-byte against llvm-mc. Adds an
encode corpus case; the symmetry baseline now drops 3 mov_orr_bitmask
encode-only entries that round-trip thanks to the logical-immediate path.

test-asm-roundtrip: 572 pass, 0 fail (was 524 pass / 48 fail).

</content>
</entry>
<entry>
<id>e156c02981eb92a6d0f9303fbde37ed4e6b83615</id>
<published>2026-06-03T22:24:17Z</published>
<updated>2026-06-03T22:24:17Z</updated>
<title>make: add rt to default target</title>
<link rel="alternate" type="text/html" href="commit/e156c02981eb92a6d0f9303fbde37ed4e6b83615.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit e156c02981eb92a6d0f9303fbde37ed4e6b83615
parent 1ccdd814588c5b6750f3f0aca37b47b9aed6907a
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 15:24:17 -0700

make: add rt to default target

</content>
</entry>
<entry>
<id>1ccdd814588c5b6750f3f0aca37b47b9aed6907a</id>
<published>2026-06-03T22:04:23Z</published>
<updated>2026-06-03T22:04:23Z</updated>
<title>doc: regenerate CODE_SIZE.md after the economy refactor</title>
<link rel="alternate" type="text/html" href="commit/1ccdd814588c5b6750f3f0aca37b47b9aed6907a.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 1ccdd814588c5b6750f3f0aca37b47b9aed6907a
parent a3e7b03a7d9a882ee7f73e48a7ccfffd0f44dd44
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 15:04:23 -0700

doc: regenerate CODE_SIZE.md after the economy refactor

</content>
</entry>
<entry>
<id>a3e7b03a7d9a882ee7f73e48a7ccfffd0f44dd44</id>
<published>2026-06-03T21:53:22Z</published>
<updated>2026-06-03T21:53:22Z</updated>
<title>Exercise toy cross TLS startup with kit</title>
<link rel="alternate" type="text/html" href="commit/a3e7b03a7d9a882ee7f73e48a7ccfffd0f44dd44.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit a3e7b03a7d9a882ee7f73e48a7ccfffd0f44dd44
parent 5fec69282f697c6a701638e7da969c3f60fd52b0
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 14:53:22 -0700

Exercise toy cross TLS startup with kit

</content>
</entry>
<entry>
<id>5fec69282f697c6a701638e7da969c3f60fd52b0</id>
<published>2026-06-03T21:53:11Z</published>
<updated>2026-06-03T21:53:11Z</updated>
<title>Add AA64 system register asm support</title>
<link rel="alternate" type="text/html" href="commit/5fec69282f697c6a701638e7da969c3f60fd52b0.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 5fec69282f697c6a701638e7da969c3f60fd52b0
parent 84863072e412579624a0d6c9f304344ebc4b1289
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 14:53:11 -0700

Add AA64 system register asm support

</content>
</entry>
<entry>
<id>84863072e412579624a0d6c9f304344ebc4b1289</id>
<published>2026-06-03T21:53:02Z</published>
<updated>2026-06-03T21:53:02Z</updated>
<title>Support explicit register asm operands</title>
<link rel="alternate" type="text/html" href="commit/84863072e412579624a0d6c9f304344ebc4b1289.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 84863072e412579624a0d6c9f304344ebc4b1289
parent 2d37ba7b367e02cf86618cfa9e3a7a92d516e7ea
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 14:53:02 -0700

Support explicit register asm operands

</content>
</entry>
<entry>
<id>2d37ba7b367e02cf86618cfa9e3a7a92d516e7ea</id>
<published>2026-06-03T19:12:29Z</published>
<updated>2026-06-03T19:12:29Z</updated>
<title>cg: restore out-of-range fallback in intrinsic table accessors</title>
<link rel="alternate" type="text/html" href="commit/2d37ba7b367e02cf86618cfa9e3a7a92d516e7ea.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 2d37ba7b367e02cf86618cfa9e3a7a92d516e7ea
parent b9d9f14016146421df4aad8dc36cb35279db6258
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 12:12:29 -0700

cg: restore out-of-range fallback in intrinsic table accessors

The four KitCgIntrinsic accessors index kIntrinTable directly; route them
through a bounds-guarded intrin_desc() so an out-of-range value falls back to
the NONE row, matching the defensive default: arms the switches carried before
the table collapse. (Equivalence-review nit; valid enum inputs unaffected.)

</content>
</entry>
<entry>
<id>b9d9f14016146421df4aad8dc36cb35279db6258</id>
<published>2026-06-03T18:46:44Z</published>
<updated>2026-06-03T18:46:44Z</updated>
<title>plan: RV32</title>
<link rel="alternate" type="text/html" href="commit/b9d9f14016146421df4aad8dc36cb35279db6258.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit b9d9f14016146421df4aad8dc36cb35279db6258
parent 972d2c69b2cde627f555c57732534d1452a281f0
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 11:46:44 -0700

plan: RV32

</content>
</entry>
<entry>
<id>972d2c69b2cde627f555c57732534d1452a281f0</id>
<published>2026-06-03T18:34:25Z</published>
<updated>2026-06-03T18:34:25Z</updated>
<title>test/coff: fix stale ARM64EC test to use KitTargetSpec (feature-model API)</title>
<link rel="alternate" type="text/html" href="commit/972d2c69b2cde627f555c57732534d1452a281f0.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit 972d2c69b2cde627f555c57732534d1452a281f0
parent dddc1f61c90cfd8dce44684c739c6e9242f43a72
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 11:34:25 -0700

test/coff: fix stale ARM64EC test to use KitTargetSpec (feature-model API)

The obj-api-tables refactor added an ARM64EC detection test written against
the pre-feature-model KitTarget type; rename to KitTargetSpec (which carries
.arch/.obj) to match the current kit_detect_target signature.

</content>
</entry>
<entry>
<id>dddc1f61c90cfd8dce44684c739c6e9242f43a72</id>
<published>2026-06-03T18:26:48Z</published>
<updated>2026-06-03T18:26:48Z</updated>
<title>cc: drop chatty &quot;ignoring accepted compatibility flag&quot; log</title>
<link rel="alternate" type="text/html" href="commit/dddc1f61c90cfd8dce44684c739c6e9242f43a72.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit dddc1f61c90cfd8dce44684c739c6e9242f43a72
parent c6c3fef5166e4061cab5a5959cfc7e10fc069def
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 11:26:48 -0700

cc: drop chatty &quot;ignoring accepted compatibility flag&quot; log

The debug-only log fired for every accepted-but-ignored compatibility
flag (-Wall, -std=, -nostdlib, ...), drowning out real diagnostics. Drop
the cc_log_ignored() helper and its 10 call sites; the flags are still
accepted, now silently. Update the driver test to assert silent
acceptance (clean stderr) instead of the removed message.

</content>
</entry>
<entry>
<id>c6c3fef5166e4061cab5a5959cfc7e10fc069def</id>
<published>2026-06-03T18:18:42Z</published>
<updated>2026-06-03T18:18:42Z</updated>
<title>obj/link: single-source no-location as SRCLOC_NONE; drop 22 no_loc() copies</title>
<link rel="alternate" type="text/html" href="commit/c6c3fef5166e4061cab5a5959cfc7e10fc069def.html" />
<author>
<name>Ryan Sepassi</name>
<email>rsepassi@gmail.com</email>
</author>
<content>commit c6c3fef5166e4061cab5a5959cfc7e10fc069def
parent a135713defeb03f4aca798cc4257b0f66efdae97
Author: Ryan Sepassi &lt;rsepassi@gmail.com&gt;
Date:   Wed,  3 Jun 2026 11:18:42 -0700

obj/link: single-source no-location as SRCLOC_NONE; drop 22 no_loc() copies

Replace the per-TU `static SrcLoc no_loc(void)` helper (duplicated verbatim
across 22 obj/ and link/ writers) with one SRCLOC_NONE macro in core/core.h.
Mechanical: 397 call sites rewritten, 22 definitions removed.

</content>
</entry>
</feed>
