Add f128 float to integer conversion functions

Add the following:

- `__fixtfsi`
- `__fixtfdi`
- `__fixtfti`
- `__fixunstfsi`
- `__fixunstfdi`
- `__fixunstfti`
This commit is contained in:
Trevor Gross 2024-05-20 20:00:11 -04:00
parent aaaf62bd6b
commit ccd179b231
6 changed files with 92 additions and 22 deletions

View file

@ -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

View file

@ -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"),
]);

View file

@ -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)
}
}

View file

@ -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 = []

View file

@ -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,24 @@ fn main() {
// <https://github.com/rust-lang/compiler-builtins/pull/606#issuecomment-2105657287>.
|| 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") || target.starts_with("i686") {
// 32-bit x86 seems to not have `__fixunstfti`, but does have everything else
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}\"");
}
}

View file

@ -146,7 +146,7 @@ mod f_to_i {
};
fuzz_float(N, |x: f32| {
f_to_i!(x,
f_to_i!(x, f32, Single, all(),
u32, __fixunssfsi;
u64, __fixunssfdi;
u128, __fixunssfti;
@ -164,7 +164,7 @@ mod f_to_i {
};
fuzz_float(N, |x: f64| {
f_to_i!(x,
f_to_i!(x, f64, Double, all(),
u32, __fixunsdfsi;
u64, __fixunsdfdi;
u128, __fixunsdfti;
@ -174,6 +174,29 @@ mod f_to_i {
);
});
}
#[test]
#[cfg(not(feature = "no-f16-f128"))]
fn f128_to_int() {
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 {