diff --git a/crates/libm-macros/src/shared.rs b/crates/libm-macros/src/shared.rs index 48d19c50d..80431b1b4 100644 --- a/crates/libm-macros/src/shared.rs +++ b/crates/libm-macros/src/shared.rs @@ -92,6 +92,13 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] None, &["copysignf128", "fdimf128", "fmaxf128", "fminf128", "fmodf128"], ), + ( + // `(f16, f16, f16) -> f16` + FloatTy::F16, + Signature { args: &[Ty::F16, Ty::F16, Ty::F16], returns: &[Ty::F16] }, + None, + &["fmaf16"], + ), ( // `(f32, f32, f32) -> f32` FloatTy::F32, diff --git a/crates/libm-test/benches/icount.rs b/crates/libm-test/benches/icount.rs index c41cef24e..3022a5e58 100644 --- a/crates/libm-test/benches/icount.rs +++ b/crates/libm-test/benches/icount.rs @@ -109,6 +109,7 @@ main!( icount_bench_floorf_group, icount_bench_fma_group, icount_bench_fmaf128_group, + icount_bench_fmaf16_group, icount_bench_fmaf_group, icount_bench_fmax_group, icount_bench_fmaxf128_group, diff --git a/crates/libm-test/benches/random.rs b/crates/libm-test/benches/random.rs index 6e8a33479..2e6284283 100644 --- a/crates/libm-test/benches/random.rs +++ b/crates/libm-test/benches/random.rs @@ -128,6 +128,7 @@ libm_macros::for_each_function! { | floorf128 | floorf16 | fmaf128 + | fmaf16 | fmaxf128 | fmaxf16 | fminf128 diff --git a/crates/libm-test/src/gen/case_list.rs b/crates/libm-test/src/gen/case_list.rs index 23226d5c2..87a2e05fa 100644 --- a/crates/libm-test/src/gen/case_list.rs +++ b/crates/libm-test/src/gen/case_list.rs @@ -6,6 +6,8 @@ //! //! This is useful for adding regression tests or expected failures. +#[cfg(f16_enabled)] +use libm::hf16; #[cfg(f128_enabled)] use libm::hf128; @@ -293,6 +295,20 @@ fn fmaf128_cases() -> Vec> { v } +#[cfg(f16_enabled)] +fn fmaf16_cases() -> Vec> { + let mut v = vec![]; + TestCase::append_pairs( + &mut v, + &[( + // Failed during extensive tests + (hf16!("-0x1.c4p-12"), hf16!("0x1.22p-14"), hf16!("-0x1.f4p-15")), + Some(hf16!("-0x1.f48p-15")), + )], + ); + v +} + fn fmax_cases() -> Vec> { vec![] } diff --git a/crates/libm-test/src/mpfloat.rs b/crates/libm-test/src/mpfloat.rs index f4a9ff7ff..8d63047fd 100644 --- a/crates/libm-test/src/mpfloat.rs +++ b/crates/libm-test/src/mpfloat.rs @@ -196,7 +196,7 @@ libm_macros::for_each_function! { expm1 | expm1f => exp_m1, fabs | fabsf => abs, fdim | fdimf | fdimf16 | fdimf128 => positive_diff, - fma | fmaf | fmaf128 => mul_add, + fma | fmaf | fmaf16 | fmaf128 => mul_add, fmax | fmaxf | fmaxf16 | fmaxf128 => max, fmin | fminf | fminf16 | fminf128 => min, lgamma | lgammaf => ln_gamma, diff --git a/crates/libm-test/src/precision.rs b/crates/libm-test/src/precision.rs index 20aa96b6a..67dc419a0 100644 --- a/crates/libm-test/src/precision.rs +++ b/crates/libm-test/src/precision.rs @@ -558,6 +558,8 @@ impl MaybeOverride<(f64, i32)> for SpecialCase {} #[cfg(f128_enabled)] impl MaybeOverride<(f128, i32)> for SpecialCase {} +#[cfg(f16_enabled)] +impl MaybeOverride<(f16, f16, f16)> for SpecialCase {} impl MaybeOverride<(f32, f32, f32)> for SpecialCase {} impl MaybeOverride<(f64, f64, f64)> for SpecialCase {} #[cfg(f128_enabled)] diff --git a/crates/libm-test/tests/compare_built_musl.rs b/crates/libm-test/tests/compare_built_musl.rs index 7fa77e832..77526ba5d 100644 --- a/crates/libm-test/tests/compare_built_musl.rs +++ b/crates/libm-test/tests/compare_built_musl.rs @@ -100,6 +100,7 @@ libm_macros::for_each_function! { floorf128, floorf16, fmaf128, + fmaf16, fmaxf128, fmaxf16, fminf128, diff --git a/crates/util/src/main.rs b/crates/util/src/main.rs index 0f845a1c4..830961da0 100644 --- a/crates/util/src/main.rs +++ b/crates/util/src/main.rs @@ -97,6 +97,7 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) { | floorf128 | floorf16 | fmaf128 + | fmaf16 | fmaxf128 | fmaxf16 | fminf128 diff --git a/etc/function-definitions.json b/etc/function-definitions.json index 5742ed585..63376f0d9 100644 --- a/etc/function-definitions.json +++ b/etc/function-definitions.json @@ -363,6 +363,13 @@ ], "type": "f128" }, + "fmaf16": { + "sources": [ + "src/math/fmaf16.rs", + "src/math/generic/fma.rs" + ], + "type": "f16" + }, "fmax": { "sources": [ "src/math/fmax.rs", diff --git a/etc/function-list.txt b/etc/function-list.txt index 1c9c5e3bc..6d0c7b0c7 100644 --- a/etc/function-list.txt +++ b/etc/function-list.txt @@ -54,6 +54,7 @@ floorf16 fma fmaf fmaf128 +fmaf16 fmax fmaxf fmaxf128 diff --git a/src/libm_helper.rs b/src/libm_helper.rs index 68f1fb362..2ac98fc85 100644 --- a/src/libm_helper.rs +++ b/src/libm_helper.rs @@ -185,6 +185,7 @@ libm_helper! { (fn fabs(x: f16) -> (f16); => fabsf16); (fn fdim(x: f16, y: f16) -> (f16); => fdimf16); (fn floorf(x: f16) -> (f16); => floorf16); + (fn fmaf16(x: f16, y: f16, z: f16) -> (f16); => fmaf16); (fn fmaxf(x: f16, y: f16) -> (f16); => fmaxf16); (fn fminf(x: f16, y: f16) -> (f16); => fminf16); (fn fmodf(x: f16, y: f16) -> (f16); => fmodf16); diff --git a/src/math/fmaf16.rs b/src/math/fmaf16.rs new file mode 100644 index 000000000..a260183bf --- /dev/null +++ b/src/math/fmaf16.rs @@ -0,0 +1,4 @@ +#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] +pub fn fmaf16(x: f16, y: f16, z: f16) -> f16 { + super::generic::fma_wide::(x, y, z) +} diff --git a/src/math/mod.rs b/src/math/mod.rs index e32045021..762f51459 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -347,6 +347,7 @@ cfg_if! { mod fabsf16; mod fdimf16; mod floorf16; + mod fmaf16; mod fmaxf16; mod fminf16; mod fmodf16; @@ -364,6 +365,7 @@ cfg_if! { pub use self::fabsf16::fabsf16; pub use self::fdimf16::fdimf16; pub use self::floorf16::floorf16; + pub use self::fmaf16::fmaf16; pub use self::fmaxf16::fmaxf16; pub use self::fminf16::fminf16; pub use self::fmodf16::fmodf16;