cgen: widen the narrow-tail aggregate-register store to full sz<=24 at every routed site (#14)
Completes the #14 close-by-construction begun by the helper extraction (e7fefa3): every <=24B aggregate register-store now routes through cg_agg_reg_store/cgaggregstore and handles all tail sizes. B/C/D/G fix a silent both-stage drop of a 3/5/6/7-byte tail (byte-id-blind: both stages dropped identically, so the gate could not see it). A/F enable a previously loud-rejected shape (a cgen backend gap, not a type rejection; harec accepts and lowers it). G (global g=f() array) routes symmetrically, dest_padded=false. The #11 arr[i].f scratch loops fold into the helper (dest_padded=true, byte-id zero-change), completing the grep-audit. Pins value-assert each eightbyte (the class is byte-id-blind) and redden under each stage's independent revert; site H's 3/5/6/7 let-receive stays a loud fatal (#22).
This commit is contained in:
@@ -5325,19 +5325,16 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *syntax.node,
|
||||
// silently dropped past the first qword for any
|
||||
// fsz > 8 (only AX got stored).
|
||||
//
|
||||
// Sized stores: MOVQ for full 8B chunks plus a
|
||||
// sized tail (MOVL/MOVW/MOVB) by `tail = fsz%8`.
|
||||
// Mirror of cstage cg_structlit_fill's #20 branch.
|
||||
// MOVW-for-tail==2 only fires on shapes that
|
||||
// didn't compile before, so no #13 byte-identity
|
||||
// concern.
|
||||
// The choke-point stores MOVQ for full 8B chunks
|
||||
// plus a sized tail (MOVL/MOVW/MOVB) by `tail =
|
||||
// fsz%8`. Mirror of cstage cg_structlit_fill's #20
|
||||
// branch.
|
||||
//
|
||||
// Guard `fsz <= 24 && fsz%8 ∈ {0,1,2,4}` matches
|
||||
// #4's cgreturn ABI: >24B falls through (sret
|
||||
// deferred); fsz%8 ∈ {3,5,6,7} would need shift-
|
||||
// store and is also unsupported by #4 — falls
|
||||
// through to the existing AX-only wrongness
|
||||
// (consistent, tracked as follow-up).
|
||||
// Guard `cfsz <= 24` (#14 widened from {0,1,2,4}):
|
||||
// the choke-point handles every in-cap tail incl.
|
||||
// 3/5/6/7 via its non-padded scratch detour
|
||||
// (dest_padded=false — a struct-lit field is
|
||||
// packed); >24B falls through (sret deferred).
|
||||
//
|
||||
// INVARIANT: between cgexpr(N_CALL) and the
|
||||
// AX/DX/CX stores below, NO instruction may touch
|
||||
@@ -5369,10 +5366,8 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *syntax.node,
|
||||
// MOVQ+MOVL where cstage
|
||||
// writes MOVQ+MOVQ.
|
||||
let cfsz: i32 = structabisize(csi);
|
||||
let crem: i32 = cfsz - (cfsz / 8) * 8;
|
||||
if (cfsz <= 24) {
|
||||
if (crem == 0 || crem == 1
|
||||
|| crem == 2 || crem == 4) {
|
||||
// #14: choke-point now stores every in-cap tail; 3/5/6/7 no longer dropped to a lone narrow MOV.
|
||||
cgexpr(c, fieldnode.lhs);
|
||||
if (mode == 1) {
|
||||
emitline("\tMOVQ\t");
|
||||
@@ -5390,7 +5385,6 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *syntax.node,
|
||||
cgaggregstore(c, basereg, disp + fi.foff, cfsz, false);
|
||||
callwhole = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user