cgen: fold str tagged-variant payload store onto slice arm (both stages)

Phase 2 step 4. The str and slice tagged-union payload stores were
byte-identical adjacent arms (3-word ptr/len/cap @ slot+8/+16/+24 +
tag) since #1 made str a 24B {ptr,len,cap}. Delete the dedicated str
arm and widen the slice arm's gate to accept str (cstage type_isstr,
wwstage nodeisstr). One site, both stages. Byte-id-neutral: str now
flows the identical slice arm; full test incl 990-997 green.
This commit is contained in:
2026-05-24 09:00:53 +09:00
parent a5ca21ddba
commit b416e7114e
4 changed files with 21 additions and 96 deletions

View File

@@ -1421,24 +1421,12 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
if (via_outer) goto copy_out;
return;
}
/* str IS []u8: AX=ptr, BX=len, CX=cap from cgexpr. Slot layout
* tag@+0, ptr@+8, len@+16, cap@+24 — same 32B shape as the slice
* payload below (#1/Phase 3). */
if (type_isstr(st) || (su && su->kind == TY_STR)) {
cgexpr(c, src, *locals_p);
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, write_off + 8));
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, write_off + 16));
ins2(c, A_MOVQ, areg(D_CX), amem(D_BP, write_off + 24));
int tag = cg_tag_for_variant(du, st);
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag),
amem(D_BP, write_off + 0));
if (via_outer) goto copy_out;
return;
}
/* Slice payload: cgexpr leaves (AX=ptr, BX=len, CX=cap). The
* slot layout is tag@+0, ptr@+8, len@+16, cap@+24 — requires the
* destination tagged-union slot be at least 32B. */
if (type_isslice(st) || (su && su->kind == TY_SLICE)) {
/* str IS []u8 — same 32B payload as a slice: cgexpr leaves
* (AX=ptr, BX=len, CX=cap); slot layout tag@+0, ptr@+8, len@+16,
* cap@+24, destination slot >= 32B. str folds onto the slice arm
* (#1/Phase 3 collapse). */
if (type_isslice(st) || (su && su->kind == TY_SLICE) ||
type_isstr(st) || (su && su->kind == TY_STR)) {
cgexpr(c, src, *locals_p);
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, write_off + 8));
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, write_off + 16));