Skip to content

Commit 586962f

Browse files
committed
Move architecture-specific code to src/math/arch
Move the code and call into its new location with `select_implementation`.
1 parent ceb26d8 commit 586962f

File tree

7 files changed

+261
-249
lines changed

7 files changed

+261
-249
lines changed

src/math/arch/i586.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//! Architecture-specific support for x86-32 without SSE2
2+
3+
use super::super::fabs;
4+
5+
/// Use an alternative implementation on x86, because the
6+
/// main implementation fails with the x87 FPU used by
7+
/// debian i386, probably due to excess precision issues.
8+
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
9+
pub fn ceil(x: f64) -> f64 {
10+
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
11+
let truncated = x as i64 as f64;
12+
if truncated < x {
13+
return truncated + 1.0;
14+
} else {
15+
return truncated;
16+
}
17+
} else {
18+
return x;
19+
}
20+
}
21+
22+
/// Use an alternative implementation on x86, because the
23+
/// main implementation fails with the x87 FPU used by
24+
/// debian i386, probably due to excess precision issues.
25+
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
26+
pub fn floor(x: f64) -> f64 {
27+
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
28+
let truncated = x as i64 as f64;
29+
if truncated > x {
30+
return truncated - 1.0;
31+
} else {
32+
return truncated;
33+
}
34+
} else {
35+
return x;
36+
}
37+
}

src/math/arch/i686.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! Architecture-specific support for x86-32 and x86-64 with SSE2
2+
3+
#![cfg(not(feature = "force-soft-floats"))]
4+
5+
#[cfg(target_arch = "x86")]
6+
use core::arch::x86::*;
7+
#[cfg(target_arch = "x86_64")]
8+
use core::arch::x86_64::*;
9+
10+
pub fn sqrtf(x: f32) -> f32 {
11+
unsafe {
12+
let m = _mm_set_ss(x);
13+
let m_sqrt = _mm_sqrt_ss(m);
14+
_mm_cvtss_f32(m_sqrt)
15+
}
16+
}
17+
18+
pub fn sqrt(x: f64) -> f64 {
19+
unsafe {
20+
let m = _mm_set_sd(x);
21+
let m_sqrt = _mm_sqrt_pd(m);
22+
_mm_cvtsd_f64(m_sqrt)
23+
}
24+
}

src/math/arch/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,22 @@
77
88
#[cfg(intrinsics_enabled)]
99
pub mod intrinsics;
10+
11+
// Most implementations should be defined here, to ensure they are not made available when
12+
// soft floats are required.
13+
#[cfg(arch_enabled)]
14+
cfg_if! {
15+
if #[cfg(target_feature = "sse2")] {
16+
mod i686;
17+
pub use i686::{sqrt, sqrtf};
18+
}
19+
}
20+
21+
// There are certain architecture-specific implementations that are needed for correctness
22+
// even with `force-soft-float`. These are configured here.
23+
cfg_if! {
24+
if #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] {
25+
mod i586;
26+
pub use i586::{ceil, floor};
27+
}
28+
}

src/math/ceil.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,11 @@ const TOINT: f64 = 1. / f64::EPSILON;
1010
pub fn ceil(x: f64) -> f64 {
1111
select_implementation! {
1212
name: ceil,
13+
use_arch_required: all(target_arch = "x86", not(target_feature = "sse2")),
1314
use_intrinsic: target_arch = "wasm32",
1415
args: x,
1516
}
1617

17-
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
18-
{
19-
//use an alternative implementation on x86, because the
20-
//main implementation fails with the x87 FPU used by
21-
//debian i386, probably due to excess precision issues.
22-
//basic implementation taken from https://github.com/rust-lang/libm/issues/219
23-
use super::fabs;
24-
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
25-
let truncated = x as i64 as f64;
26-
if truncated < x {
27-
return truncated + 1.0;
28-
} else {
29-
return truncated;
30-
}
31-
} else {
32-
return x;
33-
}
34-
}
3518
let u: u64 = x.to_bits();
3619
let e: i64 = (u >> 52 & 0x7ff) as i64;
3720
let y: f64;

src/math/floor.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,11 @@ const TOINT: f64 = 1. / f64::EPSILON;
1010
pub fn floor(x: f64) -> f64 {
1111
select_implementation! {
1212
name: floor,
13+
use_arch_required: all(target_arch = "x86", not(target_feature = "sse2")),
1314
use_intrinsic: target_arch = "wasm32",
1415
args: x,
1516
}
1617

17-
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
18-
{
19-
//use an alternative implementation on x86, because the
20-
//main implementation fails with the x87 FPU used by
21-
//debian i386, probably due to excess precision issues.
22-
//basic implementation taken from https://github.com/rust-lang/libm/issues/219
23-
use super::fabs;
24-
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
25-
let truncated = x as i64 as f64;
26-
if truncated > x {
27-
return truncated - 1.0;
28-
} else {
29-
return truncated;
30-
}
31-
} else {
32-
return x;
33-
}
34-
}
3518
let ui = x.to_bits();
3619
let e = ((ui >> 52) & 0x7ff) as i32;
3720

0 commit comments

Comments
 (0)