wcc: converge DOT-recv, structlit-fill, and bare-let zero-init onto structabisize
Three wwstage cgen sites still used the unrounded structnaturalsize where cstage rounds via lu->size (check.c:760), pre-existing gate-blind cs!=ww latents flagged in #169's reviewer notes: cgenexpr DOT register-RECV for obj.f = mk() (~5175/5393/5628/6164); cgstructlitfill's TK_ELLIPSIS zero-fill branch (cgenutil); and cglet bare 'let z: T;' zero-init of a maxalign<8 struct (cgenstmt). Each produced MOVQ-vs-MOVL or wider-write divergence vs cstage on the trailing word of a sub-eightbyte tail. Converge all three onto the maxalign-rounded structabisize the #169 work established at the register-ABI sites (cite cstage cgen.c:7720 RECV twin + cgen.c:2085 cg_structlit_fill). cgstructlitfill's signature drops the external totsize parameter in favor of one internal source; the field-walk path is untouched, only the ELLIPSIS zero-fill uses the ABI size. cglet's slot allocation stays on the frame size; only the zero-fill extent uses ABI. Gate-blind (the bootstrap exercises none of these shapes); covered by 5 new rows in probe 698 with cs==ww .s byte-cmp and a pre-fix-rebuild proving the exact MOVQ-vs-MOVL discrimination. 990-997 byte-id hold.
This commit is contained in:
@@ -5148,11 +5148,13 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
// N_IDENT: word-copy from rhs slot.
|
||||
// N_CALL: cgexpr → AX/DX/CX per #4's cgreturn
|
||||
// ABI; load *struct ptr into BX after the
|
||||
// call, sized stores per natural struct size.
|
||||
// call, sized stores per the ABI size.
|
||||
// N_STRUCTLIT: field-walk; reload BX before
|
||||
// each store so cgexpr can clobber AX/BX.
|
||||
// si.totsize is slot-padded; use
|
||||
// structnaturalsize for the type-size query.
|
||||
// register RECV reads AX/DX/CX at 8-byte
|
||||
// granularity — size via structabisize (cstage
|
||||
// SSoT lu->size, check.c:760; cgen.c:7720
|
||||
// sz=lu->size at the receive twin).
|
||||
if (n.op == tkind.TK_ASSIGN
|
||||
&& n.rhs != nil
|
||||
&& n.rhs.kind == nkind.N_CALL
|
||||
@@ -5161,7 +5163,7 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& primsize(fi.tnode.str) == 0) {
|
||||
let ssi: *structinfo = structlookup(c, fi.tnode.str);
|
||||
if (ssi != nil) {
|
||||
let ssz: i32 = structnaturalsize(ssi);
|
||||
let ssz: i32 = structabisize(ssi);
|
||||
if (ssz <= 24) {
|
||||
let tlm: i32 = ssz - (ssz / 8) * 8;
|
||||
if (tlm == 0 || tlm == 1
|
||||
@@ -5216,9 +5218,8 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& primsize(fi.tnode.str) == 0) {
|
||||
let ssi: *structinfo = structlookup(c, fi.tnode.str);
|
||||
if (ssi != nil) {
|
||||
let ssz: i32 = structnaturalsize(ssi);
|
||||
cgstructlitfill(c, ssi, n.rhs, 1, lc.off, "",
|
||||
fi.foff, ssz);
|
||||
fi.foff);
|
||||
return;
|
||||
};
|
||||
};
|
||||
@@ -5379,7 +5380,7 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& primsize(fi.tnode.str) == 0) {
|
||||
let ssi: *structinfo = structlookup(c, fi.tnode.str);
|
||||
if (ssi != nil) {
|
||||
let ssz: i32 = structnaturalsize(ssi);
|
||||
let ssz: i32 = structabisize(ssi);
|
||||
if (ssz <= 24) {
|
||||
let tlm: i32 = ssz - (ssz / 8) * 8;
|
||||
if (tlm == 0 || tlm == 1
|
||||
@@ -5430,9 +5431,8 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& primsize(fi.tnode.str) == 0) {
|
||||
let ssi: *structinfo = structlookup(c, fi.tnode.str);
|
||||
if (ssi != nil) {
|
||||
let ssz: i32 = structnaturalsize(ssi);
|
||||
cgstructlitfill(c, ssi, n.rhs, 0, 0, "",
|
||||
lc.off + fi.foff, ssz);
|
||||
lc.off + fi.foff);
|
||||
return;
|
||||
};
|
||||
};
|
||||
@@ -5614,7 +5614,7 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& primsize(fi.tnode.str) == 0) {
|
||||
let ssi: *structinfo = structlookup(c, fi.tnode.str);
|
||||
if (ssi != nil) {
|
||||
let ssz: i32 = structnaturalsize(ssi);
|
||||
let ssz: i32 = structabisize(ssi);
|
||||
if (ssz <= 24) {
|
||||
let tlm: i32 = ssz - (ssz / 8) * 8;
|
||||
if (tlm == 0 || tlm == 1
|
||||
@@ -5669,9 +5669,8 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& primsize(fi.tnode.str) == 0) {
|
||||
let ssi: *structinfo = structlookup(c, fi.tnode.str);
|
||||
if (ssi != nil) {
|
||||
let ssz: i32 = structnaturalsize(ssi);
|
||||
cgstructlitfill(c, ssi, n.rhs, 2, 0, bn,
|
||||
fi.foff, ssz);
|
||||
fi.foff);
|
||||
return;
|
||||
};
|
||||
};
|
||||
@@ -6148,9 +6147,10 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& leafstruct) {
|
||||
let lsi: *structinfo = structlookup(c, leafname);
|
||||
if (lsi != nil) {
|
||||
// si.totsize is slot-padded (rounded to 8);
|
||||
// receive ABI needs the TYPE's natural size.
|
||||
let lsz: i32 = structnaturalsize(lsi);
|
||||
// register RECV reads AX/DX/CX at 8-byte
|
||||
// granularity — size via structabisize
|
||||
// (cstage SSoT lu->size, check.c:760).
|
||||
let lsz: i32 = structabisize(lsi);
|
||||
if (lsz <= 24) {
|
||||
let tlm: i32 = lsz - (lsz / 8) * 8;
|
||||
if (tlm == 0 || tlm == 1
|
||||
@@ -6231,9 +6231,6 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
&& leafstruct) {
|
||||
let lsi: *structinfo = structlookup(c, leafname);
|
||||
if (lsi != nil) {
|
||||
// si.totsize is slot-padded (rounded to 8);
|
||||
// receive ABI needs the TYPE's natural size.
|
||||
let lsz: i32 = structnaturalsize(lsi);
|
||||
let dmode: i32 = 0;
|
||||
let ddisp: i32 = rootoff + totaloff;
|
||||
if (ptrroot) {
|
||||
@@ -6246,7 +6243,7 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
cgstructlitfill(c, lsi, n.rhs,
|
||||
dmode, rootoff, rootname,
|
||||
ddisp, lsz);
|
||||
ddisp);
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user