cgen: str tuple-positional element read -> 3-word -- Phase 2 C4.6 S3 (both stages)
Reading a str-typed tuple element by position (t.N) loaded 2 words (ptr,len), dropping cap -- the C4.6 coda with NO adjacent slice-element arm to mirror. Author the 3-word triple directly to the canonical {ptr,len,cap} ABI (AX,BX,CX off the BP frame slot; add cap->CX at +16). Kind-gated (TY_STR / isstrtype, never size==24). cstage==wwstage byte-identical -- cross-stage identity is the correctness oracle here, since there is no local slice sibling.
test/wcc/935: table-driven runtime .cap-survives over let s = t.1; poison rides the return ABI (R8) into the slot's cap word; a CX-clobbering call ensures a 2-word read cannot coincidentally pass. fail-before/pass-after verified INDEPENDENTLY on both stages.
main.combined.ww regenerated via the canonical make path (md5-stable).
This commit is contained in:
@@ -5834,13 +5834,18 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
? tp->type->under : tp->type;
|
||||
int op = fldloadop(tp->type, fsz);
|
||||
int off = localfind(locals, n->lhs->str);
|
||||
/* str element: load (ptr, len) into (AX, BX) so chains
|
||||
* like `t.1.len` propagate through the str-rhs
|
||||
* convention. Without this we'd MOVQ 8B and the .len
|
||||
* shuffle (BX→AX) would surface garbage. */
|
||||
/* str IS []u8 — load (ptr, len, cap) into
|
||||
* (AX, BX, CX), the canonical slice-header ABI,
|
||||
* so chains like `t.1.len` propagate through the
|
||||
* slice-rhs convention (#1/Phase 3 collapse).
|
||||
* UNLIKE the field arms there is no slice-element
|
||||
* sibling here, so the triple is hand-authored;
|
||||
* base is BP (frame, not a target reg) so the
|
||||
* canonical ptr/len/cap order has no clobber risk. */
|
||||
if (fu && fu->kind == TY_STR) {
|
||||
ins2(c, A_MOVQ, amem(D_BP, off + foff + 0), areg(D_AX));
|
||||
ins2(c, A_MOVQ, amem(D_BP, off + foff + 8), areg(D_BX));
|
||||
ins2(c, A_MOVQ, amem(D_BP, off + foff + 16), areg(D_CX));
|
||||
break;
|
||||
}
|
||||
ins2(c, op, amem(D_BP, off + foff), areg(D_AX));
|
||||
|
||||
Reference in New Issue
Block a user