diff --git a/library/compiler-builtins/libm/src/libm_helper.rs b/library/compiler-builtins/libm/src/libm_helper.rs index 52d0c4c2a11e..f087267e46c7 100644 --- a/library/compiler-builtins/libm/src/libm_helper.rs +++ b/library/compiler-builtins/libm/src/libm_helper.rs @@ -30,7 +30,7 @@ macro_rules! libm_helper { } }; - ({$($func:tt);*}) => { + ({$($func:tt;)*}) => { $( libm_helper! { $func } )* @@ -103,7 +103,7 @@ libm_helper! { (fn trunc(x: f32) -> (f32); => truncf); (fn y0(x: f32) -> (f32); => y0f); (fn y1(x: f32) -> (f32); => y1f); - (fn yn(n: i32, x: f32) -> (f32); => ynf) + (fn yn(n: i32, x: f32) -> (f32); => ynf); } } @@ -166,6 +166,24 @@ libm_helper! { (fn trunc(x: f64) -> (f64); => trunc); (fn y0(x: f64) -> (f64); => y0); (fn y1(x: f64) -> (f64); => y1); - (fn yn(n: i32, x: f64) -> (f64); => yn) + (fn yn(n: i32, x: f64) -> (f64); => yn); + } +} + +#[cfg(f16_enabled)] +libm_helper! { + f16, + funcs: { + (fn copysign(x: f16, y: f16) -> (f16); => copysignf16); + (fn fabs(x: f16) -> (f16); => fabsf16); + } +} + +#[cfg(f128_enabled)] +libm_helper! { + f128, + funcs: { + (fn copysign(x: f128, y: f128) -> (f128); => copysignf128); + (fn fabs(x: f128) -> (f128); => fabsf128); } } diff --git a/library/compiler-builtins/libm/src/math/copysignf128.rs b/library/compiler-builtins/libm/src/math/copysignf128.rs new file mode 100644 index 000000000000..7bd81d42b2e9 --- /dev/null +++ b/library/compiler-builtins/libm/src/math/copysignf128.rs @@ -0,0 +1,8 @@ +/// Sign of Y, magnitude of X (f128) +/// +/// Constructs a number with the magnitude (absolute value) of its +/// first argument, `x`, and the sign of its second argument, `y`. +#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] +pub fn copysignf128(x: f128, y: f128) -> f128 { + super::generic::copysign(x, y) +} diff --git a/library/compiler-builtins/libm/src/math/copysignf16.rs b/library/compiler-builtins/libm/src/math/copysignf16.rs new file mode 100644 index 000000000000..820658686010 --- /dev/null +++ b/library/compiler-builtins/libm/src/math/copysignf16.rs @@ -0,0 +1,8 @@ +/// Sign of Y, magnitude of X (f16) +/// +/// Constructs a number with the magnitude (absolute value) of its +/// first argument, `x`, and the sign of its second argument, `y`. +#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] +pub fn copysignf16(x: f16, y: f16) -> f16 { + super::generic::copysign(x, y) +} diff --git a/library/compiler-builtins/libm/src/math/fabs.rs b/library/compiler-builtins/libm/src/math/fabs.rs index 6687fdcc3563..46c0d88a5c04 100644 --- a/library/compiler-builtins/libm/src/math/fabs.rs +++ b/library/compiler-builtins/libm/src/math/fabs.rs @@ -1,4 +1,5 @@ /// Absolute value (magnitude) (f64) +/// /// Calculates the absolute value (magnitude) of the argument `x`, /// by direct manipulation of the bit representation of `x`. #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] diff --git a/library/compiler-builtins/libm/src/math/fabsf.rs b/library/compiler-builtins/libm/src/math/fabsf.rs index 99bb5b5f1c9d..d5775b600d97 100644 --- a/library/compiler-builtins/libm/src/math/fabsf.rs +++ b/library/compiler-builtins/libm/src/math/fabsf.rs @@ -1,4 +1,5 @@ /// Absolute value (magnitude) (f32) +/// /// Calculates the absolute value (magnitude) of the argument `x`, /// by direct manipulation of the bit representation of `x`. #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] diff --git a/library/compiler-builtins/libm/src/math/fabsf128.rs b/library/compiler-builtins/libm/src/math/fabsf128.rs new file mode 100644 index 000000000000..ef531bd91a45 --- /dev/null +++ b/library/compiler-builtins/libm/src/math/fabsf128.rs @@ -0,0 +1,37 @@ +/// Absolute value (magnitude) (f128) +/// +/// Calculates the absolute value (magnitude) of the argument `x`, +/// by direct manipulation of the bit representation of `x`. +#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] +pub fn fabsf128(x: f128) -> f128 { + select_implementation! { + name: fabsf, + use_intrinsic: target_arch = "wasm32", + args: x, + } + + super::generic::fabs(x) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sanity_check() { + assert_eq!(fabsf128(-1.0), 1.0); + assert_eq!(fabsf128(2.8), 2.8); + } + + /// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs + #[test] + fn spec_tests() { + assert!(fabsf128(f128::NAN).is_nan()); + for f in [0.0, -0.0].iter().copied() { + assert_eq!(fabsf128(f), 0.0); + } + for f in [f128::INFINITY, f128::NEG_INFINITY].iter().copied() { + assert_eq!(fabsf128(f), f128::INFINITY); + } + } +} diff --git a/library/compiler-builtins/libm/src/math/fabsf16.rs b/library/compiler-builtins/libm/src/math/fabsf16.rs new file mode 100644 index 000000000000..eb41f7391e51 --- /dev/null +++ b/library/compiler-builtins/libm/src/math/fabsf16.rs @@ -0,0 +1,37 @@ +/// Absolute value (magnitude) (f16) +/// +/// Calculates the absolute value (magnitude) of the argument `x`, +/// by direct manipulation of the bit representation of `x`. +#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] +pub fn fabsf16(x: f16) -> f16 { + select_implementation! { + name: fabsf, + use_intrinsic: target_arch = "wasm32", + args: x, + } + + super::generic::fabs(x) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sanity_check() { + assert_eq!(fabsf16(-1.0), 1.0); + assert_eq!(fabsf16(2.8), 2.8); + } + + /// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs + #[test] + fn spec_tests() { + assert!(fabsf16(f16::NAN).is_nan()); + for f in [0.0, -0.0].iter().copied() { + assert_eq!(fabsf16(f), 0.0); + } + for f in [f16::INFINITY, f16::NEG_INFINITY].iter().copied() { + assert_eq!(fabsf16(f), f16::INFINITY); + } + } +} diff --git a/library/compiler-builtins/libm/src/math/mod.rs b/library/compiler-builtins/libm/src/math/mod.rs index 9003a8342880..5baf35e42453 100644 --- a/library/compiler-builtins/libm/src/math/mod.rs +++ b/library/compiler-builtins/libm/src/math/mod.rs @@ -339,6 +339,26 @@ pub use self::tgammaf::tgammaf; pub use self::trunc::trunc; pub use self::truncf::truncf; +cfg_if! { + if #[cfg(f16_enabled)] { + mod copysignf16; + mod fabsf16; + + pub use self::copysignf16::copysignf16; + pub use self::fabsf16::fabsf16; + } +} + +cfg_if! { + if #[cfg(f128_enabled)] { + mod copysignf128; + mod fabsf128; + + pub use self::copysignf128::copysignf128; + pub use self::fabsf128::fabsf128; + } +} + #[inline] fn get_high_word(x: f64) -> u32 { (x.to_bits() >> 32) as u32