|
9 | 9 | // There are some targets we can't build musl for
|
10 | 10 | #![cfg(feature = "build-musl")]
|
11 | 11 |
|
12 |
| -use libm_test::gen::random; |
| 12 | +use libm_test::domain::HasDomain; |
13 | 13 | use libm_test::gen::random::RandomInput;
|
| 14 | +use libm_test::gen::{domain_logspace, edge_cases, random}; |
14 | 15 | use libm_test::{CheckBasis, CheckCtx, CheckOutput, MathOp, TupleCall};
|
15 | 16 |
|
16 | 17 | macro_rules! musl_rand_tests {
|
@@ -53,3 +54,97 @@ libm_macros::for_each_function! {
|
53 | 54 | [exp10, exp10f, exp2, exp2f, rint]
|
54 | 55 | ],
|
55 | 56 | }
|
| 57 | + |
| 58 | +/// Test against musl with generators from a domain. |
| 59 | +macro_rules! musl_domain_tests { |
| 60 | + ( |
| 61 | + fn_name: $fn_name:ident, |
| 62 | + attrs: [$($attr:meta),*], |
| 63 | + ) => { |
| 64 | + paste::paste! { |
| 65 | + #[test] |
| 66 | + $(#[$attr])* |
| 67 | + fn [< musl_edge_case_ $fn_name >]() { |
| 68 | + type Op = libm_test::op::$fn_name::Routine; |
| 69 | + domain_test_runner::<Op, _>( |
| 70 | + edge_cases::get_test_cases::<Op, _>, |
| 71 | + musl_math_sys::$fn_name, |
| 72 | + ); |
| 73 | + } |
| 74 | + |
| 75 | + #[test] |
| 76 | + $(#[$attr])* |
| 77 | + fn [< musl_logspace_ $fn_name >]() { |
| 78 | + type Op = libm_test::op::$fn_name::Routine; |
| 79 | + domain_test_runner::<Op, _>( |
| 80 | + domain_logspace::get_test_cases::<Op>, |
| 81 | + musl_math_sys::$fn_name, |
| 82 | + ); |
| 83 | + } |
| 84 | + } |
| 85 | + }; |
| 86 | +} |
| 87 | + |
| 88 | +/// Test a single routine against domaine-aware inputs. |
| 89 | +fn domain_test_runner<Op, I>(gen: impl FnOnce(&CheckCtx) -> I, musl_fn: Op::CFn) |
| 90 | +where |
| 91 | + Op: MathOp, |
| 92 | + Op: HasDomain<Op::FTy>, |
| 93 | + I: Iterator<Item = Op::RustArgs>, |
| 94 | +{ |
| 95 | + let ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Musl); |
| 96 | + let cases = gen(&ctx); |
| 97 | + |
| 98 | + for input in cases { |
| 99 | + let musl_res = input.call(musl_fn); |
| 100 | + let crate_res = input.call(Op::ROUTINE); |
| 101 | + |
| 102 | + crate_res.validate(musl_res, input, &ctx).unwrap(); |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +libm_macros::for_each_function! { |
| 107 | + callback: musl_domain_tests, |
| 108 | + attributes: [], |
| 109 | + skip: [ |
| 110 | + // Functions with multiple inputs |
| 111 | + atan2, |
| 112 | + atan2f, |
| 113 | + copysign, |
| 114 | + copysignf, |
| 115 | + copysignf16, |
| 116 | + copysignf128, |
| 117 | + fdim, |
| 118 | + fdimf, |
| 119 | + fma, |
| 120 | + fmaf, |
| 121 | + fmax, |
| 122 | + fmaxf, |
| 123 | + fmin, |
| 124 | + fminf, |
| 125 | + fmod, |
| 126 | + fmodf, |
| 127 | + hypot, |
| 128 | + hypotf, |
| 129 | + jn, |
| 130 | + jnf, |
| 131 | + ldexp, |
| 132 | + ldexpf, |
| 133 | + nextafter, |
| 134 | + nextafterf, |
| 135 | + pow, |
| 136 | + powf, |
| 137 | + remainder, |
| 138 | + remainderf, |
| 139 | + remquo, |
| 140 | + remquof, |
| 141 | + scalbn, |
| 142 | + scalbnf, |
| 143 | + yn, |
| 144 | + ynf, |
| 145 | + |
| 146 | + // Not provided by musl |
| 147 | + fabsf16, |
| 148 | + fabsf128, |
| 149 | + ], |
| 150 | +} |
0 commit comments