From 854585f68044ae9641e03a06dbcc6bdcd22a1aab Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 5 Oct 2024 16:24:18 -0700 Subject: [PATCH 1/5] Implement copysign for libcalls --- src/float/bitops.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++ src/float/mod.rs | 1 + 2 files changed, 55 insertions(+) create mode 100644 src/float/bitops.rs diff --git a/src/float/bitops.rs b/src/float/bitops.rs new file mode 100644 index 00000000..aeacfe51 --- /dev/null +++ b/src/float/bitops.rs @@ -0,0 +1,54 @@ +// FIXME: This module existing reflects a failure of the codegen backend to always legalize bitops. +// LLVM should be taught how to always emit llvm.fcopysign for f{16,32,64,128} without needing this! + +// FIXME: delete when we move fabs to core and it reaches stable +fn fabs_f32(f: f32) -> f32 { + f32::from_bits(f.to_bits() & const { !(i32::MIN as u32) }) +} + +// FIXME: delete when we move fabs to core and it reaches stable +fn fabs_f64(f: f64) -> f64 { + f64::from_bits(f.to_bits() & const { !(i64::MIN as u64) }) +} + +// FIXME: delete when we move fabs to core and it reaches stable +fn fabs_128(f: f128) -> f128 { + f128::from_bits(f.to_bits() & const { !(i128::MIN as u128) }) +} + +fn copysign_f32(magnitude: f32, sign: f32) -> f32 { + let sign = fabs_f32(sign).to_bits() ^ sign.to_bits(); + f32::from_bits(fabs_f32(magnitude).to_bits() | sign) +} + +fn copysign_f64(magnitude: f64, sign: f64) -> f64 { + let sign = fabs_f64(sign).to_bits() ^ sign.to_bits(); + f64::from_bits(fabs_f64(magnitude).to_bits() | sign) +} + +fn copysign_f128(magnitude: f128, sign: f128) -> f128 { + let sign = fabs_128(sign).to_bits() ^ sign.to_bits(); + f128::from_bits(fabs_128(magnitude).to_bits() | sign) +} + +intrinsics! { + #[cfg_attr(target_env = "msvc", link_name = "_fcopysign")] + pub extern "C" fn fcopysign(magnitude: f32, sign: f32) -> f32 { + copysign_f32(magnitude, sign) + } + + #[cfg_attr(target_env = "msvc", link_name = "_copysign")] + pub extern "C" fn copysign(magnitude: f64, sign: f64) -> f64 { + copysign_f64(magnitude, sign) + } + + #[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64")))] + pub extern "C" fn copysignl(magnitude: f128, sign: f128) -> f128 { + copysign_f128(magnitude, sign) + } + + #[cfg(any(target_arch = "x86_64", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64"))] + pub extern "C" fn copysignf128(magnitude: f128, sign: f128) -> f128 { + copysign_f128(magnitude, sign) + } +} diff --git a/src/float/mod.rs b/src/float/mod.rs index 704bba0c..cc494aef 100644 --- a/src/float/mod.rs +++ b/src/float/mod.rs @@ -3,6 +3,7 @@ use core::ops; use crate::int::{DInt, Int, MinInt}; pub mod add; +pub mod bitops; pub mod cmp; pub mod conv; pub mod div; From 2956c2c380b4f9193c4754f47e923a005cbfad72 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 5 Oct 2024 19:22:07 -0700 Subject: [PATCH 2/5] Add cfg for f128 --- src/float/bitops.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/float/bitops.rs b/src/float/bitops.rs index aeacfe51..36895a22 100644 --- a/src/float/bitops.rs +++ b/src/float/bitops.rs @@ -12,6 +12,7 @@ fn fabs_f64(f: f64) -> f64 { } // FIXME: delete when we move fabs to core and it reaches stable +#[cfg(f128_enabled)] fn fabs_128(f: f128) -> f128 { f128::from_bits(f.to_bits() & const { !(i128::MIN as u128) }) } @@ -26,6 +27,7 @@ fn copysign_f64(magnitude: f64, sign: f64) -> f64 { f64::from_bits(fabs_f64(magnitude).to_bits() | sign) } +#[cfg(f128_enabled)] fn copysign_f128(magnitude: f128, sign: f128) -> f128 { let sign = fabs_128(sign).to_bits() ^ sign.to_bits(); f128::from_bits(fabs_128(magnitude).to_bits() | sign) @@ -42,11 +44,13 @@ intrinsics! { copysign_f64(magnitude, sign) } + #[cfg(f128_enabled)] #[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64")))] pub extern "C" fn copysignl(magnitude: f128, sign: f128) -> f128 { copysign_f128(magnitude, sign) } + #[cfg(f128_enabled)] #[cfg(any(target_arch = "x86_64", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64"))] pub extern "C" fn copysignf128(magnitude: f128, sign: f128) -> f128 { copysign_f128(magnitude, sign) From b2b57e2880ecfd18fbadb6b1d04dce196ccdbcb7 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 5 Oct 2024 19:28:26 -0700 Subject: [PATCH 3/5] s/link_name/export_name/ --- src/float/bitops.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/float/bitops.rs b/src/float/bitops.rs index 36895a22..bfff6eb5 100644 --- a/src/float/bitops.rs +++ b/src/float/bitops.rs @@ -34,12 +34,12 @@ fn copysign_f128(magnitude: f128, sign: f128) -> f128 { } intrinsics! { - #[cfg_attr(target_env = "msvc", link_name = "_fcopysign")] + #[cfg_attr(target_env = "msvc", export_name = "_fcopysign")] pub extern "C" fn fcopysign(magnitude: f32, sign: f32) -> f32 { copysign_f32(magnitude, sign) } - #[cfg_attr(target_env = "msvc", link_name = "_copysign")] + #[cfg_attr(target_env = "msvc", export_name = "_copysign")] pub extern "C" fn copysign(magnitude: f64, sign: f64) -> f64 { copysign_f64(magnitude, sign) } From 0ad0d514ea53596e46f087073930bc7fdabbf038 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 5 Oct 2024 19:37:51 -0700 Subject: [PATCH 4/5] Well die then --- src/float/bitops.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/float/bitops.rs b/src/float/bitops.rs index bfff6eb5..896fe32a 100644 --- a/src/float/bitops.rs +++ b/src/float/bitops.rs @@ -34,12 +34,12 @@ fn copysign_f128(magnitude: f128, sign: f128) -> f128 { } intrinsics! { - #[cfg_attr(target_env = "msvc", export_name = "_fcopysign")] + #[cfg(not(any(target_env = "msvc", target_vendor = "apple")))] pub extern "C" fn fcopysign(magnitude: f32, sign: f32) -> f32 { copysign_f32(magnitude, sign) } - #[cfg_attr(target_env = "msvc", export_name = "_copysign")] + #[cfg(not(any(target_env = "msvc", target_vendor = "apple")))] pub extern "C" fn copysign(magnitude: f64, sign: f64) -> f64 { copysign_f64(magnitude, sign) } From f2970eeec0ea7e6d408e2ba47ed9d08a0c4d38a2 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 5 Oct 2024 19:41:13 -0700 Subject: [PATCH 5/5] more of you into the furnace --- src/float/bitops.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/float/bitops.rs b/src/float/bitops.rs index 896fe32a..af98d122 100644 --- a/src/float/bitops.rs +++ b/src/float/bitops.rs @@ -2,11 +2,13 @@ // LLVM should be taught how to always emit llvm.fcopysign for f{16,32,64,128} without needing this! // FIXME: delete when we move fabs to core and it reaches stable +#[cfg(not(any(target_env = "msvc", target_vendor = "apple")))] fn fabs_f32(f: f32) -> f32 { f32::from_bits(f.to_bits() & const { !(i32::MIN as u32) }) } // FIXME: delete when we move fabs to core and it reaches stable +#[cfg(not(any(target_env = "msvc", target_vendor = "apple")))] fn fabs_f64(f: f64) -> f64 { f64::from_bits(f.to_bits() & const { !(i64::MIN as u64) }) } @@ -17,11 +19,13 @@ fn fabs_128(f: f128) -> f128 { f128::from_bits(f.to_bits() & const { !(i128::MIN as u128) }) } +#[cfg(not(any(target_env = "msvc", target_vendor = "apple")))] fn copysign_f32(magnitude: f32, sign: f32) -> f32 { let sign = fabs_f32(sign).to_bits() ^ sign.to_bits(); f32::from_bits(fabs_f32(magnitude).to_bits() | sign) } +#[cfg(not(any(target_env = "msvc", target_vendor = "apple")))] fn copysign_f64(magnitude: f64, sign: f64) -> f64 { let sign = fabs_f64(sign).to_bits() ^ sign.to_bits(); f64::from_bits(fabs_f64(magnitude).to_bits() | sign)