fold-2 chunk C4 (drew's Fam8-13 plan): 13 float value-row C drivers re-homed. 11 migrate to test/lang/*_test.ww @test row-tables (exact IEEE-bit asserts); 1 float-overflow reject row -> a runww //ww:error carrier. 956_tuprecv_f64 slims to a w6c_ww asserttyped pin (20 value rows -> @test; the stamp dimension can't be a value/byte-id @test) -- mutation-proven non-vacuous (break #121 stamp -> RED 6/6 -> restore -> GREEN) + an in-test vacuity self-check. 946_structparam/structret stay whole: their SSE register-class .s-grep (SysV ABI conformance, #165/#171a) is the genuine defect-guard, not @test-expressible. Float was the predicted SSE-cursor byte-id hotspot -- zero fresh cs!=ww surfaced; 951_f64cgen (cstage-only before) byte-ids clean. LANGBYTEID floor 82->93; test count 384->374 (10 deleted drivers; 956 + the 2 946 kept).
57 lines
1.7 KiB
Plaintext
57 lines
1.7 KiB
Plaintext
// f32arg_test — f32 function-argument spill width, migrated from
|
|
// test/wcc/907_f32arg_run.c (#5-C4, #143). Passing an f32 as a function argument
|
|
// must spill through the stack at f32 width (MOVSS, 4-byte), not MOVSD (8-byte).
|
|
// cstage lowered the arg-push/pop with a hardcoded MOVSD; wwstage already split
|
|
// f32/f64 via exprfloatkind. The bug was a pure cs!=ww byte-id break (the callee
|
|
// reads its f32 param via MOVSS regardless), so T2 byte-id is the primary net;
|
|
// the T1 cstage run also asserts the end-to-end XMM round-trip value.
|
|
|
|
package f32arg_test;
|
|
|
|
fn takef32(x: f32) f32 = { return x; };
|
|
|
|
fn id(x: f32) f32 = { return x; };
|
|
|
|
fn add3(a: f32, b: f32, c: f32) f32 = { return a + b + c; };
|
|
|
|
fn mix(a: f32, b: f64, c: f32) f64 = { return a: f64 + b + c: f64; };
|
|
|
|
fn ten(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32, h: f32, i: f32, j: f32) f32 = {
|
|
return a + b + c + d + e + f + g + h + i + j;
|
|
};
|
|
|
|
@test fn single_var() void = {
|
|
let a: f32 = 2.5f32;
|
|
let r: f32 = takef32(a);
|
|
assert(r: i32 == 2);
|
|
};
|
|
|
|
@test fn literal_arg() void = {
|
|
let r: f32 = id(3.0f32);
|
|
assert(r: i32 == 3);
|
|
};
|
|
|
|
@test fn multi_f32() void = {
|
|
let x: f32 = 1.5f32;
|
|
let y: f32 = 2.5f32;
|
|
let z: f32 = 4.0f32;
|
|
let r: f32 = add3(x, y, z);
|
|
assert(r: i32 == 8);
|
|
};
|
|
|
|
// f32 + f64 MIX: the f64 arg stays MOVSD, the f32 args MOVSS, per-arg agree.
|
|
@test fn mixed_f32_f64() void = {
|
|
let p: f32 = 1.5f32;
|
|
let q: f64 = 10.0;
|
|
let s: f32 = 0.5f32;
|
|
let r: f64 = mix(p, q, s);
|
|
assert(r: i32 == 12);
|
|
};
|
|
|
|
// STACK-passed f32: 8 ride X0..X7, args 9+10 stay on the stack (fpidx >= 8).
|
|
@test fn stack_passed() void = {
|
|
let v: f32 = 1.0f32;
|
|
let r: f32 = ten(v, v, v, v, v, v, v, v, v, v);
|
|
assert(r: i32 == 10);
|
|
};
|