Make use of select_implementation
Replace all uses of `llvm_intrinsically` with select_implementation`.
This commit is contained in:
parent
d54896343c
commit
60e7e3b338
11 changed files with 50 additions and 90 deletions
|
|
@ -8,14 +8,12 @@ const TOINT: f64 = 1. / f64::EPSILON;
|
|||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn ceil(x: f64) -> f64 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f64.ceil` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::ceilf64(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: ceil,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
|
||||
{
|
||||
//use an alternative implementation on x86, because the
|
||||
|
|
|
|||
|
|
@ -5,14 +5,12 @@ use core::f32;
|
|||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn ceilf(x: f32) -> f32 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f32.ceil` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::ceilf32(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: ceilf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
let mut ui = x.to_bits();
|
||||
let e = (((ui >> 23) & 0xff).wrapping_sub(0x7f)) as i32;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,12 @@ use core::u64;
|
|||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn fabs(x: f64) -> f64 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f64.abs` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::fabsf64(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: fabs,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
f64::from_bits(x.to_bits() & (u64::MAX / 2))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@
|
|||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn fabsf(x: f32) -> f32 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f32.abs` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::fabsf32(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: fabsf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
f32::from_bits(x.to_bits() & 0x7fffffff)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,12 @@ const TOINT: f64 = 1. / f64::EPSILON;
|
|||
/// Finds the nearest integer less than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn floor(x: f64) -> f64 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f64.floor` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::floorf64(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: floor,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
|
||||
{
|
||||
//use an alternative implementation on x86, because the
|
||||
|
|
|
|||
|
|
@ -5,14 +5,12 @@ use core::f32;
|
|||
/// Finds the nearest integer less than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn floorf(x: f32) -> f32 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f32.floor` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::floorf32(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: floorf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
let mut ui = x.to_bits();
|
||||
let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
|
||||
|
||||
|
|
|
|||
|
|
@ -74,18 +74,6 @@ macro_rules! div {
|
|||
};
|
||||
}
|
||||
|
||||
// FIXME: phase this out, to be replaced by the more flexible `select_implementation`
|
||||
macro_rules! llvm_intrinsically_optimized {
|
||||
(#[cfg($($clause:tt)*)] $e:expr) => {
|
||||
#[cfg(all(intrinsics_enabled, not(feature = "force-soft-floats"), $($clause)*))]
|
||||
{
|
||||
if true { // thwart the dead code lint
|
||||
$e
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Private modules
|
||||
#[macro_use]
|
||||
mod support;
|
||||
|
|
|
|||
|
|
@ -81,18 +81,12 @@ use core::f64;
|
|||
/// The square root of `x` (f64).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn sqrt(x: f64) -> f64 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f64.sqrt` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return if x < 0.0 {
|
||||
f64::NAN
|
||||
} else {
|
||||
unsafe { ::core::intrinsics::sqrtf64(x) }
|
||||
}
|
||||
}
|
||||
select_implementation! {
|
||||
name: sqrt,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
#[cfg(all(target_feature = "sse2", not(feature = "force-soft-floats")))]
|
||||
{
|
||||
// Note: This path is unlikely since LLVM will usually have already
|
||||
|
|
|
|||
|
|
@ -16,18 +16,12 @@
|
|||
/// The square root of `x` (f32).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn sqrtf(x: f32) -> f32 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f32.sqrt` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return if x < 0.0 {
|
||||
::core::f32::NAN
|
||||
} else {
|
||||
unsafe { ::core::intrinsics::sqrtf32(x) }
|
||||
}
|
||||
}
|
||||
select_implementation! {
|
||||
name: sqrtf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
#[cfg(all(target_feature = "sse", not(feature = "force-soft-floats")))]
|
||||
{
|
||||
// Note: This path is unlikely since LLVM will usually have already
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@ use core::f64;
|
|||
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn trunc(x: f64) -> f64 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f64.trunc` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::truncf64(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: trunc,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
let x1p120 = f64::from_bits(0x4770000000000000); // 0x1p120f === 2 ^ 120
|
||||
|
||||
let mut i: u64 = x.to_bits();
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@ use core::f32;
|
|||
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
pub fn truncf(x: f32) -> f32 {
|
||||
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
|
||||
// `f32.trunc` native instruction, so we can leverage this for both code size
|
||||
// and speed.
|
||||
llvm_intrinsically_optimized! {
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
return unsafe { ::core::intrinsics::truncf32(x) }
|
||||
}
|
||||
select_implementation! {
|
||||
name: truncf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120
|
||||
|
||||
let mut i: u32 = x.to_bits();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue