wcc: store to a global tagged-array element resolves the (SB) base (#16)
The indexed tagged-element assign arm computed its base without the isglobal -> LEAQ name(SB) branch the scalar element arm already has, so `gs[i] = v` on a global tagged array stored to a junk frame base and was lost -- cstage rc=0 where wwstage (which has the branch) rc=42. Mirror the scalar arm's base resolution; cstage aligns up to wwstage. Local tagged arrays and scalar globals are unchanged. The global tagged-array static initializer still mis-packs its DATA in both stages -- a separate emitter path, filed as #19.
This commit is contained in:
@@ -6499,14 +6499,27 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
ins2(c, A_MOVQ, aimm(ssz), areg(D_CX));
|
||||
ins2(c, A_IMULQ, areg(D_CX), areg(D_AX));
|
||||
}
|
||||
if (base->kind == N_IDENT && is_arr) {
|
||||
if (base->kind == N_IDENT) {
|
||||
int boff = localfind(locals, base->str);
|
||||
ins2(c, A_LEAQ, amem(D_BP, boff),
|
||||
areg(D_BX));
|
||||
} else if (base->kind == N_IDENT) {
|
||||
int boff = localfind(locals, base->str);
|
||||
ins2(c, A_MOVQ, amem(D_BP, boff),
|
||||
areg(D_BX));
|
||||
int isglobal = (boff == 0) &&
|
||||
let_islet(base->str);
|
||||
if (isglobal && is_arr) {
|
||||
ins2(c, A_LEAQ,
|
||||
masym(c, base->str),
|
||||
areg(D_BX));
|
||||
} else if (isglobal) {
|
||||
ins2(c, A_MOVQ,
|
||||
masym(c, base->str),
|
||||
areg(D_BX));
|
||||
} else if (is_arr) {
|
||||
ins2(c, A_LEAQ,
|
||||
amem(D_BP, boff),
|
||||
areg(D_BX));
|
||||
} else {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_BP, boff),
|
||||
areg(D_BX));
|
||||
}
|
||||
} else if (cg_dotbase_addr(c, base, D_BX, locals)) {
|
||||
/* #259: N_DOT base resolved inline to the
|
||||
* field address; cgexpr fallback would
|
||||
|
||||
Reference in New Issue
Block a user