Skip to content

Commit 75009a8

Browse files
committed
add float math: sin, cos
1 parent 909e278 commit 75009a8

File tree

4 files changed

+140
-1
lines changed

4 files changed

+140
-1
lines changed

coresimd/ppsv/api/float_math.rs

+52-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ macro_rules! impl_float_math {
3939
use coresimd::ppsv::codegen::fma::FloatFma;
4040
FloatFma::fma(self, y, z)
4141
}
42+
43+
/// Sin
44+
#[inline(always)]
45+
pub fn sin(self) -> Self {
46+
use coresimd::ppsv::codegen::sin::FloatSin;
47+
FloatSin::sin(self)
48+
}
49+
50+
/// Cos
51+
#[inline]
52+
pub fn cos(self) -> Self {
53+
use coresimd::ppsv::codegen::cos::FloatCos;
54+
FloatCos::cos(self)
55+
}
4256
}
4357
};
4458
}
@@ -54,6 +68,14 @@ macro_rules! test_float_math {
5468
}
5569
}
5670

71+
fn pi() -> $elem_ty {
72+
match ::mem::size_of::<$elem_ty>() {
73+
4 => ::std::f32::consts::PI as $elem_ty,
74+
8 => ::std::f64::consts::PI as $elem_ty,
75+
_ => unreachable!(),
76+
}
77+
}
78+
5779
#[test]
5880
fn abs() {
5981
use coresimd::simd::*;
@@ -126,7 +148,36 @@ macro_rules! test_float_math {
126148

127149
assert_eq!(f, t.fma(t, z));
128150
assert_eq!(f, t.fma(o, t));
129-
assert_eq!(t3, t.fma(t, o));
151+
assert_eq!(t3, t.fma(o, o));
152+
}
153+
154+
#[test]
155+
fn sin() {
156+
use coresimd::simd::*;
157+
let z = $id::splat(0 as $elem_ty);
158+
let p = $id::splat(pi() as $elem_ty);
159+
let ph = $id::splat(pi() as $elem_ty / 2.);
160+
let o_r = $id::splat((pi() as $elem_ty / 2.).sin());
161+
let z_r = $id::splat((pi() as $elem_ty).sin());
162+
163+
assert_eq!(z, z.sin());
164+
assert_eq!(o_r, ph.sin());
165+
assert_eq!(z_r, p.sin());
166+
}
167+
168+
#[test]
169+
fn cos() {
170+
use coresimd::simd::*;
171+
let z = $id::splat(0 as $elem_ty);
172+
let o = $id::splat(1 as $elem_ty);
173+
let p = $id::splat(pi() as $elem_ty);
174+
let ph = $id::splat(pi() as $elem_ty / 2.);
175+
let z_r = $id::splat((pi() as $elem_ty / 2.).cos());
176+
let o_r = $id::splat((pi() as $elem_ty).cos());
177+
178+
assert_eq!(o, z.cos());
179+
assert_eq!(z_r, ph.cos());
180+
assert_eq!(o_r, p.cos());
130181
}
131182
};
132183
}

coresimd/ppsv/codegen/cos.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Exact vector cos
2+
3+
use coresimd::simd::*;
4+
5+
#[allow(improper_ctypes)]
6+
extern "C" {
7+
#[link_name = "llvm.cos.v2f32"]
8+
fn cos_v2f32(x: f32x2) -> f32x2;
9+
#[link_name = "llvm.cos.v4f32"]
10+
fn cos_v4f32(x: f32x4) -> f32x4;
11+
#[link_name = "llvm.cos.v8f32"]
12+
fn cos_v8f32(x: f32x8) -> f32x8;
13+
#[link_name = "llvm.cos.v16f32"]
14+
fn cos_v16f32(x: f32x16) -> f32x16;
15+
#[link_name = "llvm.cos.v2f64"]
16+
fn cos_v2f64(x: f64x2) -> f64x2;
17+
#[link_name = "llvm.cos.v4f64"]
18+
fn cos_v4f64(x: f64x4) -> f64x4;
19+
#[link_name = "llvm.cos.v8f64"]
20+
fn cos_v8f64(x: f64x8) -> f64x8;
21+
}
22+
23+
pub(crate) trait FloatCos {
24+
fn cos(self) -> Self;
25+
}
26+
27+
macro_rules! impl_fcos {
28+
($id:ident: $fn:ident) => {
29+
impl FloatCos for $id {
30+
fn cos(self) -> Self {
31+
unsafe { $fn(self) }
32+
}
33+
}
34+
}
35+
}
36+
37+
impl_fcos!(f32x2: cos_v2f32);
38+
impl_fcos!(f32x4: cos_v4f32);
39+
impl_fcos!(f32x8: cos_v8f32);
40+
impl_fcos!(f32x16: cos_v16f32);
41+
impl_fcos!(f64x2: cos_v2f64);
42+
impl_fcos!(f64x4: cos_v4f64);
43+
impl_fcos!(f64x8: cos_v8f64);

coresimd/ppsv/codegen/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ pub mod masks_reductions;
88
pub mod sqrt;
99
pub mod abs;
1010
pub mod fma;
11+
pub mod sin;
12+
pub mod cos;

coresimd/ppsv/codegen/sin.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Exact vector sin
2+
3+
use coresimd::simd::*;
4+
5+
#[allow(improper_ctypes)]
6+
extern "C" {
7+
#[link_name = "llvm.sin.v2f32"]
8+
fn sin_v2f32(x: f32x2) -> f32x2;
9+
#[link_name = "llvm.sin.v4f32"]
10+
fn sin_v4f32(x: f32x4) -> f32x4;
11+
#[link_name = "llvm.sin.v8f32"]
12+
fn sin_v8f32(x: f32x8) -> f32x8;
13+
#[link_name = "llvm.sin.v16f32"]
14+
fn sin_v16f32(x: f32x16) -> f32x16;
15+
#[link_name = "llvm.sin.v2f64"]
16+
fn sin_v2f64(x: f64x2) -> f64x2;
17+
#[link_name = "llvm.sin.v4f64"]
18+
fn sin_v4f64(x: f64x4) -> f64x4;
19+
#[link_name = "llvm.sin.v8f64"]
20+
fn sin_v8f64(x: f64x8) -> f64x8;
21+
}
22+
23+
pub(crate) trait FloatSin {
24+
fn sin(self) -> Self;
25+
}
26+
27+
macro_rules! impl_fsin {
28+
($id:ident: $fn:ident) => {
29+
impl FloatSin for $id {
30+
fn sin(self) -> Self {
31+
unsafe { $fn(self) }
32+
}
33+
}
34+
}
35+
}
36+
37+
impl_fsin!(f32x2: sin_v2f32);
38+
impl_fsin!(f32x4: sin_v4f32);
39+
impl_fsin!(f32x8: sin_v8f32);
40+
impl_fsin!(f32x16: sin_v16f32);
41+
impl_fsin!(f64x2: sin_v2f64);
42+
impl_fsin!(f64x4: sin_v4f64);
43+
impl_fsin!(f64x8: sin_v8f64);

0 commit comments

Comments
 (0)