// Float arr[i]= with X0-clobbering index, migrated // from test/wcc/916_arr_float_call_index_run.c (#5-C4, #125). In the `arr[i] = v` // ASSIGN path, when the element type is float and the INDEX sub-expression // clobbers X0 (e.g. a fn-call index), the value was LOST pre-fix: both stages // PUSHed AX (junk for floats), never spilled X0 across the idx/base eval, then // re-emitted MOVSS/MOVSD X0,(BX) using the already-clobbered X0. The fix spills // X0 around the idx/base eval for float elements (SUBQ/MOVSD ...(SP)). Broken // byte-identically between stages (pre-existing, exposed by #122) — T1 run + T2 // byte-id. The non-call-index rows are regression guards (lit/localvar/arith // indices don't clobber X0; worked pre-fix). package arr_float_call_index_test; fn geti(x: f64) i32 = { let y: f64 = x + 1.0; return (y: i32); }; // int-arg call: avoids a pre-call f32-arg-push MOVSD-vs-MOVSS sibling divergence; // the body's f64 arith still clobbers X0. fn getj(seed: i32) i32 = { let y: f64 = (seed: f64) + 1.0; return (y: i32); }; @test fn f64_call_index() void = { let a: [4]f64 = [99.0, 99.0, 99.0, 99.0]; a[geti(1.0)] = 1.5f64; assert((a[2]: i32) == 1); }; @test fn f32_call_index() void = { let a: [4]f32 = [99.0f32, 99.0f32, 99.0f32, 99.0f32]; a[getj(1)] = 1.5f32; assert((a[2]: i32) == 1); }; @test fn f64_lit_index() void = { let a: [4]f64 = [99.0, 99.0, 99.0, 99.0]; a[2] = 1.5f64; assert((a[2]: i32) == 1); }; @test fn f64_localvar_index() void = { let a: [4]f64 = [99.0, 99.0, 99.0, 99.0]; let k: i32 = 2; a[k] = 1.5f64; assert((a[2]: i32) == 1); }; @test fn f64_arith_index() void = { let a: [4]f64 = [99.0, 99.0, 99.0, 99.0]; let k: i32 = 1; a[k + 1] = 1.5f64; assert((a[2]: i32) == 1); };