Replace "intrinsic" config with "arch" config
WASM is the only architecture we use `intrinsics::` for. We probably don't want to do this for any other architectures since it is better to use assembly, or work toward getting the functions available in `core`. To more accurately reflect the relationship between arch and intrinsics, make wasm32 an `arch` module and call the intrinsics from there.
This commit is contained in:
parent
c574145577
commit
f3ad123a09
14 changed files with 37 additions and 50 deletions
|
|
@ -108,14 +108,14 @@
|
|||
"sources": [
|
||||
"src/libm_helper.rs",
|
||||
"src/math/arch/i586.rs",
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/ceil.rs"
|
||||
],
|
||||
"type": "f64"
|
||||
},
|
||||
"ceilf": {
|
||||
"sources": [
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/ceilf.rs"
|
||||
],
|
||||
"type": "f32"
|
||||
|
|
@ -258,7 +258,7 @@
|
|||
"fabs": {
|
||||
"sources": [
|
||||
"src/libm_helper.rs",
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/fabs.rs",
|
||||
"src/math/generic/fabs.rs"
|
||||
],
|
||||
|
|
@ -266,7 +266,7 @@
|
|||
},
|
||||
"fabsf": {
|
||||
"sources": [
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/fabsf.rs",
|
||||
"src/math/generic/fabs.rs"
|
||||
],
|
||||
|
|
@ -303,14 +303,14 @@
|
|||
"sources": [
|
||||
"src/libm_helper.rs",
|
||||
"src/math/arch/i586.rs",
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/floor.rs"
|
||||
],
|
||||
"type": "f64"
|
||||
},
|
||||
"floorf": {
|
||||
"sources": [
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/floorf.rs"
|
||||
],
|
||||
"type": "f32"
|
||||
|
|
@ -683,7 +683,7 @@
|
|||
"sources": [
|
||||
"src/libm_helper.rs",
|
||||
"src/math/arch/i686.rs",
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/sqrt.rs"
|
||||
],
|
||||
"type": "f64"
|
||||
|
|
@ -691,7 +691,7 @@
|
|||
"sqrtf": {
|
||||
"sources": [
|
||||
"src/math/arch/i686.rs",
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/sqrtf.rs"
|
||||
],
|
||||
"type": "f32"
|
||||
|
|
@ -738,14 +738,14 @@
|
|||
"trunc": {
|
||||
"sources": [
|
||||
"src/libm_helper.rs",
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/trunc.rs"
|
||||
],
|
||||
"type": "f64"
|
||||
},
|
||||
"truncf": {
|
||||
"sources": [
|
||||
"src/math/arch/intrinsics.rs",
|
||||
"src/math/arch/wasm32.rs",
|
||||
"src/math/truncf.rs"
|
||||
],
|
||||
"type": "f32"
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@
|
|||
//! is used when calling the function directly. This helps anyone who uses `libm` directly, as
|
||||
//! well as improving things when these routines are called as part of other implementations.
|
||||
|
||||
#[cfg(intrinsics_enabled)]
|
||||
pub mod intrinsics;
|
||||
|
||||
// Most implementations should be defined here, to ensure they are not made available when
|
||||
// soft floats are required.
|
||||
#[cfg(arch_enabled)]
|
||||
cfg_if! {
|
||||
if #[cfg(target_feature = "sse2")] {
|
||||
if #[cfg(all(target_arch = "wasm32", intrinsics_enabled))] {
|
||||
mod wasm32;
|
||||
pub use wasm32::{ceil, ceilf, fabs, fabsf, floor, floorf, sqrt, sqrtf, trunc, truncf};
|
||||
} else if #[cfg(target_feature = "sse2")] {
|
||||
mod i686;
|
||||
pub use i686::{sqrt, sqrtf};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// Config is needed for times when this module is available but we don't call everything
|
||||
#![allow(dead_code)]
|
||||
//! Wasm asm is not stable; just use intrinsics for operations that have asm routine equivalents.
|
||||
//!
|
||||
//! Note that we need to be absolutely certain that everything here lowers to assembly operations,
|
||||
//! otherwise libcalls will be recursive.
|
||||
|
||||
pub fn ceil(x: f64) -> f64 {
|
||||
// SAFETY: safe intrinsic with no preconditions
|
||||
|
|
@ -10,8 +10,8 @@ const TOINT: f64 = 1. / f64::EPSILON;
|
|||
pub fn ceil(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: ceil,
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
use_arch_required: all(target_arch = "x86", not(target_feature = "sse2")),
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use core::f32;
|
|||
pub fn ceilf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: ceilf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
pub fn fabs(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: fabs,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
pub fn fabsf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: fabsf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ const TOINT: f64 = 1. / f64::EPSILON;
|
|||
pub fn floor(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: floor,
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
use_arch_required: all(target_arch = "x86", not(target_feature = "sse2")),
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use core::f32;
|
|||
pub fn floorf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: floorf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,8 +83,10 @@ use core::f64;
|
|||
pub fn sqrt(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: sqrt,
|
||||
use_arch: target_feature = "sse2",
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: any(
|
||||
all(target_arch = "wasm32", intrinsics_enabled),
|
||||
target_feature = "sse2"
|
||||
),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
pub fn sqrtf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: sqrtf,
|
||||
use_arch: target_feature = "sse2",
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: any(
|
||||
all(target_arch = "wasm32", intrinsics_enabled),
|
||||
target_feature = "sse2"
|
||||
),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,13 +39,8 @@ macro_rules! cfg_if {
|
|||
(@__identity $($tokens:tt)*) => { $($tokens)* };
|
||||
}
|
||||
|
||||
/// Choose among using an intrinsic, an arch-specific implementation, and the function body.
|
||||
/// Returns directly if the intrinsic or arch is used, otherwise continue with the rest of the
|
||||
/// function.
|
||||
///
|
||||
/// Specify a `use_intrinsic` meta field if the intrinsic is (1) available on the platforms (i.e.
|
||||
/// LLVM lowers it without libcalls that may recurse), (2) it is likely to be more performant.
|
||||
/// Intrinsics require wrappers in the `math::arch::intrinsics` module.
|
||||
/// Choose between using an arch-specific implementation and the function body. Returns directly
|
||||
/// if the arch implementation is used, otherwise continue with the rest of the function.
|
||||
///
|
||||
/// Specify a `use_arch` meta field if an architecture-specific implementation is provided.
|
||||
/// These live in the `math::arch::some_target_arch` module.
|
||||
|
|
@ -53,8 +48,7 @@ macro_rules! cfg_if {
|
|||
/// Specify a `use_arch_required` meta field if something architecture-specific must be used
|
||||
/// regardless of feature configuration (`force-soft-floats`).
|
||||
///
|
||||
/// The passed meta options do not need to account for relevant Cargo features
|
||||
/// (`unstable-intrinsics`, `arch`, `force-soft-floats`), this macro handles that part.
|
||||
/// The passed meta options do not need to account for the `arch` target feature.
|
||||
macro_rules! select_implementation {
|
||||
(
|
||||
name: $fn_name:ident,
|
||||
|
|
@ -64,15 +58,12 @@ macro_rules! select_implementation {
|
|||
// Configuration meta for when to use the arch module regardless of whether softfloats
|
||||
// have been requested.
|
||||
$( use_arch_required: $use_arch_required:meta, )?
|
||||
// Configuration meta for when to call intrinsics and let LLVM figure it out
|
||||
$( use_intrinsic: $use_intrinsic:meta, )?
|
||||
args: $($arg:ident),+ ,
|
||||
) => {
|
||||
// FIXME: these use paths that are a pretty fragile (`super`). We should figure out
|
||||
// something better w.r.t. how this is vendored into compiler-builtins.
|
||||
|
||||
// However, we do need a few things from `arch` that are used even with soft floats.
|
||||
//
|
||||
select_implementation! {
|
||||
@cfg $($use_arch_required)?;
|
||||
if true {
|
||||
|
|
@ -89,16 +80,6 @@ macro_rules! select_implementation {
|
|||
return super::arch::$fn_name( $($arg),+ );
|
||||
}
|
||||
}
|
||||
|
||||
// Never use intrinsics if we are forcing soft floats, and only enable with the
|
||||
// `unstable-intrinsics` feature.
|
||||
#[cfg(intrinsics_enabled)]
|
||||
select_implementation! {
|
||||
@cfg $( $use_intrinsic )?;
|
||||
if true {
|
||||
return super::arch::intrinsics::$fn_name( $($arg),+ );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Coalesce helper to construct an expression only if a config is provided
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use core::f64;
|
|||
pub fn trunc(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: trunc,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use core::f32;
|
|||
pub fn truncf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: truncf,
|
||||
use_intrinsic: target_arch = "wasm32",
|
||||
use_arch: all(target_arch = "wasm32", intrinsics_enabled),
|
||||
args: x,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue