// f64xmm_test — f64 XMM materialise + tuple .0 compare, migrated from // test/wcc/955_f64xmm_run.c (#5-C4, #103). Two GATE-BLIND faces (both stages // emitted byte-identical-but-wrong asm, so byte-id never catches a reintroduction // — the T1 cstage run is the live net): // FACE X — a no-decimal float-typed integer literal (`0f64`, `8f64`) is an // N_INTLIT carrying float TYPE; the integer-immediate path stranded it in // AX, so `n == 0f64` compared a stale X0 and `(8f64 * 10.0): i32` read // garbage. Fixed by routing the float-typed N_INTLIT through the float- // constant-in-X0 emit (+ the wwstage exprfloatkind N_INTLIT arm). // FACE Z — a tuple positional f64 field read (`r.0`, r:(f64,i64)) loaded via // the integer op into AX, so `r.0 == 0.0` was wrongly true. Fixed by a // fld_isfloat branch -> MOVSD/MOVSS into X0. package f64xmm_test; fn g0(n: f64) i32 = { if (n == 0f64) { return 1; }; return 0; }; fn gneg(n: f64) i32 = { if (n == -8f64) { return 1; }; return 0; }; fn norm(n: f64) (f64, i64) = { return (n, 0); }; @test fn x_cmp_false() void = { assert(g0(8.0) == 0); }; @test fn x_cmp_true() void = { assert(g0(0.0) == 1); }; @test fn x_arith() void = { assert((8f64 * 10.0): i32 == 80); }; // `-8f64` is N_UN(TK_MINUS) over a float-typed N_INTLIT — the wwstage // exprfloatkind must recurse through the unary into the N_INTLIT-float arm. @test fn x_neg_cmp_true() void = { assert(gneg(-8.0) == 1); }; @test fn x_neg_cmp_false() void = { assert(gneg(8.0) == 0); }; // FACE Z: r.0 == 0.0 with r = (8.0, 0) must be false (bug: wrongly true). @test fn z_tuple_field() void = { const r = norm(8.0); assert(r.0 != 0.0); }; // CONTROL: the let-bound spelling was already correct and must stay correct. @test fn z_letbound_control() void = { const r = norm(8.0); const m = r.0; assert(m != 0.0); };