selfhost: cgfnparams variadic T... straddle stitch (closes #12)

Last reg/stack-straddle gap closed — variadic T... now stitches at
idx=5/regs_left=1/nw=3. Four classes (tagged/slice/str/variadic) at
cgendecl.ww 467/518/564/394 are now structurally symmetric. cgfn
pre-scan predicate widened to (istg || issl || isst || isvar).
cstage unchanged — type-promoted T... → []T already hits the slice
partial-fit branch.
This commit is contained in:
2026-05-14 00:36:34 +09:00
parent f2b47087a2
commit f26c86f5b7
4 changed files with 152 additions and 18 deletions

View File

@@ -209,6 +209,65 @@ static const struct row rows[] = {
" return 0;\n"
"};\n",
42 },
/* Variadic `T...` fully in regs: 3 i64 + 1 variadic. idx=3
* entering the synthesised slice (regs_left=3, nw=3) — DI/SI/DX
* carry a/b/c, CX/R8/R9 carry ptr/len/cap. Full-reg-fit regression:
* pins that the stitch addition doesn't shadow the `idx+3 <= 6`
* branch. */
{ "variadic_full_in_reg",
"fn vs(a: i64, b: i64, c: i64, xs: i64...) i64 = {\n"
" let i: i32 = 0;\n"
" let acc: i64 = a + b + c;\n"
" for (i < xs.len: i32) { acc = acc + xs[i]; i = i + 1; };\n"
" return acc + (xs.cap: i64);\n"
"};\n"
"fn main() i32 = {\n"
" let r: i64 = vs(1i64, 2i64, 3i64,\n"
" 10i64, 20i64, 30i64);\n"
" if (r == 69i64) { return 42; };\n"
" return 0;\n"
"};\n",
42 },
/* Variadic `T...` at the reg/stack straddle: 5 i64 + 1 variadic.
* idx=5 entering the synthesised slice (regs_left=1, nw=3) — ptr
* lands in R9, len and cap spill to +16/+24(BP). The variadic
* branch in cgfnparams must stitch identically to the slice branch
* (task #12). The body sums the fixed args, the variadic
* elements, and adds cap to pin the third header word. */
{ "variadic_straddle",
"fn vs(a: i64, b: i64, c: i64, d: i64, e: i64, xs: i64...) i64 = {\n"
" let i: i32 = 0;\n"
" let acc: i64 = a + b + c + d + e;\n"
" for (i < xs.len: i32) { acc = acc + xs[i]; i = i + 1; };\n"
" return acc + (xs.cap: i64);\n"
"};\n"
"fn main() i32 = {\n"
" let r: i64 = vs(1i64, 2i64, 3i64, 4i64, 5i64,\n"
" 10i64, 20i64, 30i64);\n"
" if (r == 78i64) { return 42; };\n"
" return 0;\n"
"};\n",
42 },
/* Variadic `T...` past the register window: 6 i64 saturate argi,
* the synthesised slice (3 eightbytes) goes wholly to the stack
* via localaddstack. Pure-stack regression check — pins that the
* new stitch code doesn't bleed into the existing pure-stack
* branch (regs_left=0, nw=3). */
{ "variadic_purestack",
"fn vs(a: i64, b: i64, c: i64, d: i64, e: i64, f: i64,\n"
" xs: i64...) i64 = {\n"
" let i: i32 = 0;\n"
" let acc: i64 = a + b + c + d + e + f;\n"
" for (i < xs.len: i32) { acc = acc + xs[i]; i = i + 1; };\n"
" return acc + (xs.cap: i64);\n"
"};\n"
"fn main() i32 = {\n"
" let r: i64 = vs(1i64, 2i64, 3i64, 4i64, 5i64, 6i64,\n"
" 10i64, 20i64, 30i64);\n"
" if (r == 84i64) { return 42; };\n"
" return 0;\n"
"};\n",
42 },
/* str past the register window: 6 ints saturate argi, the str
* (2 eightbytes) goes wholly to the stack via localaddstack.
* Both .ptr and .len must round-trip. */