cgen: f64 deref-load -> MOVSD/MOVSS into X0 (both stages, #96)
This commit is contained in:
@@ -2284,7 +2284,16 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
/* Handled in the pre-cgexpr early-exit above. */
|
/* Handled in the pre-cgexpr early-exit above. */
|
||||||
break;
|
break;
|
||||||
case TK_STAR: /* deref */
|
case TK_STAR: /* deref */
|
||||||
|
/* f64/f32 result rides X0 (SSE), not AX — an integer
|
||||||
|
* MOVQ strands the value off the float ABI and the
|
||||||
|
* caller's MOVSD X0 reads stale bits (#96). Mirrors the
|
||||||
|
* float field/ident load idiom at 1462/1838. */
|
||||||
|
if (node_isfloat(n)) {
|
||||||
|
ins2(c, node_isf32(n) ? A_MOVSS : A_MOVSD,
|
||||||
|
amem(D_AX, 0), areg(D_X0));
|
||||||
|
} else {
|
||||||
ins2(c, A_MOVQ, amem(D_AX, 0), areg(D_AX));
|
ins2(c, A_MOVQ, amem(D_AX, 0), areg(D_AX));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16759,7 +16759,20 @@ fn cgun(c: *cgen, n: *node) void = {
|
|||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (n.op == tkind.TK_STAR) { emitline("\tMOVQ\t(AX), AX\n"); return; };
|
if (n.op == tkind.TK_STAR) {
|
||||||
|
// f64/f32 result rides X0 (SSE), not AX — an integer MOVQ
|
||||||
|
// strands the value off the float ABI and the caller's
|
||||||
|
// MOVSD X0 reads stale bits (#96). Mirrors the float
|
||||||
|
// field/ident load idiom.
|
||||||
|
if (isfloattype(c, n)) {
|
||||||
|
let mov: str = "MOVSD";
|
||||||
|
if (isf32type(c, n)) { mov = "MOVSS"; };
|
||||||
|
emitline("\t"); emitline(mov); emitline("\t(AX), X0\n");
|
||||||
|
} else {
|
||||||
|
emitline("\tMOVQ\t(AX), AX\n");
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
};
|
||||||
if (n.op == tkind.TK_NOT) {
|
if (n.op == tkind.TK_NOT) {
|
||||||
let t: str = mklabel(c, "tt");
|
let t: str = mklabel(c, "tt");
|
||||||
let e: str = mklabel(c, "te");
|
let e: str = mklabel(c, "te");
|
||||||
|
|||||||
@@ -2736,7 +2736,20 @@ fn cgun(c: *cgen, n: *node) void = {
|
|||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (n.op == tkind.TK_STAR) { emitline("\tMOVQ\t(AX), AX\n"); return; };
|
if (n.op == tkind.TK_STAR) {
|
||||||
|
// f64/f32 result rides X0 (SSE), not AX — an integer MOVQ
|
||||||
|
// strands the value off the float ABI and the caller's
|
||||||
|
// MOVSD X0 reads stale bits (#96). Mirrors the float
|
||||||
|
// field/ident load idiom.
|
||||||
|
if (isfloattype(c, n)) {
|
||||||
|
let mov: str = "MOVSD";
|
||||||
|
if (isf32type(c, n)) { mov = "MOVSS"; };
|
||||||
|
emitline("\t"); emitline(mov); emitline("\t(AX), X0\n");
|
||||||
|
} else {
|
||||||
|
emitline("\tMOVQ\t(AX), AX\n");
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
};
|
||||||
if (n.op == tkind.TK_NOT) {
|
if (n.op == tkind.TK_NOT) {
|
||||||
let t: str = mklabel(c, "tt");
|
let t: str = mklabel(c, "tt");
|
||||||
let e: str = mklabel(c, "te");
|
let e: str = mklabel(c, "te");
|
||||||
|
|||||||
@@ -16759,7 +16759,20 @@ fn cgun(c: *cgen, n: *node) void = {
|
|||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (n.op == tkind.TK_STAR) { emitline("\tMOVQ\t(AX), AX\n"); return; };
|
if (n.op == tkind.TK_STAR) {
|
||||||
|
// f64/f32 result rides X0 (SSE), not AX — an integer MOVQ
|
||||||
|
// strands the value off the float ABI and the caller's
|
||||||
|
// MOVSD X0 reads stale bits (#96). Mirrors the float
|
||||||
|
// field/ident load idiom.
|
||||||
|
if (isfloattype(c, n)) {
|
||||||
|
let mov: str = "MOVSD";
|
||||||
|
if (isf32type(c, n)) { mov = "MOVSS"; };
|
||||||
|
emitline("\t"); emitline(mov); emitline("\t(AX), X0\n");
|
||||||
|
} else {
|
||||||
|
emitline("\tMOVQ\t(AX), AX\n");
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
};
|
||||||
if (n.op == tkind.TK_NOT) {
|
if (n.op == tkind.TK_NOT) {
|
||||||
let t: str = mklabel(c, "tt");
|
let t: str = mklabel(c, "tt");
|
||||||
let e: str = mklabel(c, "te");
|
let e: str = mklabel(c, "te");
|
||||||
|
|||||||
Reference in New Issue
Block a user