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:
@@ -596,7 +596,7 @@ fn cgreturn(c: *cgen, n: *node) void = {
|
||||
// the dest pointer IS the struct base.
|
||||
cgstructlitfill(c, sret_si, rhs,
|
||||
1, sretargoff, emptys,
|
||||
0, scs);
|
||||
0);
|
||||
};
|
||||
} else {
|
||||
let rl: *local = localfindnode(c, rhs.str);
|
||||
@@ -1469,26 +1469,40 @@ fn cglet(c: *cgen, n: *node) void = {
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_TARRAY) { isarr = true; };
|
||||
};
|
||||
// Zero-fill extent. cstage sizes the run on `lu->size`
|
||||
// (the maxalign-rounded ABI size, check.c:760); wwstage's
|
||||
// `sz` from letslotsize is slot-padded (round-to-8), so a
|
||||
// struct with maxalign<8 and a sub-8 tail would over-zero
|
||||
// MOVQ where cstage emits MOVL/MOVB. Read structabisize
|
||||
// for a struct-typed let to converge; slot allocation
|
||||
// stays on `sz` (frame uses slot-padded slots).
|
||||
let zsz: i32 = sz;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_TNAME) {
|
||||
let szi: *structinfo = structlookupchain(c, n.lhs);
|
||||
if (szi != nil) { zsz = structabisize(szi); };
|
||||
};
|
||||
};
|
||||
if (typeis8byteprimitive(c, n.lhs)) {
|
||||
emitline("\tMOVQ\t$0, ");
|
||||
emitoff(off: i64);
|
||||
emitline("(BP)\n");
|
||||
} else { if (!isarr) { if (sz > 8) {
|
||||
} else { if (!isarr) { if (zsz > 8) {
|
||||
emitline("\tXORQ\tAX, AX\n");
|
||||
let zi: i32 = 0;
|
||||
for (zi + 8 <= sz) {
|
||||
for (zi + 8 <= zsz) {
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + zi): i64);
|
||||
emitline("(BP)\n");
|
||||
zi += 8;
|
||||
};
|
||||
for (zi + 4 <= sz) {
|
||||
for (zi + 4 <= zsz) {
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((off + zi): i64);
|
||||
emitline("(BP)\n");
|
||||
zi += 4;
|
||||
};
|
||||
for (zi < sz) {
|
||||
for (zi < zsz) {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((off + zi): i64);
|
||||
emitline("(BP)\n");
|
||||
|
||||
Reference in New Issue
Block a user