wcc: struct ABI size maxalign-rounded via structabisize (#169)
wwstage struct-return RECV and RETURN used unrounded / round-to-8 sizes where
cstage uses the maxalign-rounded lu->size / rt->size, so a struct with maxalign
8 and a sub-8 tail (e.g. struct{i64,i32}) — or a maxalign<8 struct on the
return path — unpacked with a different trailing-word width (MOVL vs MOVQ)
between stages. Value-correct either way, but a cs!=ww asm divergence.
Add a dedicated structabisize = round(natural, maxalign) used only at the two
register-ABI sites. structnaturalsize stays unrounded: cstage's >24B sret and
memory-move path (cgen.c:8150, Task #33) genuinely uses the unrounded natural
size, so the two are different sizes — rounding the shared metric breaks 995.
maxalign derives from each field's tinfo.align (mirrors cstage check.c:708),
not an fsz ladder (a ladder over-rounds composite [N]u8 fields).
Gate-blind (no bootstrap struct hits the maxalign-8+tail shape) — the
discriminator is the cs==ww .s byte-cmp; covered by probe 698.
This commit is contained in:
@@ -656,7 +656,10 @@ fn cgreturn(c: *cgen, n: *node) void = {
|
||||
if (rname.len > 0) {
|
||||
let rsi: *structinfo = structlookup(c, rname);
|
||||
if (rsi != nil) {
|
||||
let rsz: i32 = rsi.totsize;
|
||||
// ≤24B register RETURN: cstage sizes by rt->size
|
||||
// (maxalign-rounded), not the slot-padded totsize
|
||||
// (round-to-8) — see structabisize (#169).
|
||||
let rsz: i32 = structabisize(rsi);
|
||||
if (rsz <= 24) {
|
||||
let okrhs: bool = false;
|
||||
if (rhs.kind == nkind.N_IDENT) {
|
||||
@@ -1214,10 +1217,11 @@ fn cglet(c: *cgen, n: *node) void = {
|
||||
if (sname.len > 0) {
|
||||
let lsi: *structinfo = structlookup(c, sname);
|
||||
if (lsi != nil) {
|
||||
// si.totsize is slot-padded (rounded to 8) for
|
||||
// stack-slot use; the receive ABI needs the
|
||||
// TYPE's natural size — see structnaturalsize.
|
||||
let lsz: i32 = structnaturalsize(lsi);
|
||||
// ≤24B register RECV: the value arrives packed
|
||||
// in AX/DX/CX, so size by the maxalign-rounded
|
||||
// ABI size (cstage lu->size), not the natural
|
||||
// extent — see structabisize (#169).
|
||||
let lsz: i32 = structabisize(lsi);
|
||||
let tlm: i32 = lsz - (lsz / 8) * 8;
|
||||
if (lsz <= 24) {
|
||||
if (tlm == 0 || tlm == 1
|
||||
|
||||
Reference in New Issue
Block a user