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:
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user