Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 2c1ec98

Browse files
committed
test several outputs
1 parent 9f0bc49 commit 2c1ec98

File tree

3 files changed

+125
-53
lines changed

3 files changed

+125
-53
lines changed

build.rs

Lines changed: 121 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,38 +27,30 @@ mod musl_reference_tests {
2727
// These files are all internal functions or otherwise miscellaneous, not
2828
// defining a function we want to test.
2929
const IGNORED_FILES: &[&str] = &[
30-
"expo2.rs",
30+
"expo2.rs", // kernel, private
3131
"fenv.rs",
32-
"k_cos.rs",
33-
"k_cosf.rs",
34-
"k_expo2.rs",
35-
"k_expo2f.rs",
36-
"k_sin.rs",
37-
"k_sinf.rs",
38-
"k_tan.rs",
39-
"k_tanf.rs",
32+
"k_cos.rs", // kernel, private
33+
"k_cosf.rs", // kernel, private
34+
"k_expo2.rs", // kernel, private
35+
"k_expo2f.rs", // kernel, private
36+
"k_sin.rs", // kernel, private
37+
"k_sinf.rs", // kernel, private
38+
"k_tan.rs", // kernel, private
39+
"k_tanf.rs", // kernel, private
4040
"mod.rs",
41-
"rem_pio2.rs",
42-
"rem_pio2_large.rs",
43-
"rem_pio2f.rs",
44-
"remquo.rs", // more than 1 result
45-
"remquof.rs", // more than 1 result
46-
"lgamma_r.rs", // more than 1 result
47-
"lgammaf_r.rs", // more than 1 result
48-
"frexp.rs", // more than 1 result
49-
"frexpf.rs", // more than 1 result
50-
"sincos.rs", // more than 1 result
51-
"sincosf.rs", // more than 1 result
52-
"modf.rs", // more than 1 result
53-
"modff.rs", // more than 1 result
54-
"jn.rs", // passed, but very slow
55-
"jnf.rs", // passed, but very slow
41+
"rem_pio2.rs", // kernel, private
42+
"rem_pio2_large.rs", // kernel, private
43+
"rem_pio2f.rs", // kernel, private
44+
"sincos.rs", // more than 1 result
45+
"sincosf.rs", // more than 1 result
46+
"jn.rs", // passed, but very slow
47+
"jnf.rs", // passed, but very slow
5648
];
5749

5850
struct Function {
5951
name: String,
6052
args: Vec<Ty>,
61-
ret: Ty,
53+
ret: Vec<Ty>,
6254
tests: Vec<Test>,
6355
}
6456

@@ -71,7 +63,7 @@ mod musl_reference_tests {
7163

7264
struct Test {
7365
inputs: Vec<i64>,
74-
output: i64,
66+
outputs: Vec<i64>,
7567
}
7668

7769
pub fn generate() {
@@ -103,7 +95,7 @@ mod musl_reference_tests {
10395
// After we have all our inputs, use the x86_64-unknown-linux-musl
10496
// target to generate the expected output.
10597
generate_test_outputs(&mut math);
106-
98+
//panic!("Boo");
10799
// ... and now that we have both inputs and expected outputs, do a bunch
108100
// of codegen to create the unit tests which we'll actually execute.
109101
generate_unit_tests(&math);
@@ -125,7 +117,7 @@ mod musl_reference_tests {
125117
.collect::<Vec<_>>();
126118
let tail = &s[end + 1..];
127119
let tail = eat(tail, " -> ");
128-
let ret = parse_ty(tail.trim().split(' ').next().unwrap());
120+
let ret = parse_retty(tail.replace("{", "").trim());
129121

130122
return Function {
131123
name: name.to_string(),
@@ -144,6 +136,16 @@ mod musl_reference_tests {
144136
}
145137
}
146138

139+
fn parse_retty(s: &str) -> Vec<Ty> {
140+
match s {
141+
"(f32, f32)" => vec![Ty::F32, Ty::F32],
142+
"(f32, i32)" => vec![Ty::F32, Ty::I32],
143+
"(f64, f64)" => vec![Ty::F64, Ty::F64],
144+
"(f64, i32)" => vec![Ty::F64, Ty::I32],
145+
other => vec![parse_ty(other)],
146+
}
147+
}
148+
147149
fn eat<'a>(s: &'a str, prefix: &str) -> &'a str {
148150
if s.starts_with(prefix) {
149151
&s[prefix.len()..]
@@ -163,7 +165,10 @@ mod musl_reference_tests {
163165
fn generate_test<R: Rng>(args: &[Ty], rng: &mut R) -> Test {
164166
let inputs = args.iter().map(|ty| ty.gen_i64(rng)).collect();
165167
// zero output for now since we'll generate it later
166-
Test { inputs, output: 0 }
168+
Test {
169+
inputs,
170+
outputs: vec![],
171+
}
167172
}
168173
}
169174

@@ -192,6 +197,33 @@ mod musl_reference_tests {
192197
Ty::Bool => "i32",
193198
}
194199
}
200+
201+
fn libc_pty(&self) -> &'static str {
202+
match self {
203+
Ty::F32 => "*mut f32",
204+
Ty::F64 => "*mut f64",
205+
Ty::I32 => "*mut i32",
206+
Ty::Bool => "*mut i32",
207+
}
208+
}
209+
210+
fn default(&self) -> &'static str {
211+
match self {
212+
Ty::F32 => "0_f32",
213+
Ty::F64 => "0_f64",
214+
Ty::I32 => "0_i32",
215+
Ty::Bool => "false",
216+
}
217+
}
218+
219+
fn to_i64(&self) -> &'static str {
220+
match self {
221+
Ty::F32 => ".to_bits() as i64",
222+
Ty::F64 => ".to_bits() as i64",
223+
Ty::I32 => " as i64",
224+
Ty::Bool => " as i64",
225+
}
226+
}
195227
}
196228

197229
fn generate_test_outputs(functions: &mut [Function]) {
@@ -212,8 +244,11 @@ mod musl_reference_tests {
212244
for (i, arg) in function.args.iter().enumerate() {
213245
src.push_str(&format!("arg{}: {},", i, arg.libc_ty()));
214246
}
247+
for (i, ret) in function.ret.iter().skip(1).enumerate() {
248+
src.push_str(&format!("argret{}: {},", i, ret.libc_pty()));
249+
}
215250
src.push_str(") -> ");
216-
src.push_str(function.ret.libc_ty());
251+
src.push_str(function.ret[0].libc_ty());
217252
src.push_str("; }");
218253

219254
src.push_str(&format!("static TESTS: &[[i64; {}]]", function.args.len()));
@@ -229,6 +264,14 @@ mod musl_reference_tests {
229264
src.push_str("];");
230265

231266
src.push_str("for test in TESTS {");
267+
for (i, arg) in function.ret.iter().skip(1).enumerate() {
268+
src.push_str(&format!("let mut argret{} = {};", i, arg.default()));
269+
src.push_str(&format!(
270+
"let argret_ptr{0} = &mut argret{0} as *mut {1};",
271+
i,
272+
arg.libc_ty()
273+
));
274+
}
232275
src.push_str("let output = ");
233276
src.push_str(&function.name);
234277
src.push_str("(");
@@ -241,17 +284,20 @@ mod musl_reference_tests {
241284
});
242285
src.push_str(",");
243286
}
287+
for (i, _) in function.ret.iter().skip(1).enumerate() {
288+
src.push_str(&format!("argret_ptr{},", i));
289+
}
244290
src.push_str(");");
245-
src.push_str("let output = ");
246-
src.push_str(match function.ret {
247-
Ty::F32 => "output.to_bits() as i64",
248-
Ty::F64 => "output.to_bits() as i64",
249-
Ty::I32 => "output as i64",
250-
Ty::Bool => "output as i64",
251-
});
252-
src.push_str(";");
291+
src.push_str(&format!("let output = output{};", function.ret[0].to_i64()));
253292
src.push_str("result.extend_from_slice(&output.to_le_bytes());");
254293

294+
for (i, ret) in function.ret.iter().skip(1).enumerate() {
295+
src.push_str(&format!("let output{0} = argret{0}{1};", i, ret.to_i64()));
296+
src.push_str(&format!(
297+
"result.extend_from_slice(&output{}.to_le_bytes());",
298+
i
299+
));
300+
}
255301
src.push_str("}");
256302

257303
src.push_str("}");
@@ -288,8 +334,13 @@ mod musl_reference_tests {
288334
i64::from_le_bytes(exact)
289335
});
290336

291-
for test in functions.iter_mut().flat_map(|f| f.tests.iter_mut()) {
292-
test.output = results.next().unwrap();
337+
for f in functions.iter_mut() {
338+
for test in f.tests.iter_mut() {
339+
test.outputs = vec![results.next().unwrap()];
340+
for _ in f.ret.iter().skip(1) {
341+
test.outputs.push(results.next().unwrap());
342+
}
343+
}
293344
}
294345
assert!(results.next().is_none());
295346
}
@@ -306,8 +357,9 @@ mod musl_reference_tests {
306357
src.push_str(&function.name);
307358
src.push_str("_matches_musl() {");
308359
src.push_str(&format!(
309-
"static TESTS: &[([i64; {}], i64)]",
310-
function.args.len()
360+
"static TESTS: &[([i64; {}], [i64; {}])]",
361+
function.args.len(),
362+
function.ret.len(),
311363
));
312364
src.push_str(" = &[");
313365
for test in function.tests.iter() {
@@ -317,7 +369,12 @@ mod musl_reference_tests {
317369
src.push_str(",");
318370
}
319371
src.push_str("],");
320-
src.push_str(&test.output.to_string());
372+
src.push_str("[");
373+
for val in test.outputs.iter() {
374+
src.push_str(&val.to_string());
375+
src.push_str(",");
376+
}
377+
src.push_str("],");
321378
src.push_str("),");
322379
}
323380
src.push_str("];");
@@ -336,12 +393,27 @@ mod musl_reference_tests {
336393
src.push_str(",");
337394
}
338395
src.push_str(");");
339-
src.push_str(match function.ret {
340-
Ty::F32 => "if _eqf(output, f32::from_bits(*expected as u32)).is_ok() { continue }",
341-
Ty::F64 => "if _eq(output, f64::from_bits(*expected as u64)).is_ok() { continue }",
342-
Ty::I32 => "if output as i64 == *expected { continue }",
343-
Ty::Bool => unreachable!(),
344-
});
396+
if function.ret.len() > 1 {
397+
for (i, ret) in function.ret.iter().enumerate() {
398+
src.push_str(&(match ret {
399+
Ty::F32 => format!("if _eqf(output.{0}, f32::from_bits(expected[{0}] as u32)).is_ok() {{ continue }}", i),
400+
Ty::F64 => format!("if _eq(output.{0}, f64::from_bits(expected[{0}] as u64)).is_ok() {{ continue }}", i),
401+
Ty::I32 => format!("if output.{0} as i64 == expected[{0}] {{ continue }}", i),
402+
Ty::Bool => unreachable!(),
403+
}));
404+
}
405+
} else {
406+
src.push_str(match function.ret[0] {
407+
Ty::F32 => {
408+
"if _eqf(output, f32::from_bits(expected[0] as u32)).is_ok() { continue }"
409+
}
410+
Ty::F64 => {
411+
"if _eq(output, f64::from_bits(expected[0] as u64)).is_ok() { continue }"
412+
}
413+
Ty::I32 => "if output as i64 == expected[0] { continue }",
414+
Ty::Bool => unreachable!(),
415+
});
416+
}
345417

346418
src.push_str(
347419
r#"

src/math/remquo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub fn remquo(mut x: f64, mut y: f64) -> (f64, i32) {
4848
}
4949
/* x mod y */
5050
while ex > ey {
51-
i = uxi - uy;
51+
i = uxi.wrapping_sub(uy);
5252
if (i >> 63) == 0 {
5353
uxi = i;
5454
q += 1;
@@ -57,7 +57,7 @@ pub fn remquo(mut x: f64, mut y: f64) -> (f64, i32) {
5757
q <<= 1;
5858
ex -= 1;
5959
}
60-
i = uxi - uy;
60+
i = uxi.wrapping_sub(uy);
6161
if (i >> 63) == 0 {
6262
uxi = i;
6363
q += 1;

src/math/remquof.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub fn remquof(mut x: f32, mut y: f32) -> (f32, i32) {
4747
}
4848
/* x mod y */
4949
while ex > ey {
50-
i = uxi - uy;
50+
i = uxi.wrapping_sub(uy);
5151
if (i >> 31) == 0 {
5252
uxi = i;
5353
q += 1;
@@ -56,7 +56,7 @@ pub fn remquof(mut x: f32, mut y: f32) -> (f32, i32) {
5656
q <<= 1;
5757
ex -= 1;
5858
}
59-
i = uxi - uy;
59+
i = uxi.wrapping_sub(uy);
6060
if (i >> 31) == 0 {
6161
uxi = i;
6262
q += 1;

0 commit comments

Comments
 (0)