Skip to content

Commit

Permalink
[s390x] Fall back to scalar math for portable floating-point vector o…
Browse files Browse the repository at this point in the history
…perations.

I've opened rust-lang#501 to track the workarounds introduced here.

Closes rust-lang#498.
  • Loading branch information
gnzlbg committed Jun 26, 2018
1 parent e47dfe3 commit 60826e7
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 5 deletions.
36 changes: 35 additions & 1 deletion coresimd/ppsv/codegen/abs.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! Vector absolute value

#![allow(dead_code)]
use coresimd::simd::*;

#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.fabs.f32"]
fn abs_f32(x: f32) -> f32;
#[link_name = "llvm.fabs.f64"]
fn abs_f64(x: f64) -> f64;

#[link_name = "llvm.fabs.v2f32"]
fn abs_v2f32(x: f32x2) -> f32x2;
#[link_name = "llvm.fabs.v4f32"]
Expand All @@ -24,13 +29,42 @@ pub(crate) trait FloatAbs {
fn abs(self) -> Self;
}

trait RawAbs {
fn raw_abs(self) -> Self;
}

impl RawAbs for f32 {
fn raw_abs(self) -> Self {
unsafe { abs_f32(self) }
}
}

impl RawAbs for f64 {
fn raw_abs(self) -> Self {
unsafe { abs_f64(self) }
}
}


macro_rules! impl_fabs {
($id:ident : $fn:ident) => {
#[cfg(not(target_arch = "s390x"))]
impl FloatAbs for $id {
fn abs(self) -> Self {
unsafe { $fn(self) }
}
}
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
#[cfg(target_arch = "s390x")]
impl FloatAbs for $id {
fn abs(self) -> Self {
let mut v = $id::splat(0.);
for i in 0..$id::lanes() {
v = v.replace(i, self.extract(i).raw_abs())
}
v
}
}
};
}

Expand Down
37 changes: 36 additions & 1 deletion coresimd/ppsv/codegen/cos.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! Exact vector cos

#![allow(dead_code)]
use coresimd::simd::*;

#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.cos.f32"]
fn cos_f32(x: f32) -> f32;
#[link_name = "llvm.cos.f64"]
fn cos_f64(x: f64) -> f64;

#[link_name = "llvm.cos.v2f32"]
fn cos_v2f32(x: f32x2) -> f32x2;
#[link_name = "llvm.cos.v4f32"]
Expand All @@ -24,13 +29,43 @@ pub(crate) trait FloatCos {
fn cos(self) -> Self;
}

trait RawCos {
fn raw_cos(self) -> Self;
}

impl RawCos for f32 {
fn raw_cos(self) -> Self {
unsafe { cos_f32(self) }
}
}

impl RawCos for f64 {
fn raw_cos(self) -> Self {
unsafe { cos_f64(self) }
}
}


macro_rules! impl_fcos {
($id:ident : $fn:ident) => {
#[cfg(not(target_arch = "s390x"))]
impl FloatCos for $id {
fn cos(self) -> Self {
unsafe { $fn(self) }
}
}

// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
#[cfg(target_arch = "s390x")]
impl FloatCos for $id {
fn cos(self) -> Self {
let mut v = $id::splat(0.);
for i in 0..$id::lanes() {
v = v.replace(i, self.extract(i).raw_cos())
}
v
}
}
};
}

Expand Down
10 changes: 9 additions & 1 deletion coresimd/ppsv/codegen/fma.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Vector fused multiply add

#![allow(dead_code)]
use coresimd::simd::*;

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

macro_rules! impl_fma {
($id:ident : $fn:ident) => {
#[cfg(not(target_arch = "s390x"))]
impl FloatFma for $id {
fn fma(self, y: Self, z: Self) -> Self {
unsafe { $fn(self, y, z) }
}
}
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
#[cfg(target_arch = "s390x")]
impl FloatFma for $id {
fn fma(self, y: Self, z: Self) -> Self {
self * y + z
}
}
};
}

Expand Down
37 changes: 36 additions & 1 deletion coresimd/ppsv/codegen/sin.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! Exact vector sin

#![allow(dead_code)]
use coresimd::simd::*;

#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.sin.f32"]
fn sin_f32(x: f32) -> f32;
#[link_name = "llvm.sin.f64"]
fn sin_f64(x: f64) -> f64;

#[link_name = "llvm.sin.v2f32"]
fn sin_v2f32(x: f32x2) -> f32x2;
#[link_name = "llvm.sin.v4f32"]
Expand All @@ -24,13 +29,43 @@ pub(crate) trait FloatSin {
fn sin(self) -> Self;
}

trait RawSin {
fn raw_sin(self) -> Self;
}

impl RawSin for f32 {
fn raw_sin(self) -> Self {
unsafe { sin_f32(self) }
}
}

impl RawSin for f64 {
fn raw_sin(self) -> Self {
unsafe { sin_f64(self) }
}
}

macro_rules! impl_fsin {
($id:ident : $fn:ident) => {
#[cfg(not(target_arch = "s390x"))]
impl FloatSin for $id {
fn sin(self) -> Self {
unsafe { $fn(self) }
}
}

// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
#[cfg(target_arch = "s390x")]
impl FloatSin for $id {
fn sin(self) -> Self {
let mut v = $id::splat(0.);
for i in 0..$id::lanes() {
v = v.replace(i, self.extract(i).raw_sin())
}
v
}
}

};
}

Expand Down
36 changes: 35 additions & 1 deletion coresimd/ppsv/codegen/sqrt.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! Exact vector square-root

#![allow(dead_code)]
use coresimd::simd::*;

#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.sqrt.f32"]
fn sqrt_f32(x: f32) -> f32;
#[link_name = "llvm.sqrt.f64"]
fn sqrt_f64(x: f64) -> f64;

#[link_name = "llvm.sqrt.v2f32"]
fn sqrt_v2f32(x: f32x2) -> f32x2;
#[link_name = "llvm.sqrt.v4f32"]
Expand All @@ -24,13 +29,42 @@ pub(crate) trait FloatSqrt {
fn sqrt(self) -> Self;
}

trait RawSqrt {
fn raw_sqrt(self) -> Self;
}

impl RawSqrt for f32 {
fn raw_sqrt(self) -> Self {
unsafe { sqrt_f32(self) }
}
}

impl RawSqrt for f64 {
fn raw_sqrt(self) -> Self {
unsafe { sqrt_f64(self) }
}
}

macro_rules! impl_fsqrt {
($id:ident : $fn:ident) => {
#[cfg(not(target_arch = "s390x"))]
impl FloatSqrt for $id {
fn sqrt(self) -> Self {
unsafe { $fn(self) }
}
}
// FIXME: https://github.com/rust-lang-nursery/stdsimd/issues/501
#[cfg(target_arch = "s390x")]
impl FloatSqrt for $id {
fn sqrt(self) -> Self {
let mut v = $id::splat(0.);
for i in 0..$id::lanes() {
v = v.replace(i, self.extract(i).raw_sqrt());
}
v
}
}

};
}

Expand Down

0 comments on commit 60826e7

Please sign in to comment.