w6c+selfhost: cgen N_ASSIGN TY_SLICE field branch (closes #24)

Parallel to the existing TY_STR branch at cgen.c:1939. Stores AX/BX/CX
at field+0/+8/+16 across three sub-shapes (via_ptr, is_global, direct
local) — DX as addr scratch where needed so CX (cap) survives.
Symmetric in wwstage cgassign. Surfaces tasks #25 (whole-struct rhs)
and #26 (whole-tagged rhs) in the same locus class.
This commit is contained in:
2026-05-14 03:18:49 +09:00
parent 79c758c046
commit eb0602d070
5 changed files with 221 additions and 0 deletions

View File

@@ -11661,6 +11661,26 @@ fn cgassign(c: *cgen, n: *node) void = {
emitline("\n");
return;
};
// slice field via *struct: rhs left
// (AX=ptr, BX=len, CX=cap). CX is
// taken, so stage the struct addr
// in DX. Store all three words at
// foff/+8/+16.
if (isslicetype(c, fi.tnode)) {
emitline("\tMOVQ\t");
emitoff(lc.off: i64);
emitline("(BP), DX\n");
emitline("\tMOVQ\tAX, ");
emitdispreg(fi.foff: i64, "DX");
emitline("\n");
emitline("\tMOVQ\tBX, ");
emitdispreg((fi.foff + 8): i64, "DX");
emitline("\n");
emitline("\tMOVQ\tCX, ");
emitdispreg((fi.foff + 16): i64, "DX");
emitline("\n");
return;
};
// f64/f32 plain `=` via *struct: cgexpr left the
// value in X0. Reload struct ptr and MOVSD/MOVSS.
if (isfloattype(c, fi.tnode)) {
@@ -11717,6 +11737,23 @@ fn cgassign(c: *cgen, n: *node) void = {
emitline("(BP)\n");
return;
};
// slice field direct: cgexpr left
// (AX=ptr, BX=len, CX=cap); store all
// three at +0/+8/+16. The generic
// fldstoreop below would only write AX,
// dropping .len/.cap.
if (isslicetype(c, fi.tnode)) {
emitline("\tMOVQ\tAX, ");
emitoff((lc.off + fi.foff): i64);
emitline("(BP)\n");
emitline("\tMOVQ\tBX, ");
emitoff((lc.off + fi.foff + 8): i64);
emitline("(BP)\n");
emitline("\tMOVQ\tCX, ");
emitoff((lc.off + fi.foff + 16): i64);
emitline("(BP)\n");
return;
};
// f64/f32 direct struct local store: route via X0.
if (isfloattype(c, fi.tnode)) {
let mov: str = "MOVSD";

View File

@@ -3613,6 +3613,26 @@ fn cgassign(c: *cgen, n: *node) void = {
emitline("\n");
return;
};
// slice field via *struct: rhs left
// (AX=ptr, BX=len, CX=cap). CX is
// taken, so stage the struct addr
// in DX. Store all three words at
// foff/+8/+16.
if (isslicetype(c, fi.tnode)) {
emitline("\tMOVQ\t");
emitoff(lc.off: i64);
emitline("(BP), DX\n");
emitline("\tMOVQ\tAX, ");
emitdispreg(fi.foff: i64, "DX");
emitline("\n");
emitline("\tMOVQ\tBX, ");
emitdispreg((fi.foff + 8): i64, "DX");
emitline("\n");
emitline("\tMOVQ\tCX, ");
emitdispreg((fi.foff + 16): i64, "DX");
emitline("\n");
return;
};
// f64/f32 plain `=` via *struct: cgexpr left the
// value in X0. Reload struct ptr and MOVSD/MOVSS.
if (isfloattype(c, fi.tnode)) {
@@ -3669,6 +3689,23 @@ fn cgassign(c: *cgen, n: *node) void = {
emitline("(BP)\n");
return;
};
// slice field direct: cgexpr left
// (AX=ptr, BX=len, CX=cap); store all
// three at +0/+8/+16. The generic
// fldstoreop below would only write AX,
// dropping .len/.cap.
if (isslicetype(c, fi.tnode)) {
emitline("\tMOVQ\tAX, ");
emitoff((lc.off + fi.foff): i64);
emitline("(BP)\n");
emitline("\tMOVQ\tBX, ");
emitoff((lc.off + fi.foff + 8): i64);
emitline("(BP)\n");
emitline("\tMOVQ\tCX, ");
emitoff((lc.off + fi.foff + 16): i64);
emitline("(BP)\n");
return;
};
// f64/f32 direct struct local store: route via X0.
if (isfloattype(c, fi.tnode)) {
let mov: str = "MOVSD";

View File

@@ -11661,6 +11661,26 @@ fn cgassign(c: *cgen, n: *node) void = {
emitline("\n");
return;
};
// slice field via *struct: rhs left
// (AX=ptr, BX=len, CX=cap). CX is
// taken, so stage the struct addr
// in DX. Store all three words at
// foff/+8/+16.
if (isslicetype(c, fi.tnode)) {
emitline("\tMOVQ\t");
emitoff(lc.off: i64);
emitline("(BP), DX\n");
emitline("\tMOVQ\tAX, ");
emitdispreg(fi.foff: i64, "DX");
emitline("\n");
emitline("\tMOVQ\tBX, ");
emitdispreg((fi.foff + 8): i64, "DX");
emitline("\n");
emitline("\tMOVQ\tCX, ");
emitdispreg((fi.foff + 16): i64, "DX");
emitline("\n");
return;
};
// f64/f32 plain `=` via *struct: cgexpr left the
// value in X0. Reload struct ptr and MOVSD/MOVSS.
if (isfloattype(c, fi.tnode)) {
@@ -11717,6 +11737,23 @@ fn cgassign(c: *cgen, n: *node) void = {
emitline("(BP)\n");
return;
};
// slice field direct: cgexpr left
// (AX=ptr, BX=len, CX=cap); store all
// three at +0/+8/+16. The generic
// fldstoreop below would only write AX,
// dropping .len/.cap.
if (isslicetype(c, fi.tnode)) {
emitline("\tMOVQ\tAX, ");
emitoff((lc.off + fi.foff): i64);
emitline("(BP)\n");
emitline("\tMOVQ\tBX, ");
emitoff((lc.off + fi.foff + 8): i64);
emitline("(BP)\n");
emitline("\tMOVQ\tCX, ");
emitoff((lc.off + fi.foff + 16): i64);
emitline("(BP)\n");
return;
};
// f64/f32 direct struct local store: route via X0.
if (isfloattype(c, fi.tnode)) {
let mov: str = "MOVSD";