Skip to content

Commit 60826e7

Browse files
committed
[s390x] Fall back to scalar math for portable floating-point vector operations.
I've opened #501 to track the workarounds introduced here. Closes #498.
1 parent e47dfe3 commit 60826e7

File tree

5 files changed

+151
-5
lines changed

5 files changed

+151
-5
lines changed

coresimd/ppsv/codegen/abs.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
//! Vector absolute value
2-
2+
#![allow(dead_code)]
33
use coresimd::simd::*;
44

55
#[allow(improper_ctypes)]
66
extern "C" {
7+
#[link_name = "llvm.fabs.f32"]
8+
fn abs_f32(x: f32) -> f32;
9+
#[link_name = "llvm.fabs.f64"]
10+
fn abs_f64(x: f64) -> f64;
11+
712
#[link_name = "llvm.fabs.v2f32"]
813
fn abs_v2f32(x: f32x2) -> f32x2;
914
#[link_name = "llvm.fabs.v4f32"]
@@ -24,13 +29,42 @@ pub(crate) trait FloatAbs {
2429
fn abs(self) -> Self;
2530
}
2631

32+
trait RawAbs {
33+
fn raw_abs(self) -> Self;
34+
}
35+
36+
impl RawAbs for f32 {
37+
fn raw_abs(self) -> Self {
38+
unsafe { abs_f32(self) }
39+
}
40+
}
41+
42+
impl RawAbs for f64 {
43+
fn raw_abs(self) -> Self {
44+
unsafe { abs_f64(self) }
45+
}
46+
}
47+
48+
2749
macro_rules! impl_fabs {
2850
($id:ident : $fn:ident) => {
51+
#[cfg(not(target_arch = "s390x"))]
2952
impl FloatAbs for $id {
3053
fn abs(self) -> Self {
3154
unsafe { $fn(self) }
3255
}
3356
}
57+
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
58+
#[cfg(target_arch = "s390x")]
59+
impl FloatAbs for $id {
60+
fn abs(self) -> Self {
61+
let mut v = $id::splat(0.);
62+
for i in 0..$id::lanes() {
63+
v = v.replace(i, self.extract(i).raw_abs())
64+
}
65+
v
66+
}
67+
}
3468
};
3569
}
3670

coresimd/ppsv/codegen/cos.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
//! Exact vector cos
2-
2+
#![allow(dead_code)]
33
use coresimd::simd::*;
44

55
#[allow(improper_ctypes)]
66
extern "C" {
7+
#[link_name = "llvm.cos.f32"]
8+
fn cos_f32(x: f32) -> f32;
9+
#[link_name = "llvm.cos.f64"]
10+
fn cos_f64(x: f64) -> f64;
11+
712
#[link_name = "llvm.cos.v2f32"]
813
fn cos_v2f32(x: f32x2) -> f32x2;
914
#[link_name = "llvm.cos.v4f32"]
@@ -24,13 +29,43 @@ pub(crate) trait FloatCos {
2429
fn cos(self) -> Self;
2530
}
2631

32+
trait RawCos {
33+
fn raw_cos(self) -> Self;
34+
}
35+
36+
impl RawCos for f32 {
37+
fn raw_cos(self) -> Self {
38+
unsafe { cos_f32(self) }
39+
}
40+
}
41+
42+
impl RawCos for f64 {
43+
fn raw_cos(self) -> Self {
44+
unsafe { cos_f64(self) }
45+
}
46+
}
47+
48+
2749
macro_rules! impl_fcos {
2850
($id:ident : $fn:ident) => {
51+
#[cfg(not(target_arch = "s390x"))]
2952
impl FloatCos for $id {
3053
fn cos(self) -> Self {
3154
unsafe { $fn(self) }
3255
}
3356
}
57+
58+
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
59+
#[cfg(target_arch = "s390x")]
60+
impl FloatCos for $id {
61+
fn cos(self) -> Self {
62+
let mut v = $id::splat(0.);
63+
for i in 0..$id::lanes() {
64+
v = v.replace(i, self.extract(i).raw_cos())
65+
}
66+
v
67+
}
68+
}
3469
};
3570
}
3671

coresimd/ppsv/codegen/fma.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Vector fused multiply add
2-
2+
#![allow(dead_code)]
33
use coresimd::simd::*;
44

55
#[allow(improper_ctypes)]
@@ -26,11 +26,19 @@ pub(crate) trait FloatFma {
2626

2727
macro_rules! impl_fma {
2828
($id:ident : $fn:ident) => {
29+
#[cfg(not(target_arch = "s390x"))]
2930
impl FloatFma for $id {
3031
fn fma(self, y: Self, z: Self) -> Self {
3132
unsafe { $fn(self, y, z) }
3233
}
3334
}
35+
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
36+
#[cfg(target_arch = "s390x")]
37+
impl FloatFma for $id {
38+
fn fma(self, y: Self, z: Self) -> Self {
39+
self * y + z
40+
}
41+
}
3442
};
3543
}
3644

coresimd/ppsv/codegen/sin.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
//! Exact vector sin
2-
2+
#![allow(dead_code)]
33
use coresimd::simd::*;
44

55
#[allow(improper_ctypes)]
66
extern "C" {
7+
#[link_name = "llvm.sin.f32"]
8+
fn sin_f32(x: f32) -> f32;
9+
#[link_name = "llvm.sin.f64"]
10+
fn sin_f64(x: f64) -> f64;
11+
712
#[link_name = "llvm.sin.v2f32"]
813
fn sin_v2f32(x: f32x2) -> f32x2;
914
#[link_name = "llvm.sin.v4f32"]
@@ -24,13 +29,43 @@ pub(crate) trait FloatSin {
2429
fn sin(self) -> Self;
2530
}
2631

32+
trait RawSin {
33+
fn raw_sin(self) -> Self;
34+
}
35+
36+
impl RawSin for f32 {
37+
fn raw_sin(self) -> Self {
38+
unsafe { sin_f32(self) }
39+
}
40+
}
41+
42+
impl RawSin for f64 {
43+
fn raw_sin(self) -> Self {
44+
unsafe { sin_f64(self) }
45+
}
46+
}
47+
2748
macro_rules! impl_fsin {
2849
($id:ident : $fn:ident) => {
50+
#[cfg(not(target_arch = "s390x"))]
2951
impl FloatSin for $id {
3052
fn sin(self) -> Self {
3153
unsafe { $fn(self) }
3254
}
3355
}
56+
57+
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
58+
#[cfg(target_arch = "s390x")]
59+
impl FloatSin for $id {
60+
fn sin(self) -> Self {
61+
let mut v = $id::splat(0.);
62+
for i in 0..$id::lanes() {
63+
v = v.replace(i, self.extract(i).raw_sin())
64+
}
65+
v
66+
}
67+
}
68+
3469
};
3570
}
3671

coresimd/ppsv/codegen/sqrt.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
//! Exact vector square-root
2-
2+
#![allow(dead_code)]
33
use coresimd::simd::*;
44

55
#[allow(improper_ctypes)]
66
extern "C" {
7+
#[link_name = "llvm.sqrt.f32"]
8+
fn sqrt_f32(x: f32) -> f32;
9+
#[link_name = "llvm.sqrt.f64"]
10+
fn sqrt_f64(x: f64) -> f64;
11+
712
#[link_name = "llvm.sqrt.v2f32"]
813
fn sqrt_v2f32(x: f32x2) -> f32x2;
914
#[link_name = "llvm.sqrt.v4f32"]
@@ -24,13 +29,42 @@ pub(crate) trait FloatSqrt {
2429
fn sqrt(self) -> Self;
2530
}
2631

32+
trait RawSqrt {
33+
fn raw_sqrt(self) -> Self;
34+
}
35+
36+
impl RawSqrt for f32 {
37+
fn raw_sqrt(self) -> Self {
38+
unsafe { sqrt_f32(self) }
39+
}
40+
}
41+
42+
impl RawSqrt for f64 {
43+
fn raw_sqrt(self) -> Self {
44+
unsafe { sqrt_f64(self) }
45+
}
46+
}
47+
2748
macro_rules! impl_fsqrt {
2849
($id:ident : $fn:ident) => {
50+
#[cfg(not(target_arch = "s390x"))]
2951
impl FloatSqrt for $id {
3052
fn sqrt(self) -> Self {
3153
unsafe { $fn(self) }
3254
}
3355
}
56+
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
57+
#[cfg(target_arch = "s390x")]
58+
impl FloatSqrt for $id {
59+
fn sqrt(self) -> Self {
60+
let mut v = $id::splat(0.);
61+
for i in 0..$id::lanes() {
62+
v = v.replace(i, self.extract(i).raw_sqrt());
63+
}
64+
v
65+
}
66+
}
67+
3468
};
3569
}
3670

0 commit comments

Comments
 (0)