w6c+wwstage: array return-by-value via the struct-return ABI (#267 fold-2)

Wire TY_ARRAY into the existing struct-return gates so arrays ride the
same reg-class (<=24B in AX:DX:CX) / sret-class (>24B) path the struct
return ABI already emits byte-identically. No new ABI machinery.

Both stages, uniform gate-widen:
- cg_sret_retsize / sretretsize: +TY_ARRAY (natural size sub.size*len,
  the type table) -> auto-enables sret send/recv + the >24B sret N_IDENT
  word-copy + return-forward, all keyed on the shared sret SSoT.
- cgreturn <=24B reg-send: +TY_ARRAY (N_IDENT scratch word-copy ->
  AX/DX/CX). reg-class return-forward rides the default cgexpr passthrough.
- let-init / assign <=24B recv: +TY_ARRAY (AX/DX/CX sized stores).

struct_float_class stays struct-only: pure-int element arrays only; no
pure-float-array-return consumer exists today.

949 +11 rows: reg-class 8/16/24B + sret-class 32B, [N]u32 and [N]u8,
at let-init/assign/return-forward, full-member readback, + a struct-
return regression control. All cstage-run + cs==ww byte-id.
This commit is contained in:
2026-06-02 12:00:58 +09:00
parent 35b517ca3e
commit ebbc3f98c2
7 changed files with 682 additions and 6 deletions

View File

@@ -1304,6 +1304,18 @@ export fn sretretsize(c: *cgen, t: *node) i32 = {
};
return 0;
};
// #267: arrays ride the struct-return ABI — natural size
// (sub.size*len, the type table) gates ≤24 reg / >24 sret, mirroring
// cstage cg_sret_retsize TY_ARRAY arm. Pure-int element arrays only;
// no float-array-return consumer (structfloatclass stays struct-only).
if (r.kind == nkind.N_TARRAY) {
let ati: *tinfo = r.type_: *tinfo;
for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; };
if (ati == nil) { return 0; };
let asz: i32 = ati.size: i32;
if (asz <= 24) { return 0; };
return asz;
};
if (r.kind != nkind.N_TNAME) { return 0; };
// Primitives / aliased-to-primitives are never sret.
if (primsize(r.str) > 0) { return 0; };