|
| 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 | +} |
0 commit comments