Add truncf16 and truncf128

Use the generic algorithms to provide implementations for these
routines.
This commit is contained in:
Trevor Gross 2025-01-12 04:12:56 +00:00
parent 6ac06a97e5
commit b558b365d3
13 changed files with 61 additions and 5 deletions

View file

@ -157,6 +157,8 @@ no_mangle! {
tgammaf(x: f32) -> f32;
trunc(x: f64) -> f64;
truncf(x: f32) -> f32;
truncf128(x: f128) -> f128;
truncf16(x: f16) -> f16;
y0(x: f64) -> f64;
y0f(x: f32) -> f32;
y1(x: f64) -> f64;

View file

@ -9,7 +9,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
FloatTy::F16,
Signature { args: &[Ty::F16], returns: &[Ty::F16] },
None,
&["fabsf16"],
&["fabsf16", "truncf16"],
),
(
// `fn(f32) -> f32`
@ -40,7 +40,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
FloatTy::F128,
Signature { args: &[Ty::F128], returns: &[Ty::F128] },
None,
&["fabsf128"],
&["fabsf128", "truncf128"],
),
(
// `(f16, f16) -> f16`

View file

@ -117,7 +117,7 @@ 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 => (false, None),
copysignf16 | copysignf128 | fabsf16 | fabsf128 | truncf16 | truncf128 => (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

@ -199,3 +199,13 @@ impl HasDomain<f16> for crate::op::fabsf16::Routine {
impl HasDomain<f128> for crate::op::fabsf128::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;
}
#[cfg(f128_enabled)]
impl HasDomain<f128> for crate::op::truncf128::Routine {
const DOMAIN: Domain<f128> = Domain::<f128>::UNBOUNDED;
}

View file

@ -141,6 +141,7 @@ libm_macros::for_each_function! {
lgamma_r, lgammaf_r, modf, modff, nextafter, nextafterf, pow,powf,
remquo, remquof, scalbn, scalbnf, sincos, sincosf, yn, ynf,
copysignf16, copysignf128, fabsf16, fabsf128,
truncf16, truncf128,
],
fn_extra: match MACRO_FN_NAME {
// Remap function names that are different between mpfr and libm
@ -202,11 +203,13 @@ impl_no_round! {
#[cfg(f16_enabled)]
impl_no_round! {
fabsf16 => abs_mut;
truncf16 => trunc_mut;
}
#[cfg(f128_enabled)]
impl_no_round! {
fabsf128 => abs_mut;
truncf128 => trunc_mut;
}
/// Some functions are difficult to do in a generic way. Implement them here.

View file

@ -48,7 +48,7 @@ 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],
skip: [copysignf16, copysignf128, fabsf16, fabsf128, truncf16, truncf128],
attributes: [
#[cfg_attr(x86_no_sse, ignore)] // FIXME(correctness): wrong result on i586
[exp10, exp10f, exp2, exp2f, rint]
@ -146,5 +146,7 @@ libm_macros::for_each_function! {
// Not provided by musl
fabsf16,
fabsf128,
truncf16,
truncf128,
],
}

View file

@ -84,7 +84,7 @@ 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 => None,
copysignf16 | copysignf128 | fabsf16 | fabsf128 | truncf16 | truncf128 => None,
_ => Some(musl_math_sys::MACRO_FN_NAME)
}
}

View file

@ -743,6 +743,7 @@
"sources": [
"src/libm_helper.rs",
"src/math/arch/wasm32.rs",
"src/math/generic/trunc.rs",
"src/math/trunc.rs"
],
"type": "f64"
@ -750,10 +751,25 @@
"truncf": {
"sources": [
"src/math/arch/wasm32.rs",
"src/math/generic/trunc.rs",
"src/math/truncf.rs"
],
"type": "f32"
},
"truncf128": {
"sources": [
"src/math/generic/trunc.rs",
"src/math/truncf128.rs"
],
"type": "f128"
},
"truncf16": {
"sources": [
"src/math/generic/trunc.rs",
"src/math/truncf16.rs"
],
"type": "f16"
},
"y0": {
"sources": [
"src/libm_helper.rs",

View file

@ -111,6 +111,8 @@ tgamma
tgammaf
trunc
truncf
truncf128
truncf16
y0
y0f
y1

View file

@ -1,3 +1,6 @@
/* SPDX-License-Identifier: MIT
* origin: musl src/math/trunc.c */
use super::super::{Float, Int, IntTy, MinInt};
pub fn trunc<F: Float>(x: F) -> F {

View file

@ -343,9 +343,11 @@ cfg_if! {
if #[cfg(f16_enabled)] {
mod copysignf16;
mod fabsf16;
mod truncf16;
pub use self::copysignf16::copysignf16;
pub use self::fabsf16::fabsf16;
pub use self::truncf16::truncf16;
}
}
@ -353,9 +355,11 @@ cfg_if! {
if #[cfg(f128_enabled)] {
mod copysignf128;
mod fabsf128;
mod truncf128;
pub use self::copysignf128::copysignf128;
pub use self::fabsf128::fabsf128;
pub use self::truncf128::truncf128;
}
}

View file

@ -0,0 +1,7 @@
/// Rounds the number toward 0 to the closest integral value (f128).
///
/// This effectively removes the decimal part of the number, leaving the integral part.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn truncf128(x: f128) -> f128 {
super::generic::trunc(x)
}

View file

@ -0,0 +1,7 @@
/// Rounds the number toward 0 to the closest integral value (f16).
///
/// This effectively removes the decimal part of the number, leaving the integral part.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn truncf16(x: f16) -> f16 {
super::generic::trunc(x)
}