cgen: wwstage cglet spills both eightbytes of a 16B tuple-from-call receive (#102)
wwstage-only. cglet had no 16B whole-tuple-from-call receive branch, so `let t = call()` whose callee returns a 2-eightbyte (16B) tuple fell through to the generic single-word store (MOVQ AX, off(BP)) and never spilled word1 (the DX eightbyte) — silent loss of t.1. Align to cstage cgen.c:6652, which spills both AX->off+0 and DX->off+8. Not a tupstore cursor off-by-one and not f64-specific: the destructure form `let (a,b) = call()` (cgmlet + tupstore cursor) was already byte-id; only the whole-tuple N_LET receive dropped word1, for any element mix incl. all-integer (i64,i64). An f64 element surfaced it first. The f64 element rides its eightbyte in AX/DX at receive and is re-read from X0/XMM at field-read (already byte-id), so no SSE cursor is needed.
This commit is contained in:
@@ -864,6 +864,26 @@ fn cglet(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// 16B tuple init from a function call: SysV returns a
|
||||
// 16-byte aggregate across the integer cursor (AX, DX). Spill
|
||||
// BOTH eightbytes over the integer registers — an f64 element
|
||||
// also rides its eightbyte in AX/DX here and is re-read from
|
||||
// X0/XMM at field-read time, so no SSE cursor is needed (the
|
||||
// f64 read is already byte-id). Mirror of cstage cgen.c:6652.
|
||||
// Without this branch a 16B tuple receive (any element mix,
|
||||
// incl. all-integer) fell to the generic single-word store
|
||||
// below and dropped word1 — silent loss of t.1 (#102).
|
||||
if (rettupleof(c, rhs) != nil && sz == 16) {
|
||||
cgexpr(c, rhs);
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff(off: i64);
|
||||
emitline("(BP)\n");
|
||||
emitline("\tMOVQ\tDX, ");
|
||||
emitoff((off + 8): i64);
|
||||
emitline("(BP)\n");
|
||||
c.lastwasreturn = 0;
|
||||
return;
|
||||
};
|
||||
// Array literal init: `let xs: [N]T = [a, b, c];` (or [_]T).
|
||||
// Walk elements in declaration order, store each at off + i*esz
|
||||
// using the right width for the element type. Trailing `...`
|
||||
|
||||
Reference in New Issue
Block a user