wcc: f32 array-element store from X0 (#122)
Float array-element stores (array-literal init, [v...] repeat-fill, and arr[i]=v) now route from X0 via MOVSS/MOVSD in both stages; the AX path stored the raw double low-bits, garbage for f32 (f64 worked by accident). A clobbering call-index (a[geti()]=v) loses the X0 value — deferred to #125.
This commit is contained in:
@@ -3815,6 +3815,22 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
ins2(c, A_MOVQ, areg(D_CX), amem(D_BX, 16));
|
||||
break;
|
||||
}
|
||||
/* float element → store FROM X0 (MOVSS/MOVSD): cgexpr
|
||||
* leaves a float value in X0, and for f32 the #104
|
||||
* CVTSD2SS narrowing only touches X0 — the AX path
|
||||
* below would store the raw double low-bits (garbage
|
||||
* for f32). Float-ness from esub, mirroring the read
|
||||
* side at cgen.c:6423 (#122). X0 survives the index/
|
||||
* base eval only for literal/local-var indices; a
|
||||
* call-index (`a[geti()]=v`) clobbers X0 and loses the
|
||||
* value — this path does not spill X0 across the eval,
|
||||
* unlike the *p=v float deref store above. Deferred to
|
||||
* #125. */
|
||||
if (type_isfloat(esub)) {
|
||||
int mov = type_isf32(esub) ? A_MOVSS : A_MOVSD;
|
||||
ins2(c, mov, areg(D_X0), amem(D_BX, 0));
|
||||
break;
|
||||
}
|
||||
int store_op = fldstoreop(esub, esz);
|
||||
ins2(c, store_op, areg(D_AX), amem(D_BX, 0));
|
||||
break;
|
||||
@@ -6867,6 +6883,11 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
Type *esub = lu->sub;
|
||||
int esz = esub ? (int)esub->size : 1;
|
||||
int is_str_el = type_isstr(esub);
|
||||
/* float element → store FROM X0; the AX path stores
|
||||
* raw double low-bits, garbage for f32 (#122, twin of
|
||||
* the arr[i]= store fix and the cgen.c:6423 read). */
|
||||
int is_float_el = type_isfloat(esub);
|
||||
int fmov = type_isf32(esub) ? A_MOVSS : A_MOVSD;
|
||||
int op = A_MOVQ;
|
||||
if (!is_str_el) {
|
||||
if (esz == 1) op = A_MOVB;
|
||||
@@ -6893,6 +6914,9 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
amem(D_BP, base));
|
||||
ins2(c, A_MOVQ, areg(D_BX),
|
||||
amem(D_BP, base + 8));
|
||||
} else if (is_float_el) {
|
||||
ins2(c, fmov, areg(D_X0),
|
||||
amem(D_BP, base));
|
||||
} else {
|
||||
ins2(c, op, areg(D_AX),
|
||||
amem(D_BP, base));
|
||||
@@ -6910,6 +6934,9 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
amem(D_BP, base));
|
||||
ins2(c, A_MOVQ, areg(D_BX),
|
||||
amem(D_BP, base + 8));
|
||||
} else if (is_float_el) {
|
||||
ins2(c, fmov, areg(D_X0),
|
||||
amem(D_BP, base));
|
||||
} else {
|
||||
ins2(c, op, areg(D_AX),
|
||||
amem(D_BP, base));
|
||||
|
||||
Reference in New Issue
Block a user