wcc: whole-struct field-copy completes the ragged tail greedily, both stages
A `x.f = o` copy of a whole struct field emits a MOVQ run for the
8-byte chunks plus a tail. Both stages inlined a tail that handled only
{4,1}: a 4-byte remainder went MOVL, a 1-byte MOVB, but {2,3,5,6,7} fell
through to an 8-byte MOVQ that OVER-READS the source and OVER-WRITES the
field's natural-offset successor. With #44 packing a successor at its
natural offset, that is a live clobber: outer2{i:inner2{u8,u8}, mark:i32}
copies i with `MOVQ -8(BP),AX; MOVQ AX,-16(BP)` and wipes mark@-12; the
correct move is a single MOVW. Same defect in cstage (cgen.c) and the
four wwstage field-copy sites (cgenexpr.ww: via-ptr, direct-BP-local,
global, and the multi-hop dot-chain CX variant).
Fix: replace each inline {4,1} tail with the descending greedy 4/2/1
(MOVL/MOVW/MOVB) the canonical aggregate-copy emitters already use, so
the tail is complete on every natural size. This is path (alpha) of the
#73 brief — a corpus-neutral, no-workaround completion of the inline
tail. Routing field copies through the shared aggcopy/cg_aggcopy choke-
point (beta) is the balloon: those emitters hardcode (SI)->(BX) at offset
k with zero base displacement, but the four field-copy dsts are
heterogeneous (foff(BX), boff+foff(BP) with no base reg, totaloff(CX)),
so routing forces per-site-per-stage LEAQ src->SI + LEAQ dst->BX rewrites
with no mechanical cross-stage mirror at the CX site = a gate-blind
cs!=ww risk. The emitter extraction is filed as a later addressing-
unification arc (#12). The ragged tail is corpus-absent (every corpus
field copy is tail in {0,4}, where greedy 4/2/1 emits exactly what the
old {4,1} tail did), so this is CLASS-N: zero corpus move on both stages,
byte-id holds by construction.
The cstage <=24 N_CALL receive site (cgen.c:5234) is a different copy
family (sret result read from AX/DX/CX, not a mem-to-mem field copy) and
already handles 4/2/1; left untouched. The str/slice/tagged/tuple 4/1
sites (#76) are likewise a separate family, filed not folded.
989_structcopytail_run pins it on both driver twins: tail2 (MOVW), tail6
(MOVL+MOVW), tail7 (the full MOVL+MOVW+MOVB ladder, the MOVB-path row),
plus an 8-aligned ctl8 (tail-0 control). Pre-fix cstage clobbers mark and
exits non-zero -> cs!=ww; post-fix 4/4 ok cs==ww.
This commit is contained in:
@@ -33325,21 +33325,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -33551,21 +33562,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("(BP)\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -33838,21 +33860,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -34487,29 +34520,50 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
|
||||
@@ -9979,21 +9979,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -10205,21 +10216,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("(BP)\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -10492,21 +10514,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -11141,29 +11174,50 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
|
||||
@@ -33325,21 +33325,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -33551,21 +33562,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("(BP)\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((lc.off + fi.foff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -33838,21 +33860,32 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\n");
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((fi.foff + k): i64, "BX");
|
||||
emitline("\n");
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
@@ -34487,29 +34520,50 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
k += 8;
|
||||
};
|
||||
if (k < ssz) {
|
||||
let tail: i32 = ssz - k;
|
||||
let lop: str = "MOVQ";
|
||||
if (tail == 4) { lop = "MOVL"; }
|
||||
else { if (tail == 1) { lop = "MOVB"; }; };
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\t");
|
||||
if (k + 4 <= ssz) {
|
||||
emitline("\tMOVL\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\t");
|
||||
emitline(lop);
|
||||
emitline("\tAX, ");
|
||||
emitline("\tMOVL\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 4;
|
||||
};
|
||||
if (k + 2 <= ssz) {
|
||||
emitline("\tMOVW\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\tMOVW\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 2;
|
||||
};
|
||||
if (k + 1 <= ssz) {
|
||||
emitline("\tMOVB\t");
|
||||
emitoff((srhs.off + k): i64);
|
||||
emitline("(BP), AX\n");
|
||||
if (viacx) {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitdispreg((totaloff + k): i64, "CX");
|
||||
emitline("\n");
|
||||
} else {
|
||||
emitline("\tMOVB\tAX, ");
|
||||
emitoff((rootoff + totaloff + k): i64);
|
||||
emitline("(BP)\n");
|
||||
};
|
||||
k += 1;
|
||||
};
|
||||
return;
|
||||
};};
|
||||
|
||||
Reference in New Issue
Block a user