selfhost: cgfnparams slice/str straddle stitch (closes #11)
Three branches (tagged/slice/str) in cgendecl.ww now structurally symmetric — partial-fit reg+stack stitching. cgfn pre-scan predicate widened to (istg || issl || isst). Variadic T... at straddle is the last open class, deferred to task #12.
This commit is contained in:
@@ -13606,10 +13606,37 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
emitoff((off + 16): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
} else { if (idx < 6) {
|
||||
// Partial-fit stitch — mirrors tagged at lines
|
||||
// 440-469. Caller's pushargsrev greedy-fills the
|
||||
// remaining argregs (ptr,len,cap order), the tail
|
||||
// spills to +16+stkcursor*8(BP).
|
||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
||||
let regs_left: i32 = 6 - idx;
|
||||
let w: i32 = 0;
|
||||
for (w < regs_left) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitline(argregname(idx));
|
||||
emitline(", ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
w += 1;
|
||||
};
|
||||
for (w < 3) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((16 + stkcursor*8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
stkcursor += 1;
|
||||
w += 1;
|
||||
};
|
||||
} else {
|
||||
localaddstack(c, nm, p.lhs, 16 + stkcursor*8);
|
||||
stkcursor += 3;
|
||||
};
|
||||
};};
|
||||
} else { if (isstrtype(c, p.lhs)) {
|
||||
if (idx + 2 <= 6) {
|
||||
let off: i32 = localadd(c, nm, 16, p.lhs);
|
||||
@@ -13625,10 +13652,37 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
emitoff((off + 8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
} else { if (idx < 6) {
|
||||
// Partial-fit stitch — mirrors tagged at lines
|
||||
// 440-469. Only idx=5 hits this (nw=2,
|
||||
// regs_left=1): ptr lands in R9, len at
|
||||
// +16+stkcursor*8(BP).
|
||||
let off: i32 = localadd(c, nm, 16, p.lhs);
|
||||
let regs_left: i32 = 6 - idx;
|
||||
let w: i32 = 0;
|
||||
for (w < regs_left) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitline(argregname(idx));
|
||||
emitline(", ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
w += 1;
|
||||
};
|
||||
for (w < 2) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((16 + stkcursor*8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
stkcursor += 1;
|
||||
w += 1;
|
||||
};
|
||||
} else {
|
||||
localaddstack(c, nm, p.lhs, 16 + stkcursor*8);
|
||||
stkcursor += 2;
|
||||
};
|
||||
};};
|
||||
} else {
|
||||
if (idx < 6) {
|
||||
let off: i32 = localadd(c, nm, 8, p.lhs);
|
||||
@@ -13725,14 +13779,15 @@ fn cgfn(c: *cgen, fn_: *node) void = {
|
||||
frame += sz;
|
||||
if (isf) { fargi += 1; }
|
||||
else { argi += eb; };
|
||||
} else { if (eb > 1 && regs_left > 0 && istg) {
|
||||
// Tagged param straddles the reg/stack boundary;
|
||||
} else { if (eb > 1 && regs_left > 0 && (istg || issl || isst)) {
|
||||
// Multi-word param straddles the reg/stack boundary;
|
||||
// cgfnparams stitches the tail from positive BP
|
||||
// offsets into a single local slot, so we still
|
||||
// reserve the full size. Slice/str at the same
|
||||
// straddle are *not* stitched by cgfnparams today
|
||||
// (task #11) — once that's fixed the predicate
|
||||
// here must widen symmetrically.
|
||||
// reserve the full size. Symmetric across tagged,
|
||||
// slice and str (cgendecl.ww:440/491/537). Variadic
|
||||
// `T...` is deliberately omitted (task #12) — the
|
||||
// cgfnparams variadic branch doesn't stitch yet, so
|
||||
// it falls through to the pure-stack accounting.
|
||||
frame += sz;
|
||||
argi = 6;
|
||||
} else {
|
||||
|
||||
@@ -488,10 +488,37 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
emitoff((off + 16): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
} else { if (idx < 6) {
|
||||
// Partial-fit stitch — mirrors tagged at lines
|
||||
// 440-469. Caller's pushargsrev greedy-fills the
|
||||
// remaining argregs (ptr,len,cap order), the tail
|
||||
// spills to +16+stkcursor*8(BP).
|
||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
||||
let regs_left: i32 = 6 - idx;
|
||||
let w: i32 = 0;
|
||||
for (w < regs_left) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitline(argregname(idx));
|
||||
emitline(", ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
w += 1;
|
||||
};
|
||||
for (w < 3) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((16 + stkcursor*8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
stkcursor += 1;
|
||||
w += 1;
|
||||
};
|
||||
} else {
|
||||
localaddstack(c, nm, p.lhs, 16 + stkcursor*8);
|
||||
stkcursor += 3;
|
||||
};
|
||||
};};
|
||||
} else { if (isstrtype(c, p.lhs)) {
|
||||
if (idx + 2 <= 6) {
|
||||
let off: i32 = localadd(c, nm, 16, p.lhs);
|
||||
@@ -507,10 +534,37 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
emitoff((off + 8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
} else { if (idx < 6) {
|
||||
// Partial-fit stitch — mirrors tagged at lines
|
||||
// 440-469. Only idx=5 hits this (nw=2,
|
||||
// regs_left=1): ptr lands in R9, len at
|
||||
// +16+stkcursor*8(BP).
|
||||
let off: i32 = localadd(c, nm, 16, p.lhs);
|
||||
let regs_left: i32 = 6 - idx;
|
||||
let w: i32 = 0;
|
||||
for (w < regs_left) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitline(argregname(idx));
|
||||
emitline(", ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
w += 1;
|
||||
};
|
||||
for (w < 2) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((16 + stkcursor*8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
stkcursor += 1;
|
||||
w += 1;
|
||||
};
|
||||
} else {
|
||||
localaddstack(c, nm, p.lhs, 16 + stkcursor*8);
|
||||
stkcursor += 2;
|
||||
};
|
||||
};};
|
||||
} else {
|
||||
if (idx < 6) {
|
||||
let off: i32 = localadd(c, nm, 8, p.lhs);
|
||||
@@ -607,14 +661,15 @@ fn cgfn(c: *cgen, fn_: *node) void = {
|
||||
frame += sz;
|
||||
if (isf) { fargi += 1; }
|
||||
else { argi += eb; };
|
||||
} else { if (eb > 1 && regs_left > 0 && istg) {
|
||||
// Tagged param straddles the reg/stack boundary;
|
||||
} else { if (eb > 1 && regs_left > 0 && (istg || issl || isst)) {
|
||||
// Multi-word param straddles the reg/stack boundary;
|
||||
// cgfnparams stitches the tail from positive BP
|
||||
// offsets into a single local slot, so we still
|
||||
// reserve the full size. Slice/str at the same
|
||||
// straddle are *not* stitched by cgfnparams today
|
||||
// (task #11) — once that's fixed the predicate
|
||||
// here must widen symmetrically.
|
||||
// reserve the full size. Symmetric across tagged,
|
||||
// slice and str (cgendecl.ww:440/491/537). Variadic
|
||||
// `T...` is deliberately omitted (task #12) — the
|
||||
// cgfnparams variadic branch doesn't stitch yet, so
|
||||
// it falls through to the pure-stack accounting.
|
||||
frame += sz;
|
||||
argi = 6;
|
||||
} else {
|
||||
|
||||
@@ -13606,10 +13606,37 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
emitoff((off + 16): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
} else { if (idx < 6) {
|
||||
// Partial-fit stitch — mirrors tagged at lines
|
||||
// 440-469. Caller's pushargsrev greedy-fills the
|
||||
// remaining argregs (ptr,len,cap order), the tail
|
||||
// spills to +16+stkcursor*8(BP).
|
||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
||||
let regs_left: i32 = 6 - idx;
|
||||
let w: i32 = 0;
|
||||
for (w < regs_left) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitline(argregname(idx));
|
||||
emitline(", ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
w += 1;
|
||||
};
|
||||
for (w < 3) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((16 + stkcursor*8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
stkcursor += 1;
|
||||
w += 1;
|
||||
};
|
||||
} else {
|
||||
localaddstack(c, nm, p.lhs, 16 + stkcursor*8);
|
||||
stkcursor += 3;
|
||||
};
|
||||
};};
|
||||
} else { if (isstrtype(c, p.lhs)) {
|
||||
if (idx + 2 <= 6) {
|
||||
let off: i32 = localadd(c, nm, 16, p.lhs);
|
||||
@@ -13625,10 +13652,37 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
emitoff((off + 8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
} else { if (idx < 6) {
|
||||
// Partial-fit stitch — mirrors tagged at lines
|
||||
// 440-469. Only idx=5 hits this (nw=2,
|
||||
// regs_left=1): ptr lands in R9, len at
|
||||
// +16+stkcursor*8(BP).
|
||||
let off: i32 = localadd(c, nm, 16, p.lhs);
|
||||
let regs_left: i32 = 6 - idx;
|
||||
let w: i32 = 0;
|
||||
for (w < regs_left) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitline(argregname(idx));
|
||||
emitline(", ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
idx += 1;
|
||||
w += 1;
|
||||
};
|
||||
for (w < 2) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((16 + stkcursor*8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((off + w*8): i64);
|
||||
emitline("(BP)\n");
|
||||
stkcursor += 1;
|
||||
w += 1;
|
||||
};
|
||||
} else {
|
||||
localaddstack(c, nm, p.lhs, 16 + stkcursor*8);
|
||||
stkcursor += 2;
|
||||
};
|
||||
};};
|
||||
} else {
|
||||
if (idx < 6) {
|
||||
let off: i32 = localadd(c, nm, 8, p.lhs);
|
||||
@@ -13725,14 +13779,15 @@ fn cgfn(c: *cgen, fn_: *node) void = {
|
||||
frame += sz;
|
||||
if (isf) { fargi += 1; }
|
||||
else { argi += eb; };
|
||||
} else { if (eb > 1 && regs_left > 0 && istg) {
|
||||
// Tagged param straddles the reg/stack boundary;
|
||||
} else { if (eb > 1 && regs_left > 0 && (istg || issl || isst)) {
|
||||
// Multi-word param straddles the reg/stack boundary;
|
||||
// cgfnparams stitches the tail from positive BP
|
||||
// offsets into a single local slot, so we still
|
||||
// reserve the full size. Slice/str at the same
|
||||
// straddle are *not* stitched by cgfnparams today
|
||||
// (task #11) — once that's fixed the predicate
|
||||
// here must widen symmetrically.
|
||||
// reserve the full size. Symmetric across tagged,
|
||||
// slice and str (cgendecl.ww:440/491/537). Variadic
|
||||
// `T...` is deliberately omitted (task #12) — the
|
||||
// cgfnparams variadic branch doesn't stitch yet, so
|
||||
// it falls through to the pure-stack accounting.
|
||||
frame += sz;
|
||||
argi = 6;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user