From 75fdacde1ce6da3a93058a9fca248bfaf2611cd3 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 11 Oct 2020 13:22:26 -0400 Subject: [PATCH] Add rounding to integers --- crates/core_simd/src/round.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs index 43285cdd3f7f..6a03f7f81768 100644 --- a/crates/core_simd/src/round.rs +++ b/crates/core_simd/src/round.rs @@ -1,10 +1,12 @@ macro_rules! implement { { impl $type:ident { + int_type = $int_type:ident, floor = $floor_intrinsic:literal, ceil = $ceil_intrinsic:literal, round = $round_intrinsic:literal, trunc = $trunc_intrinsic:literal, + round_to_int = $round_to_int_intrinsic:literal, } } => { mod $type { @@ -18,6 +20,8 @@ macro_rules! implement { fn round_intrinsic(x: crate::$type) -> crate::$type; #[link_name = $trunc_intrinsic] fn trunc_intrinsic(x: crate::$type) -> crate::$type; + #[link_name = $round_to_int_intrinsic] + fn round_to_int_intrinsic(x: crate::$type) -> crate::$int_type; } impl crate::$type { @@ -55,6 +59,13 @@ macro_rules! implement { pub fn fract(self) -> Self { self - self.trunc() } + + /// Returns the nearest integer to each lane. Round half-way cases away from 0.0. + #[must_use = "method returns a new vector and does not mutate the original value"] + #[inline] + pub fn round_to_int(self) -> crate::$int_type { + unsafe { round_to_int_intrinsic(self) } + } } } } @@ -62,63 +73,77 @@ macro_rules! implement { implement! { impl f32x2 { + int_type = i32x2, floor = "llvm.floor.v2f32", ceil = "llvm.ceil.v2f32", round = "llvm.round.v2f32", trunc = "llvm.trunc.v2f32", + round_to_int = "llvm.lround.i32.v2f32", } } implement! { impl f32x4 { + int_type = i32x4, floor = "llvm.floor.v4f32", ceil = "llvm.ceil.v4f32", round = "llvm.round.v4f32", trunc = "llvm.trunc.v4f32", + round_to_int = "llvm.lround.i32.v4f32", } } implement! { impl f32x8 { + int_type = i32x8, floor = "llvm.floor.v8f32", ceil = "llvm.ceil.v8f32", round = "llvm.round.v8f32", trunc = "llvm.trunc.v8f32", + round_to_int = "llvm.lround.i32.v8f32", } } implement! { impl f32x16 { + int_type = i32x16, floor = "llvm.floor.v16f32", ceil = "llvm.ceil.v16f32", round = "llvm.round.v16f32", trunc = "llvm.trunc.v16f32", + round_to_int = "llvm.lround.i32.v16f32", } } implement! { impl f64x2 { + int_type = i64x2, floor = "llvm.floor.v2f64", ceil = "llvm.ceil.v2f64", round = "llvm.round.v2f64", trunc = "llvm.trunc.v2f64", + round_to_int = "llvm.lround.i64.v2f64", } } implement! { impl f64x4 { + int_type = i64x4, floor = "llvm.floor.v4f64", ceil = "llvm.ceil.v4f64", round = "llvm.round.v4f64", trunc = "llvm.trunc.v4f64", + round_to_int = "llvm.lround.i64.v4f64", } } implement! { impl f64x8 { + int_type = i64x8, floor = "llvm.floor.v8f64", ceil = "llvm.ceil.v8f64", round = "llvm.round.v8f64", trunc = "llvm.trunc.v8f64", + round_to_int = "llvm.lround.i64.v8f64", } }