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:
@@ -4206,6 +4206,24 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
emitline("\tMOVQ\tCX, 16(BX)\n");
|
||||
return;
|
||||
};
|
||||
// float element → store FROM X0 (MOVSS/MOVSD): cgexpr
|
||||
// left the value in X0. 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. Deferred to #125.
|
||||
// For f32 the #104 CVTSD2SS narrowing only touches X0,
|
||||
// so the AX store below would write raw double low-
|
||||
// bits, garbage for f32 (#122, mirrors cstage cgen.c
|
||||
// arr[i]= float store).
|
||||
if (isfloattype(c, elemtn)) {
|
||||
let fmov: str = "MOVSD";
|
||||
if (isf32type(c, elemtn)) { fmov = "MOVSS"; };
|
||||
emitline("\t");
|
||||
emitline(fmov);
|
||||
emitline("\tX0, (BX)\n");
|
||||
return;
|
||||
};
|
||||
let isop: str = tnodestoreop(c, elemtn, esz);
|
||||
emitline("\t");
|
||||
emitline(isop);
|
||||
|
||||
Reference in New Issue
Block a user