w6c+wwstage: emit over-cap tuple return via sret callee-side (#10 Fold A)
A tuple return whose SysV register-return footprint exceeds the caps
(> 4 integer eightbytes or > 2 SSE eightbytes) previously LOUD-STOPPED
at the N_RETURN SEND. Fold A makes the CALLEE emit such a return through
the existing >24B-struct sret skeleton:
- classifier (cg_sret_retsize / sretretsize) grows a TY_TUPLE arm:
walk the element footprint over the SAME caps the SEND uses, and
return the tuple's natural total size (type table) when over-cap,
else 0. The gp/sse caps are factored to a single shared SSoT
(TUPLE_GPCAP / TUPLE_SSECAP — cgen.c macros in cstage, cgen.ww defs
in wwstage) consumed by the classifier AND every emit/receive site
(the SEND, the destructure guards, the cgcall arg guard) — so
classify and emit can't disagree in either stage.
- the SEND replaces the loud-stop with a write-through: cgexpr each
element, store it through *(@sretarg) at its packed layout offset
(the t.0/t.1 positional layout), each at its natural width so a
narrow tail stores MOVL/MOVB not an over-MOVQ (#169); the dest base
reloads into DX each step since a wide element clobbers AX/BX/CX.
Then the existing struct-sret epilogue (MOVQ @sretarg->AX; ret).
- the prologue already wires @sretarg when the classifier is nonzero.
The CALL/receive side is deliberately untouched: the N_MLET/N_MASSIGN
destructure loud-stops stay, so an over-cap tuple return is not yet
usefully callable. The end-to-end round-trip arrives with Fold B (#10-B).
Symmetric cstage (cmd/w6c/cgen.c) + wwstage (cgen.ww / cgenstmt.ww /
cgenutil.ww); combined.ww amalgams regenerated. Test 798 asserts the
callee now COMPILES (no loud-stop) and w6c vs w6c_ww .s byte-identical
across all-wide, str, narrow-tail, and float-over-cap shapes; no runtime
row (uncallable until Fold B). All 236 pass incl. 990-997 byte-id.
This commit is contained in:
@@ -449,6 +449,15 @@ type enumtype = struct {
|
||||
def LOOP_MAX: i32 = 16;
|
||||
def DEFER_MAX: i32 = 16;
|
||||
|
||||
// The SysV register-return-ABI caps — the SINGLE SSoT shared by the sret
|
||||
// classifier (sretretsize over-cap-tuple arm) AND every emit/receive site
|
||||
// (cgreturn tuple SEND, cgmlet/cgmassign destructure, cgcall arg guard).
|
||||
// Classify and emit MUST agree on these, else a tuple gets classified
|
||||
// sret by one and in-reg by the other -> corruption. Mirrors cstage
|
||||
// cgen.c TUPLE_GPCAP/TUPLE_SSECAP (#10).
|
||||
def TUPLE_GPCAP: i32 = 4; // AX,DX,CX,R8
|
||||
def TUPLE_SSECAP: i32 = 2; // X0,X1
|
||||
|
||||
type cgen = struct {
|
||||
locals: *local,
|
||||
// atlocals — persistent registry of `@`-prefix scratch slots
|
||||
|
||||
Reference in New Issue
Block a user