Skip to content

Commit ffedbe5

Browse files
committed
Add rounding functions
1 parent 4872901 commit ffedbe5

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed

crates/core_simd/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![no_std]
2-
#![feature(repr_simd, platform_intrinsics)]
2+
#![feature(repr_simd, platform_intrinsics, link_llvm_intrinsics, simd_ffi)]
33
#![warn(missing_docs)]
44
//! Portable SIMD module.
55
@@ -56,3 +56,5 @@ mod vectors_mask128;
5656
pub use vectors_mask128::*;
5757
mod vectors_masksize;
5858
pub use vectors_masksize::*;
59+
60+
mod round;

crates/core_simd/src/round.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
macro_rules! implement {
2+
{
3+
impl $type:ident {
4+
floor = $floor_intrinsic:literal,
5+
ceil = $ceil_intrinsic:literal,
6+
round = $round_intrinsic:literal,
7+
trunc = $trunc_intrinsic:literal,
8+
}
9+
} => {
10+
mod $type {
11+
#[allow(improper_ctypes)]
12+
extern "C" {
13+
#[link_name = $floor_intrinsic]
14+
fn floor_intrinsic(x: crate::$type) -> crate::$type;
15+
#[link_name = $ceil_intrinsic]
16+
fn ceil_intrinsic(x: crate::$type) -> crate::$type;
17+
#[link_name = $round_intrinsic]
18+
fn round_intrinsic(x: crate::$type) -> crate::$type;
19+
#[link_name = $trunc_intrinsic]
20+
fn trunc_intrinsic(x: crate::$type) -> crate::$type;
21+
}
22+
23+
impl crate::$type {
24+
/// Returns the largest integer less than or equal to each lane.
25+
#[must_use = "method returns a new vector and does not mutate the original value"]
26+
#[inline]
27+
pub fn floor(self) -> Self {
28+
unsafe { floor_intrinsic(self) }
29+
}
30+
31+
/// Returns the smallest integer greater than or equal to each lane.
32+
#[must_use = "method returns a new vector and does not mutate the original value"]
33+
#[inline]
34+
pub fn ceil(self) -> Self {
35+
unsafe { ceil_intrinsic(self) }
36+
}
37+
38+
/// Returns the nearest integer to each lane. Round half-way cases away from 0.0.
39+
#[must_use = "method returns a new vector and does not mutate the original value"]
40+
#[inline]
41+
pub fn round(self) -> Self {
42+
unsafe { round_intrinsic(self) }
43+
}
44+
45+
/// Returns the integer part of each lane.
46+
#[must_use = "method returns a new vector and does not mutate the original value"]
47+
#[inline]
48+
pub fn trunc(self) -> Self {
49+
unsafe { trunc_intrinsic(self) }
50+
}
51+
52+
/// Returns the fractional part of each lane.
53+
#[must_use = "method returns a new vector and does not mutate the original value"]
54+
#[inline]
55+
pub fn fract(self) -> Self {
56+
self - self.trunc()
57+
}
58+
}
59+
}
60+
}
61+
}
62+
63+
implement! {
64+
impl f32x2 {
65+
floor = "llvm.floor.v2f32",
66+
ceil = "llvm.ceil.v2f32",
67+
round = "llvm.round.v2f32",
68+
trunc = "llvm.trunc.v2f32",
69+
}
70+
}
71+
72+
implement! {
73+
impl f32x4 {
74+
floor = "llvm.floor.v4f32",
75+
ceil = "llvm.ceil.v4f32",
76+
round = "llvm.round.v4f32",
77+
trunc = "llvm.trunc.v4f32",
78+
}
79+
}
80+
81+
implement! {
82+
impl f32x8 {
83+
floor = "llvm.floor.v8f32",
84+
ceil = "llvm.ceil.v8f32",
85+
round = "llvm.round.v8f32",
86+
trunc = "llvm.trunc.v8f32",
87+
}
88+
}
89+
90+
implement! {
91+
impl f32x16 {
92+
floor = "llvm.floor.v16f32",
93+
ceil = "llvm.ceil.v16f32",
94+
round = "llvm.round.v16f32",
95+
trunc = "llvm.trunc.v16f32",
96+
}
97+
}
98+
99+
implement! {
100+
impl f64x2 {
101+
floor = "llvm.floor.v2f64",
102+
ceil = "llvm.ceil.v2f64",
103+
round = "llvm.round.v2f64",
104+
trunc = "llvm.trunc.v2f64",
105+
}
106+
}
107+
108+
implement! {
109+
impl f64x4 {
110+
floor = "llvm.floor.v4f64",
111+
ceil = "llvm.ceil.v4f64",
112+
round = "llvm.round.v4f64",
113+
trunc = "llvm.trunc.v4f64",
114+
}
115+
}
116+
117+
implement! {
118+
impl f64x8 {
119+
floor = "llvm.floor.v8f64",
120+
ceil = "llvm.ceil.v8f64",
121+
round = "llvm.round.v8f64",
122+
trunc = "llvm.trunc.v8f64",
123+
}
124+
}

0 commit comments

Comments
 (0)