w6c: set variadic-call AL to XMM-reg count, not hardcoded 0 (catB-54 C1)

SysV §3.5.7 requires a variadic call to set AL = number of vector (XMM) regs used for the variable float args; the C callee gates its xmm-save-area stores on `test %al,%al`, so the old hardcoded XORQ AX,AX (AL=0) made va_arg(double) read garbage for any float-bearing C variadic call. Emit MOVQ $fi,AX (fi = the in-scope XMM cursor, ≤8); w6a has no MOVL-immediate encoding so MOVQ is the assemblable form and sets AL=fi identically. fi==0 keeps XORQ → byte-identical to pre-fix for no-float variadic calls. Runtime test 989_ffivariadic links a cc-compiled va_arg(double) fixture (zero relocs/undefined, w6l-linkable) and sweeps N=3/5/8 floats (N=2 is vacuous via stale-stack aliasing). C1 of the C-FFI-variadic align-up (USER ruling); C2 wwstage + C3 bodiless gate follow. ref/qbe/amd64/sysv.c:384. 454 green.
This commit is contained in:
2026-06-20 23:21:44 +09:00
parent b9692b14f1
commit 294f4c93fd
4 changed files with 218 additions and 5 deletions

View File

@@ -264,6 +264,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_taggedcompoundplace_reject \
$(BIN)/test_libprecond_abort \
$(BIN)/test_idxarg_run \
$(BIN)/test_ffivariadic_run \
$(BIN)/test_chainidx_run \
$(BIN)/test_m1mangle_run \
$(BIN)/test_m1mangle_sym \
@@ -828,6 +829,26 @@ $(BIN)/test_idxarg_run: test/wcc/989_idxarg_run.c \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# 989_ffivariadic_run (C1, catB-54): a ww caller of a C variadic fn must set
# the SysV AL register to the count of XMM regs used for the variadic float
# args — a RUNTIME-only correctness property (byte-id is blind to AL). The cc
# fixture is built self-contained (zero relocs + zero undef syms, verified via
# readelf -r / nm) so w6l links it with no libc, then wrapped in libffifix.a
# under $(OUT)/ffivariadic (the harness finds it via $(BIN)/../ffivariadic).
# cstage `ww` ONLY — wwstage AL is C2. Fixture flags are fixed (NOT $(CFLAGS),
# which is -O0/-std=c99) to match ken's verified self-contained build.
$(OUT)/ffivariadic/libffifix.a: test/wcc/data/ffivariadic/fixture.c
@mkdir -p $(OUT)/ffivariadic
$(CC) -O1 -fno-stack-protector -fno-asynchronous-unwind-tables \
-fcf-protection=none -c -o $(OUT)/ffivariadic/fixture.o $<
$(AR) rcs $@ $(OUT)/ffivariadic/fixture.o
$(BIN)/test_ffivariadic_run: test/wcc/989_ffivariadic_run.c \
$(OUT)/ffivariadic/libffifix.a \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# 989_chainidx_run (F7-c3, #22): a chained index `m[i][k]` whose element is
# a str/slice must load the full 24B/16B header. Builds+runs each fixture on
# BOTH the cstage `ww` and wwstage `ww_ww` drivers (rule-10).