From 55357750066b44b196ebc4b826bb6ff1cd5e6939 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Fri, 15 Jul 2022 15:20:44 -0700 Subject: [PATCH] RMath: implement Bool4 type. --- sub_crates/rmath/src/wide4.rs | 162 +++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 4 deletions(-) diff --git a/sub_crates/rmath/src/wide4.rs b/sub_crates/rmath/src/wide4.rs index 9cb9e8e..e846753 100644 --- a/sub_crates/rmath/src/wide4.rs +++ b/sub_crates/rmath/src/wide4.rs @@ -1,12 +1,14 @@ -use std::ops::{AddAssign, DivAssign, MulAssign, SubAssign}; +use std::ops::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, MulAssign, SubAssign, +}; use approx::ulps_eq; use crate::{difference_of_products, two_prod, two_sum}; -pub use fallback::Float4; +pub use fallback::{Bool4, Float4}; mod fallback { - use std::ops::{Add, Div, Mul, Neg, Sub}; + use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Sub}; use crate::FMulAdd; @@ -78,6 +80,64 @@ mod fallback { // a.max(b) // } + //----------------------------------------------------- + // Comparisons. + + /// Less than. + #[inline(always)] + pub fn lt(self, rhs: Self) -> Bool4 { + Bool4([ + self.0[0] < rhs.0[0], + self.0[1] < rhs.0[1], + self.0[2] < rhs.0[2], + self.0[3] < rhs.0[3], + ]) + } + + /// Less than or equal. + #[inline(always)] + pub fn lte(self, rhs: Self) -> Bool4 { + Bool4([ + self.0[0] <= rhs.0[0], + self.0[1] <= rhs.0[1], + self.0[2] <= rhs.0[2], + self.0[3] <= rhs.0[3], + ]) + } + + /// Greater than. + #[inline(always)] + pub fn gt(self, rhs: Self) -> Bool4 { + Bool4([ + self.0[0] > rhs.0[0], + self.0[1] > rhs.0[1], + self.0[2] > rhs.0[2], + self.0[3] > rhs.0[3], + ]) + } + + /// Greater than or equal. + #[inline(always)] + pub fn gte(self, rhs: Self) -> Bool4 { + Bool4([ + self.0[0] >= rhs.0[0], + self.0[1] >= rhs.0[1], + self.0[2] >= rhs.0[2], + self.0[3] >= rhs.0[3], + ]) + } + + /// Equal. + #[inline(always)] + pub fn eq(self, rhs: Self) -> Bool4 { + Bool4([ + self.0[0] == rhs.0[0], + self.0[1] == rhs.0[1], + self.0[2] == rhs.0[2], + self.0[3] == rhs.0[3], + ]) + } + //----------------------------------------------------- // Individual components. @@ -265,14 +325,87 @@ mod fallback { } impl FMulAdd for Float4 { + #[inline(always)] fn fma(self, b: Self, c: Self) -> Self { self.mul_add(b, c) } } + + //--------------------------------------------------------- + + #[derive(Debug, Copy, Clone)] + #[repr(transparent)] + pub struct Bool4([bool; 4]); + + impl Bool4 { + #[inline(always)] + pub fn to_bools(self) -> [bool; 4] { + self.0 + } + + #[inline(always)] + pub fn to_bitmask(self) -> u8 { + self.0[0] as u8 + | ((self.0[1] as u8) << 1) + | ((self.0[2] as u8) << 2) + | ((self.0[3] as u8) << 3) + } + } + + impl BitAnd for Bool4 { + type Output = Self; + + #[inline(always)] + fn bitand(self, rhs: Self) -> Self { + Self([ + self.0[0] & rhs.0[0], + self.0[1] & rhs.0[1], + self.0[2] & rhs.0[2], + self.0[3] & rhs.0[3], + ]) + } + } + + impl BitOr for Bool4 { + type Output = Self; + + #[inline(always)] + fn bitor(self, rhs: Self) -> Self { + Self([ + self.0[0] | rhs.0[0], + self.0[1] | rhs.0[1], + self.0[2] | rhs.0[2], + self.0[3] | rhs.0[3], + ]) + } + } + + impl BitXor for Bool4 { + type Output = Self; + + #[inline(always)] + fn bitxor(self, rhs: Self) -> Self { + Self([ + self.0[0] ^ rhs.0[0], + self.0[1] ^ rhs.0[1], + self.0[2] ^ rhs.0[2], + self.0[3] ^ rhs.0[3], + ]) + } + } + + impl Not for Bool4 { + type Output = Self; + + #[inline(always)] + fn not(self) -> Self { + Self([!self.0[0], !self.0[1], !self.0[2], !self.0[3]]) + } + } } //------------------------------------------------------------- -// Float4 impls that don't depend on its inner representation. +// Impls that don't depend on inner representation. impl Float4 { /// 3D dot product (only uses the first 3 components). @@ -562,3 +695,24 @@ impl DivAssign for Float4 { *self = *self / rhs; } } + +impl BitAndAssign for Bool4 { + #[inline(always)] + fn bitand_assign(&mut self, rhs: Self) { + *self = *self & rhs; + } +} + +impl BitOrAssign for Bool4 { + #[inline(always)] + fn bitor_assign(&mut self, rhs: Self) { + *self = *self | rhs; + } +} + +impl BitXorAssign for Bool4 { + #[inline(always)] + fn bitxor_assign(&mut self, rhs: Self) { + *self = *self ^ rhs; + } +}