Skip to content

Commit 854585f

Browse files
Implement copysign for libcalls
1 parent 96851fd commit 854585f

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/float/bitops.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// FIXME: This module existing reflects a failure of the codegen backend to always legalize bitops.
2+
// LLVM should be taught how to always emit llvm.fcopysign for f{16,32,64,128} without needing this!
3+
4+
// FIXME: delete when we move fabs to core and it reaches stable
5+
fn fabs_f32(f: f32) -> f32 {
6+
f32::from_bits(f.to_bits() & const { !(i32::MIN as u32) })
7+
}
8+
9+
// FIXME: delete when we move fabs to core and it reaches stable
10+
fn fabs_f64(f: f64) -> f64 {
11+
f64::from_bits(f.to_bits() & const { !(i64::MIN as u64) })
12+
}
13+
14+
// FIXME: delete when we move fabs to core and it reaches stable
15+
fn fabs_128(f: f128) -> f128 {
16+
f128::from_bits(f.to_bits() & const { !(i128::MIN as u128) })
17+
}
18+
19+
fn copysign_f32(magnitude: f32, sign: f32) -> f32 {
20+
let sign = fabs_f32(sign).to_bits() ^ sign.to_bits();
21+
f32::from_bits(fabs_f32(magnitude).to_bits() | sign)
22+
}
23+
24+
fn copysign_f64(magnitude: f64, sign: f64) -> f64 {
25+
let sign = fabs_f64(sign).to_bits() ^ sign.to_bits();
26+
f64::from_bits(fabs_f64(magnitude).to_bits() | sign)
27+
}
28+
29+
fn copysign_f128(magnitude: f128, sign: f128) -> f128 {
30+
let sign = fabs_128(sign).to_bits() ^ sign.to_bits();
31+
f128::from_bits(fabs_128(magnitude).to_bits() | sign)
32+
}
33+
34+
intrinsics! {
35+
#[cfg_attr(target_env = "msvc", link_name = "_fcopysign")]
36+
pub extern "C" fn fcopysign(magnitude: f32, sign: f32) -> f32 {
37+
copysign_f32(magnitude, sign)
38+
}
39+
40+
#[cfg_attr(target_env = "msvc", link_name = "_copysign")]
41+
pub extern "C" fn copysign(magnitude: f64, sign: f64) -> f64 {
42+
copysign_f64(magnitude, sign)
43+
}
44+
45+
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64")))]
46+
pub extern "C" fn copysignl(magnitude: f128, sign: f128) -> f128 {
47+
copysign_f128(magnitude, sign)
48+
}
49+
50+
#[cfg(any(target_arch = "x86_64", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64"))]
51+
pub extern "C" fn copysignf128(magnitude: f128, sign: f128) -> f128 {
52+
copysign_f128(magnitude, sign)
53+
}
54+
}

src/float/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use core::ops;
33
use crate::int::{DInt, Int, MinInt};
44

55
pub mod add;
6+
pub mod bitops;
67
pub mod cmp;
78
pub mod conv;
89
pub mod div;

0 commit comments

Comments
 (0)