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:
@@ -1421,24 +1421,12 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
if (via_outer) goto copy_out;
|
if (via_outer) goto copy_out;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* str IS []u8: AX=ptr, BX=len, CX=cap from cgexpr. Slot layout
|
/* str IS []u8 — same 32B payload as a slice: cgexpr leaves
|
||||||
* tag@+0, ptr@+8, len@+16, cap@+24 — same 32B shape as the slice
|
* (AX=ptr, BX=len, CX=cap); slot layout tag@+0, ptr@+8, len@+16,
|
||||||
* payload below (#1/Phase 3). */
|
* cap@+24, destination slot >= 32B. str folds onto the slice arm
|
||||||
if (type_isstr(st) || (su && su->kind == TY_STR)) {
|
* (#1/Phase 3 collapse). */
|
||||||
cgexpr(c, src, *locals_p);
|
if (type_isslice(st) || (su && su->kind == TY_SLICE) ||
|
||||||
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, write_off + 8));
|
type_isstr(st) || (su && su->kind == TY_STR)) {
|
||||||
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)) {
|
|
||||||
cgexpr(c, src, *locals_p);
|
cgexpr(c, src, *locals_p);
|
||||||
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, write_off + 8));
|
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_BX), amem(D_BP, write_off + 16));
|
||||||
|
|||||||
@@ -13176,32 +13176,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// str IS []u8: AX=ptr, BX=len, CX=cap from cgexpr. Slot layout
|
// str IS []u8 — same 32B payload as a slice: cgexpr leaves
|
||||||
// tag@+0, ptr@+8, len@+16, cap@+24 — same 32B shape as the slice
|
// (AX=ptr, BX=len, CX=cap); slot layout [+0]=tag, [+8]=ptr,
|
||||||
// payload below (#1/Phase 3).
|
// [+16]=len, [+24]=cap. str folds onto the slice arm (#1/Phase 3
|
||||||
if (nodeisstr(c, src)) {
|
// collapse; cite cstage cg_widen_tagged_store).
|
||||||
cgexpr(c, src);
|
if (nodeisslice(c, src) || nodeisstr(c, src)) {
|
||||||
emitline("\tMOVQ\tAX, ");
|
|
||||||
emitoff((slot_off + 8): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
emitline("\tMOVQ\tBX, ");
|
|
||||||
emitoff((slot_off + 16): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
emitline("\tMOVQ\tCX, ");
|
|
||||||
emitoff((slot_off + 24): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
let tag: i32 = taggedvariantindext(c, dt, src);
|
|
||||||
if (tag < 0) { tag = 0; };
|
|
||||||
emitline("\tMOVQ\t$");
|
|
||||||
emitint(tag: i64);
|
|
||||||
emitline(", ");
|
|
||||||
emitoff(slot_off: i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
// Slice payload (24B): cgexpr leaves (AX=ptr, BX=len, CX=cap).
|
|
||||||
// Slot layout: [+0]=tag, [+8]=ptr, [+16]=len, [+24]=cap.
|
|
||||||
if (nodeisslice(c, src)) {
|
|
||||||
cgexpr(c, src);
|
cgexpr(c, src);
|
||||||
emitline("\tMOVQ\tAX, ");
|
emitline("\tMOVQ\tAX, ");
|
||||||
emitoff((slot_off + 8): i64);
|
emitoff((slot_off + 8): i64);
|
||||||
|
|||||||
@@ -2616,32 +2616,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// str IS []u8: AX=ptr, BX=len, CX=cap from cgexpr. Slot layout
|
// str IS []u8 — same 32B payload as a slice: cgexpr leaves
|
||||||
// tag@+0, ptr@+8, len@+16, cap@+24 — same 32B shape as the slice
|
// (AX=ptr, BX=len, CX=cap); slot layout [+0]=tag, [+8]=ptr,
|
||||||
// payload below (#1/Phase 3).
|
// [+16]=len, [+24]=cap. str folds onto the slice arm (#1/Phase 3
|
||||||
if (nodeisstr(c, src)) {
|
// collapse; cite cstage cg_widen_tagged_store).
|
||||||
cgexpr(c, src);
|
if (nodeisslice(c, src) || nodeisstr(c, src)) {
|
||||||
emitline("\tMOVQ\tAX, ");
|
|
||||||
emitoff((slot_off + 8): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
emitline("\tMOVQ\tBX, ");
|
|
||||||
emitoff((slot_off + 16): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
emitline("\tMOVQ\tCX, ");
|
|
||||||
emitoff((slot_off + 24): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
let tag: i32 = taggedvariantindext(c, dt, src);
|
|
||||||
if (tag < 0) { tag = 0; };
|
|
||||||
emitline("\tMOVQ\t$");
|
|
||||||
emitint(tag: i64);
|
|
||||||
emitline(", ");
|
|
||||||
emitoff(slot_off: i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
// Slice payload (24B): cgexpr leaves (AX=ptr, BX=len, CX=cap).
|
|
||||||
// Slot layout: [+0]=tag, [+8]=ptr, [+16]=len, [+24]=cap.
|
|
||||||
if (nodeisslice(c, src)) {
|
|
||||||
cgexpr(c, src);
|
cgexpr(c, src);
|
||||||
emitline("\tMOVQ\tAX, ");
|
emitline("\tMOVQ\tAX, ");
|
||||||
emitoff((slot_off + 8): i64);
|
emitoff((slot_off + 8): i64);
|
||||||
|
|||||||
@@ -13176,32 +13176,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// str IS []u8: AX=ptr, BX=len, CX=cap from cgexpr. Slot layout
|
// str IS []u8 — same 32B payload as a slice: cgexpr leaves
|
||||||
// tag@+0, ptr@+8, len@+16, cap@+24 — same 32B shape as the slice
|
// (AX=ptr, BX=len, CX=cap); slot layout [+0]=tag, [+8]=ptr,
|
||||||
// payload below (#1/Phase 3).
|
// [+16]=len, [+24]=cap. str folds onto the slice arm (#1/Phase 3
|
||||||
if (nodeisstr(c, src)) {
|
// collapse; cite cstage cg_widen_tagged_store).
|
||||||
cgexpr(c, src);
|
if (nodeisslice(c, src) || nodeisstr(c, src)) {
|
||||||
emitline("\tMOVQ\tAX, ");
|
|
||||||
emitoff((slot_off + 8): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
emitline("\tMOVQ\tBX, ");
|
|
||||||
emitoff((slot_off + 16): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
emitline("\tMOVQ\tCX, ");
|
|
||||||
emitoff((slot_off + 24): i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
let tag: i32 = taggedvariantindext(c, dt, src);
|
|
||||||
if (tag < 0) { tag = 0; };
|
|
||||||
emitline("\tMOVQ\t$");
|
|
||||||
emitint(tag: i64);
|
|
||||||
emitline(", ");
|
|
||||||
emitoff(slot_off: i64);
|
|
||||||
emitline("(BP)\n");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
// Slice payload (24B): cgexpr leaves (AX=ptr, BX=len, CX=cap).
|
|
||||||
// Slot layout: [+0]=tag, [+8]=ptr, [+16]=len, [+24]=cap.
|
|
||||||
if (nodeisslice(c, src)) {
|
|
||||||
cgexpr(c, src);
|
cgexpr(c, src);
|
||||||
emitline("\tMOVQ\tAX, ");
|
emitline("\tMOVQ\tAX, ");
|
||||||
emitoff((slot_off + 8): i64);
|
emitoff((slot_off + 8): i64);
|
||||||
|
|||||||
Reference in New Issue
Block a user