w6c: 'as' on a module-global tagged ident loads the full box
cstage's N_TYPEASSERT assumed cgexpr filled the registers and spilled an uninitialized payload (cs=0 for any stored value); mirror the landed wwstage emission (tag/payload/cap from g(SB)). Flips the residual row to cs==ww==correct. Task #46.
This commit is contained in:
@@ -10716,7 +10716,22 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (sl_off == 0) {
|
||||
sl_off = localoff(c, &locals, "@asrt_spill",
|
||||
slot_size, cg_frame);
|
||||
if (cg_tagged_memread(s)) {
|
||||
if (s && s->kind == N_IDENT && let_islet(s->str)) {
|
||||
/* #46 (#263): a module-global tagged ident —
|
||||
* cgexpr loads only the tag word (MOVQ g(SB),AX),
|
||||
* so the DX/CX spill below would write
|
||||
* uninitialized payload. Copy the whole box from
|
||||
* g(SB)+0/+8[/+16] into the spill so the
|
||||
* tag-check + payload load index off memory like
|
||||
* a local. ww half landed F8-c3. */
|
||||
ins2(c, A_LEAQ, masym(c, s->str), areg(D_AX));
|
||||
for (int k = 0; k < slot_size; k += 8) {
|
||||
ins2(c, A_MOVQ, amem(D_AX, k),
|
||||
areg(D_DX));
|
||||
ins2(c, A_MOVQ, areg(D_DX),
|
||||
amem(D_BP, sl_off + k));
|
||||
}
|
||||
} else if (cg_tagged_memread(s)) {
|
||||
/* #37: >32B box read — ADDRESS in AX; copy
|
||||
* the whole box from memory. */
|
||||
cgexpr(c, s, locals);
|
||||
|
||||
Reference in New Issue
Block a user