Add fdimf16 and fdimf128

Use the generic algorithms to provide implementations for these
routines.
This commit is contained in:
Trevor Gross 2025-01-13 13:58:40 +00:00
parent 0f285df716
commit 13b5bf3959
14 changed files with 93 additions and 8 deletions

View file

@ -93,6 +93,8 @@ no_mangle! {
fabsf16(x: f16) -> f16;
fdim(x: f64, y: f64) -> f64;
fdimf(x: f32, y: f32) -> f32;
fdimf128(x: f128, y: f128) -> f128;
fdimf16(x: f16, y: f16) -> f16;
floor(x: f64) -> f64;
floorf(x: f32) -> f32;
fma(x: f64, y: f64, z: f64) -> f64;

View file

@ -47,7 +47,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
FloatTy::F16,
Signature { args: &[Ty::F16, Ty::F16], returns: &[Ty::F16] },
None,
&["copysignf16"],
&["copysignf16", "fdimf16"],
),
(
// `(f32, f32) -> f32`
@ -90,7 +90,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
FloatTy::F128,
Signature { args: &[Ty::F128, Ty::F128], returns: &[Ty::F128] },
None,
&["copysignf128"],
&["copysignf128", "fdimf128"],
),
(
// `(f32, f32, f32) -> f32`

View file

@ -117,7 +117,14 @@ libm_macros::for_each_function! {
exp10 | exp10f | exp2 | exp2f => (true, Some(musl_math_sys::MACRO_FN_NAME)),
// Musl does not provide `f16` and `f128` functions
copysignf16 | copysignf128 | fabsf16 | fabsf128 | truncf16 | truncf128 => (false, None),
copysignf128
| copysignf16
| fabsf128
| fabsf16
| fdimf128
| fdimf16
| truncf128
| truncf16 => (false, None),
// By default we never skip (false) and always have a musl function available
_ => (false, Some(musl_math_sys::MACRO_FN_NAME))

View file

@ -200,6 +200,16 @@ impl HasDomain<f128> for crate::op::fabsf128::Routine {
const DOMAIN: Domain<f128> = Domain::<f128>::UNBOUNDED;
}
#[cfg(f16_enabled)]
impl HasDomain<f16> for crate::op::fdimf16::Routine {
const DOMAIN: Domain<f16> = Domain::<f16>::UNBOUNDED;
}
#[cfg(f128_enabled)]
impl HasDomain<f128> for crate::op::fdimf128::Routine {
const DOMAIN: Domain<f128> = Domain::<f128>::UNBOUNDED;
}
#[cfg(f16_enabled)]
impl HasDomain<f16> for crate::op::truncf16::Routine {
const DOMAIN: Domain<f16> = Domain::<f16>::UNBOUNDED;

View file

@ -181,7 +181,7 @@ libm_macros::for_each_function! {
// Remap function names that are different between mpfr and libm
expm1 | expm1f => exp_m1,
fabs | fabsf => abs,
fdim | fdimf => positive_diff,
fdim | fdimf | fdimf16 | fdimf128 => positive_diff,
fma | fmaf => mul_add,
fmax | fmaxf => max,
fmin | fminf => min,

View file

@ -48,7 +48,16 @@ where
libm_macros::for_each_function! {
callback: musl_rand_tests,
// Musl does not support `f16` and `f128` on all platforms.
skip: [copysignf16, copysignf128, fabsf16, fabsf128, truncf16, truncf128],
skip: [
copysignf128,
copysignf16,
fabsf128,
fabsf16,
fdimf128,
fdimf16,
truncf128,
truncf16,
],
attributes: [
#[cfg_attr(x86_no_sse, ignore)] // FIXME(correctness): wrong result on i586
[exp10, exp10f, exp2, exp2f, rint]
@ -144,9 +153,11 @@ libm_macros::for_each_function! {
ynf,
// Not provided by musl
fabsf16,
fabsf128,
truncf16,
fabsf16,
fdimf128,
fdimf16,
truncf128,
truncf16,
],
}

View file

@ -120,6 +120,8 @@ libm_macros::for_each_function! {
copysignf128,
fdim,
fdimf,
fdimf16,
fdimf128,
fma,
fmaf,
fmax,

View file

@ -84,7 +84,14 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
emit_types: [CFn, RustFn, RustArgs],
extra: (basis, op, inputs),
fn_extra: match MACRO_FN_NAME {
copysignf16 | copysignf128 | fabsf16 | fabsf128 | truncf16 | truncf128 => None,
copysignf128
| copysignf16
| fabsf128
| fabsf16
| fdimf128
| fdimf16
| truncf128
| truncf16 => None,
_ => Some(musl_math_sys::MACRO_FN_NAME)
}
}

View file

@ -301,6 +301,20 @@
],
"type": "f32"
},
"fdimf128": {
"sources": [
"src/math/fdimf128.rs",
"src/math/generic/fdim.rs"
],
"type": "f128"
},
"fdimf16": {
"sources": [
"src/math/fdimf16.rs",
"src/math/generic/fdim.rs"
],
"type": "f16"
},
"floor": {
"sources": [
"src/libm_helper.rs",

View file

@ -43,6 +43,8 @@ fabsf128
fabsf16
fdim
fdimf
fdimf128
fdimf16
floor
floorf
fma

View file

@ -176,6 +176,7 @@ libm_helper! {
funcs: {
(fn copysign(x: f16, y: f16) -> (f16); => copysignf16);
(fn fabs(x: f16) -> (f16); => fabsf16);
(fn fdim(x: f16, y: f16) -> (f16); => fdimf16);
}
}
@ -185,5 +186,6 @@ libm_helper! {
funcs: {
(fn copysign(x: f128, y: f128) -> (f128); => copysignf128);
(fn fabs(x: f128) -> (f128); => fabsf128);
(fn fdim(x: f128, y: f128) -> (f128); => fdimf128);
}
}

View file

@ -0,0 +1,12 @@
/// Positive difference (f128)
///
/// Determines the positive difference between arguments, returning:
/// * x - y if x > y, or
/// * +0 if x <= y, or
/// * NAN if either argument is NAN.
///
/// A range error may occur.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fdimf128(x: f128, y: f128) -> f128 {
super::generic::fdim(x, y)
}

View file

@ -0,0 +1,12 @@
/// Positive difference (f16)
///
/// Determines the positive difference between arguments, returning:
/// * x - y if x > y, or
/// * +0 if x <= y, or
/// * NAN if either argument is NAN.
///
/// A range error may occur.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fdimf16(x: f16, y: f16) -> f16 {
super::generic::fdim(x, y)
}

View file

@ -343,10 +343,12 @@ cfg_if! {
if #[cfg(f16_enabled)] {
mod copysignf16;
mod fabsf16;
mod fdimf16;
mod truncf16;
pub use self::copysignf16::copysignf16;
pub use self::fabsf16::fabsf16;
pub use self::fdimf16::fdimf16;
pub use self::truncf16::truncf16;
}
}
@ -355,10 +357,12 @@ cfg_if! {
if #[cfg(f128_enabled)] {
mod copysignf128;
mod fabsf128;
mod fdimf128;
mod truncf128;
pub use self::copysignf128::copysignf128;
pub use self::fabsf128::fabsf128;
pub use self::fdimf128::fdimf128;
pub use self::truncf128::truncf128;
}
}