From 642d082c46ef777d50e9f8ffaaff0c50aebdda6d Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 17 May 2024 22:05:59 -0500 Subject: [PATCH] Add float to integer conversion functions for `f128` --- README.md | 12 ++++++------ build.rs | 10 ---------- src/float/conv.rs | 30 ++++++++++++++++++++++++++++++ testcrate/Cargo.toml | 4 +++- testcrate/build.rs | 30 +++++++++++++++++++++++++++--- testcrate/tests/conv.rs | 22 ++++++++++++++++++++++ 6 files changed, 88 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 37d7ab2e..8233c669 100644 --- a/README.md +++ b/README.md @@ -239,12 +239,12 @@ These builtins are needed to support `f16` and `f128`, which are in the process - [x] extendhfsf2.c - [x] extendhftf2.c - [x] extendsftf2.c -- [ ] fixtfdi.c -- [ ] fixtfsi.c -- [ ] fixtfti.c -- [ ] fixunstfdi.c -- [ ] fixunstfsi.c -- [ ] fixunstfti.c +- [x] fixtfdi.c +- [x] fixtfsi.c +- [x] fixtfti.c +- [x] fixunstfdi.c +- [x] fixunstfsi.c +- [x] fixunstfti.c - [ ] floatditf.c - [ ] floatsitf.c - [ ] floatunditf.c diff --git a/build.rs b/build.rs index ec830ecb..50415910 100644 --- a/build.rs +++ b/build.rs @@ -533,12 +533,6 @@ mod c { if (target_arch == "aarch64" || target_arch == "arm64ec") && consider_float_intrinsics { sources.extend(&[ ("__comparetf2", "comparetf2.c"), - ("__fixtfdi", "fixtfdi.c"), - ("__fixtfsi", "fixtfsi.c"), - ("__fixtfti", "fixtfti.c"), - ("__fixunstfdi", "fixunstfdi.c"), - ("__fixunstfsi", "fixunstfsi.c"), - ("__fixunstfti", "fixunstfti.c"), ("__floatditf", "floatditf.c"), ("__floatsitf", "floatsitf.c"), ("__floatunditf", "floatunditf.c"), @@ -561,9 +555,7 @@ mod c { if target_arch == "mips64" { sources.extend(&[ ("__netf2", "comparetf2.c"), - ("__fixtfsi", "fixtfsi.c"), ("__floatsitf", "floatsitf.c"), - ("__fixunstfsi", "fixunstfsi.c"), ("__floatunsitf", "floatunsitf.c"), ("__fe_getround", "fp_mode.c"), ]); @@ -572,9 +564,7 @@ mod c { if target_arch == "loongarch64" { sources.extend(&[ ("__netf2", "comparetf2.c"), - ("__fixtfsi", "fixtfsi.c"), ("__floatsitf", "floatsitf.c"), - ("__fixunstfsi", "fixunstfsi.c"), ("__floatunsitf", "floatunsitf.c"), ("__fe_getround", "fp_mode.c"), ]); diff --git a/src/float/conv.rs b/src/float/conv.rs index 931840f1..a37206cd 100644 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -261,6 +261,21 @@ intrinsics! { pub extern "C" fn __fixunsdfti(f: f64) -> u128 { float_to_unsigned_int(f) } + + #[cfg(not(feature = "no-f16-f128"))] + pub extern "C" fn __fixunstfsi(f: f128) -> u32 { + float_to_unsigned_int(f) + } + + #[cfg(not(feature = "no-f16-f128"))] + pub extern "C" fn __fixunstfdi(f: f128) -> u64 { + float_to_unsigned_int(f) + } + + #[cfg(not(feature = "no-f16-f128"))] + pub extern "C" fn __fixunstfti(f: f128) -> u128 { + float_to_unsigned_int(f) + } } // Conversions from floats to signed integers. @@ -294,4 +309,19 @@ intrinsics! { pub extern "C" fn __fixdfti(f: f64) -> i128 { float_to_signed_int(f) } + + #[cfg(not(feature = "no-f16-f128"))] + pub extern "C" fn __fixtfsi(f: f128) -> i32 { + float_to_signed_int(f) + } + + #[cfg(not(feature = "no-f16-f128"))] + pub extern "C" fn __fixtfdi(f: f128) -> i64 { + float_to_signed_int(f) + } + + #[cfg(not(feature = "no-f16-f128"))] + pub extern "C" fn __fixtfti(f: f128) -> i128 { + float_to_signed_int(f) + } } diff --git a/testcrate/Cargo.toml b/testcrate/Cargo.toml index 6f771181..1de0c397 100644 --- a/testcrate/Cargo.toml +++ b/testcrate/Cargo.toml @@ -34,4 +34,6 @@ no-f16-f128 = ["compiler_builtins/no-f16-f128"] mem = ["compiler_builtins/mem"] mangled-names = ["compiler_builtins/mangled-names"] # Skip tests that rely on f128 symbols being available on the system -no-sys-f128 = [] +no-sys-f128 = ["no-sys-f128-int-convert"] +# Some platforms have some f128 functions but everything except integer conversions +no-sys-f128-int-convert = [] diff --git a/testcrate/build.rs b/testcrate/build.rs index f24dae3c..e19d33dd 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -1,7 +1,15 @@ -use std::env; +use std::{collections::HashSet, env}; + +/// Features to enable +#[derive(Debug, PartialEq, Eq, Hash)] +enum Feature { + NoSysF128, + NoSysF128IntConvert, +} fn main() { let target = env::var("TARGET").unwrap(); + let mut features = HashSet::new(); // These platforms do not have f128 symbols available in their system libraries, so // skip related tests. @@ -21,7 +29,23 @@ fn main() { // . || target.starts_with("powerpc64-") { - println!("cargo:warning=using apfloat fallback for f128"); - println!("cargo:rustc-cfg=feature=\"no-sys-f128\""); + features.insert(Feature::NoSysF128); + features.insert(Feature::NoSysF128IntConvert); + } + + if target.starts_with("i586") { + features.insert(Feature::NoSysF128IntConvert); + } + + for feature in features { + let (name, warning) = match feature { + Feature::NoSysF128 => ("no-sys-f128", "using apfloat fallback for f128"), + Feature::NoSysF128IntConvert => ( + "no-sys-f128-int-convert", + "using apfloat fallback for f128 to int conversions", + ), + }; + println!("cargo:warning={warning}"); + println!("cargo:rustc-cfg=feature=\"{name}\""); } } diff --git a/testcrate/tests/conv.rs b/testcrate/tests/conv.rs index 470a9bc0..89d2be10 100644 --- a/testcrate/tests/conv.rs +++ b/testcrate/tests/conv.rs @@ -166,6 +166,28 @@ fn float_to_int() { i128, __fixdfti; ); }); + + #[cfg(not(feature = "no-f16-f128"))] + { + use compiler_builtins::float::conv::{ + __fixtfdi, __fixtfsi, __fixtfti, __fixunstfdi, __fixunstfsi, __fixunstfti, + }; + + fuzz_float(N, |x: f128| { + f_to_i!( + x, + f128, + Quad, + not(feature = "no-sys-f128-int-convert"), + u32, __fixunstfsi; + u64, __fixunstfdi; + u128, __fixunstfti; + i32, __fixtfsi; + i64, __fixtfdi; + i128, __fixtfti; + ); + }); + } } macro_rules! conv {