Files
ww/test/wcc/data/ffivariadic/fixture.c
Hojun-Cho 294f4c93fd 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.
2026-06-20 23:21:58 +09:00

27 lines
639 B
C

/*
* C-FFI variadic test fixture (C1, catB-54). A va_arg(double) summer the
* ww caller links against to prove the SysV AL=XMM-count fix: the callee
* gates its xmm-save-area stores on `test %al,%al`, so a wrong AL makes
* these va_arg(double) reads pull garbage.
*
* Built self-contained (zero relocs, zero undef syms) so w6l can link it
* with no libc — verified via readelf -r / nm. Do not add any call that
* pulls in a libc symbol.
*/
#include <stdarg.h>
double
fixture(long n, ...)
{
va_list ap;
double s;
long i;
va_start(ap, n);
s = 0;
for(i = 0; i < n; i++)
s += va_arg(ap, double);
va_end(ap);
return s;
}