w6c: global *struct base field store loads the pointer from g(SB)
cstage dereferenced 0(BP) for the base — a SEGV on every store through a module-global struct pointer; wwstage was already correct (the inverse-set member). Mirror ww's global-pointer load. New 989_globptrfield_run pins cs==ww both stages. Task #47.
This commit is contained in:
@@ -5368,7 +5368,27 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
}
|
||||
/* now store AX into target */
|
||||
if (via_ptr) {
|
||||
ins2(c, A_MOVQ, amem(D_BP, boff), areg(D_BX));
|
||||
if (boff == 0 && let_islet(base->str)) {
|
||||
/* #47 (inverse): a GLOBAL *struct
|
||||
* base. The pointer VALUE lives at
|
||||
* gp(SB), not a BP slot — load it
|
||||
* from the symbol. Pre-fix MOVQ
|
||||
* (BP),BX derefed saved BP → SEGV.
|
||||
* Mirrors the already-correct wwstage
|
||||
* global-base load; cs==ww. (Other
|
||||
* via_ptr field arms keep the latent
|
||||
* BP-deref — inverse siblings #60/#61,
|
||||
* ken-triage.) */
|
||||
ins1(c, A_PUSHQ, areg(D_AX));
|
||||
ins2(c, A_LEAQ,
|
||||
masym(c, base->str), areg(D_BX));
|
||||
ins2(c, A_MOVQ, amem(D_BX, 0),
|
||||
areg(D_BX));
|
||||
ins1(c, A_POPQ, areg(D_AX));
|
||||
} else {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_BP, boff), areg(D_BX));
|
||||
}
|
||||
ins2(c, store_op, areg(D_AX), amem(D_BX, foff));
|
||||
} else if (is_global) {
|
||||
ins2(c, A_LEAQ, masym(c, base->str), areg(D_BX));
|
||||
|
||||
Reference in New Issue
Block a user