selfhost/cmd/wcc: route cgalloc field-store foff through emitdispreg

Four ad-hoc emit sites in cgalloc's N_STRUCTLIT field-store loop
(cgenexpr.ww:2770-2802) wrote the displacement via
emitint(foff: i64); emitline("(REG)\n"), producing 0(REG) for
foff=0. cstage's txt.c:130-134 omits the zero displacement, so
ww2.s (cstage compiling wwstage) and ww3.s (wwstage compiling
wwstage) would diverge the moment any selfhost site migrates to
alloc(T{...})!. Dormant today only because selfhost source has
no alloc(T{...})! yet.

Route the four sites through emitdispreg (cgen.ww:786), the
existing SSoT that already omits zero displacement.

Extends test/wcc/758_cgalloc_str_field.c with 4 table-driven
asm_disp_rows pinning the displacement text for {str/int/f64
at offset 0, str at offset 8}. Internal subtest count: 16 → 20.
The 3 foff=0 rows fail without the fix.
This commit is contained in:
2026-05-20 17:41:41 +09:00
parent 4c51bce244
commit d617a698b0
4 changed files with 144 additions and 24 deletions

View File

@@ -15983,8 +15983,8 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\t");
emitline(mov);
emitline("\tX0, ");
emitint(fi.foff: i64);
emitline("(BX)\n");
emitdispreg(fi.foff: i64, "BX");
emitline("\n");
fi = nil;
} else { if (isstrtype(c, fi.tnode)) {
// alloc(T{ fval = s }) for str field: cgexpr
@@ -15993,11 +15993,11 @@ fn cgalloc(c: *cgen, n: *node) void = {
// cmd/w6c/cgen.c:4184-4190.
emitline("\tMOVQ\t(SP), CX\n");
emitline("\tMOVQ\tAX, ");
emitint(fi.foff: i64);
emitline("(CX)\n");
emitdispreg(fi.foff: i64, "CX");
emitline("\n");
emitline("\tMOVQ\tBX, ");
emitint((fi.foff + 8): i64);
emitline("(CX)\n");
emitdispreg((fi.foff + 8): i64, "CX");
emitline("\n");
fi = nil;
} else {
emitline("\tMOVQ\t(SP), BX\n");
@@ -16005,8 +16005,8 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\t");
emitline(sop);
emitline("\tAX, ");
emitint(fi.foff: i64);
emitline("(BX)\n");
emitdispreg(fi.foff: i64, "BX");
emitline("\n");
fi = nil;
};};
} else {

View File

@@ -2774,8 +2774,8 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\t");
emitline(mov);
emitline("\tX0, ");
emitint(fi.foff: i64);
emitline("(BX)\n");
emitdispreg(fi.foff: i64, "BX");
emitline("\n");
fi = nil;
} else { if (isstrtype(c, fi.tnode)) {
// alloc(T{ fval = s }) for str field: cgexpr
@@ -2784,11 +2784,11 @@ fn cgalloc(c: *cgen, n: *node) void = {
// cmd/w6c/cgen.c:4184-4190.
emitline("\tMOVQ\t(SP), CX\n");
emitline("\tMOVQ\tAX, ");
emitint(fi.foff: i64);
emitline("(CX)\n");
emitdispreg(fi.foff: i64, "CX");
emitline("\n");
emitline("\tMOVQ\tBX, ");
emitint((fi.foff + 8): i64);
emitline("(CX)\n");
emitdispreg((fi.foff + 8): i64, "CX");
emitline("\n");
fi = nil;
} else {
emitline("\tMOVQ\t(SP), BX\n");
@@ -2796,8 +2796,8 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\t");
emitline(sop);
emitline("\tAX, ");
emitint(fi.foff: i64);
emitline("(BX)\n");
emitdispreg(fi.foff: i64, "BX");
emitline("\n");
fi = nil;
};};
} else {

View File

@@ -15983,8 +15983,8 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\t");
emitline(mov);
emitline("\tX0, ");
emitint(fi.foff: i64);
emitline("(BX)\n");
emitdispreg(fi.foff: i64, "BX");
emitline("\n");
fi = nil;
} else { if (isstrtype(c, fi.tnode)) {
// alloc(T{ fval = s }) for str field: cgexpr
@@ -15993,11 +15993,11 @@ fn cgalloc(c: *cgen, n: *node) void = {
// cmd/w6c/cgen.c:4184-4190.
emitline("\tMOVQ\t(SP), CX\n");
emitline("\tMOVQ\tAX, ");
emitint(fi.foff: i64);
emitline("(CX)\n");
emitdispreg(fi.foff: i64, "CX");
emitline("\n");
emitline("\tMOVQ\tBX, ");
emitint((fi.foff + 8): i64);
emitline("(CX)\n");
emitdispreg((fi.foff + 8): i64, "CX");
emitline("\n");
fi = nil;
} else {
emitline("\tMOVQ\t(SP), BX\n");
@@ -16005,8 +16005,8 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\t");
emitline(sop);
emitline("\tAX, ");
emitint(fi.foff: i64);
emitline("(BX)\n");
emitdispreg(fi.foff: i64, "BX");
emitline("\n");
fi = nil;
};};
} else {