Skip to content

Commit 5bc5d7f

Browse files
committed
Add comparison ops
1 parent cebc2ca commit 5bc5d7f

File tree

5 files changed

+414
-83
lines changed

5 files changed

+414
-83
lines changed

crates/core_simd/src/intrinsics.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,11 @@ extern "platform-intrinsic" {
4545

4646
// ceil
4747
pub(crate) fn simd_ceil<T>(x: T) -> T;
48+
49+
pub(crate) fn simd_eq<T, U>(x: T, y: T) -> U;
50+
pub(crate) fn simd_ne<T, U>(x: T, y: T) -> U;
51+
pub(crate) fn simd_lt<T, U>(x: T, y: T) -> U;
52+
pub(crate) fn simd_le<T, U>(x: T, y: T) -> U;
53+
pub(crate) fn simd_gt<T, U>(x: T, y: T) -> U;
54+
pub(crate) fn simd_ge<T, U>(x: T, y: T) -> U;
4855
}

crates/core_simd/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod intrinsics;
1111
mod ops;
1212

1313
pub mod masks;
14+
pub use masks::opaque::*;
1415

1516
mod vectors_u8;
1617
pub use vectors_u8::*;

crates/core_simd/src/macros.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,24 @@ macro_rules! define_mask_vector {
336336
call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | }
337337
call_counting_args! { $lanes => define_mask_vector => new $type | }
338338
call_counting_args! { $lanes => define_mask_vector => new_from_bool $type | }
339+
340+
/// Tests the value of the specified lane.
341+
///
342+
/// # Panics
343+
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
344+
#[inline]
345+
pub fn test(&self, lane: usize) -> bool {
346+
self[lane].test()
347+
}
348+
349+
/// Sets the value of the specified lane.
350+
///
351+
/// # Panics
352+
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
353+
#[inline]
354+
pub fn set(&mut self, lane: usize, value: bool) {
355+
self[lane] = value.into();
356+
}
339357
}
340358

341359
base_vector_traits! { $name => [$type; $lanes] }

crates/core_simd/src/masks/mod.rs

Lines changed: 180 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
33
pub mod wide;
44

5-
trait MaskImpl {
5+
mod ops;
6+
pub use ops::*;
7+
8+
pub(crate) trait MaskImpl {
69
type Mask;
710
}
811

@@ -93,123 +96,217 @@ macro_rules! define_opaque_mask {
9396
} => {
9497
$(#[$attr])*
9598
#[allow(non_camel_case_types)]
96-
pub struct $name(<[$width; $lanes] as MaskImpl>::Mask);
99+
pub struct $name(<[$width; $lanes] as crate::masks::MaskImpl>::Mask);
97100

98101
impl $name {
102+
pub(crate) fn new_from_inner(inner: <[$width; $lanes] as crate::masks::MaskImpl>::Mask) -> Self {
103+
Self(inner)
104+
}
105+
99106
/// Construct a mask by setting all lanes to the given value.
100107
pub fn splat(value: bool) -> Self {
101-
Self(<[$width; $lanes] as MaskImpl>::Mask::splat(value.into()))
108+
Self(<[$width; $lanes] as crate::masks::MaskImpl>::Mask::splat(value.into()))
102109
}
103110

104111
call_counting_args! { $lanes => define_opaque_mask => new [$width; $lanes] }
112+
113+
/// Tests the value of the specified lane.
114+
///
115+
/// # Panics
116+
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
117+
#[inline]
118+
pub fn test(&self, lane: usize) -> bool {
119+
self.0.test(lane)
120+
}
121+
122+
/// Sets the value of the specified lane.
123+
///
124+
/// # Panics
125+
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
126+
#[inline]
127+
pub fn set(&mut self, lane: usize, value: bool) {
128+
self.0.set(lane, value);
129+
}
130+
}
131+
132+
impl Copy for $name {}
133+
134+
impl Clone for $name {
135+
#[inline]
136+
fn clone(&self) -> Self {
137+
*self
138+
}
139+
}
140+
141+
impl Default for $name {
142+
#[inline]
143+
fn default() -> Self {
144+
Self::splat(false)
145+
}
146+
}
147+
148+
impl PartialEq for $name {
149+
#[inline]
150+
fn eq(&self, other: &Self) -> bool {
151+
self.0 == other.0
152+
}
153+
}
154+
155+
impl PartialOrd for $name {
156+
#[inline]
157+
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
158+
self.0.partial_cmp(&other.0)
159+
}
105160
}
106161
};
107162
{ new [$width:ty; $lanes:tt] $($var:ident)* } => {
108163
/// Construct a vector by setting each lane to the given values.
109164
#[allow(clippy::too_many_arguments)]
110165
#[inline]
111166
pub const fn new($($var: bool),*) -> Self {
112-
Self(<[$width; $lanes] as MaskImpl>::Mask::new_from_bool($($var),*))
167+
Self(<[$width; $lanes] as crate::masks::MaskImpl>::Mask::new_from_bool($($var),*))
113168
}
114169
}
115170
}
116171

117-
define_opaque_mask! {
118-
/// Mask for 8 8-bit lanes
119-
struct mask8x8([u8; 8]);
120-
}
172+
pub(crate) mod opaque {
173+
define_opaque_mask! {
174+
/// Mask for 8 8-bit lanes.
175+
///
176+
/// The layout of this type is unspecified.
177+
struct mask8x8([u8; 8]);
178+
}
121179

122-
define_opaque_mask! {
123-
/// Mask for 16 8-bit lanes
124-
struct mask8x16([u8; 16]);
125-
}
180+
define_opaque_mask! {
181+
/// Mask for 16 8-bit lanes.
182+
///
183+
/// The layout of this type is unspecified.
184+
struct mask8x16([u8; 16]);
185+
}
126186

127-
define_opaque_mask! {
128-
/// Mask for 32 8-bit lanes
129-
struct mask8x32([u8; 32]);
130-
}
187+
define_opaque_mask! {
188+
/// Mask for 32 8-bit lanes.
189+
///
190+
/// The layout of this type is unspecified.
191+
struct mask8x32([u8; 32]);
192+
}
131193

132-
define_opaque_mask! {
133-
/// Mask for 64 8-bit lanes
134-
struct mask8x64([u8; 64]);
135-
}
194+
define_opaque_mask! {
195+
/// Mask for 64 8-bit lanes.
196+
///
197+
/// The layout of this type is unspecified.
198+
struct mask8x64([u8; 64]);
199+
}
136200

137-
define_opaque_mask! {
138-
/// Mask for 4 16-bit lanes
139-
struct mask16x4([u16; 4]);
140-
}
201+
define_opaque_mask! {
202+
/// Mask for 4 16-bit lanes.
203+
///
204+
/// The layout of this type is unspecified.
205+
struct mask16x4([u16; 4]);
206+
}
141207

142-
define_opaque_mask! {
143-
/// Mask for 8 16-bit lanes
144-
struct mask16x8([u16; 8]);
145-
}
208+
define_opaque_mask! {
209+
/// Mask for 8 16-bit lanes.
210+
///
211+
/// The layout of this type is unspecified.
212+
struct mask16x8([u16; 8]);
213+
}
146214

147-
define_opaque_mask! {
148-
/// Mask for 16 16-bit lanes
149-
struct mask16x16([u16; 16]);
150-
}
215+
define_opaque_mask! {
216+
/// Mask for 16 16-bit lanes.
217+
///
218+
/// The layout of this type is unspecified.
219+
struct mask16x16([u16; 16]);
220+
}
151221

152-
define_opaque_mask! {
153-
/// Mask for 32 16-bit lanes
154-
struct mask16x32([u16; 32]);
155-
}
222+
define_opaque_mask! {
223+
/// Mask for 32 16-bit lanes.
224+
///
225+
/// The layout of this type is unspecified.
226+
struct mask16x32([u16; 32]);
227+
}
156228

157-
define_opaque_mask! {
158-
/// Mask for 2 32-bit lanes
159-
struct mask32x2([u32; 2]);
160-
}
229+
define_opaque_mask! {
230+
/// Mask for 2 32-bit lanes.
231+
///
232+
/// The layout of this type is unspecified.
233+
struct mask32x2([u32; 2]);
234+
}
161235

162-
define_opaque_mask! {
163-
/// Mask for 4 32-bit lanes
164-
struct mask32x4([u32; 4]);
165-
}
236+
define_opaque_mask! {
237+
/// Mask for 4 32-bit lanes.
238+
///
239+
/// The layout of this type is unspecified.
240+
struct mask32x4([u32; 4]);
241+
}
166242

167-
define_opaque_mask! {
168-
/// Mask for 8 32-bit lanes
169-
struct mask32x8([u32; 8]);
170-
}
243+
define_opaque_mask! {
244+
/// Mask for 8 32-bit lanes.
245+
///
246+
/// The layout of this type is unspecified.
247+
struct mask32x8([u32; 8]);
248+
}
171249

172-
define_opaque_mask! {
173-
/// Mask for 16 32-bit lanes
174-
struct mask32x16([u32; 16]);
175-
}
250+
define_opaque_mask! {
251+
/// Mask for 16 32-bit lanes.
252+
///
253+
/// The layout of this type is unspecified.
254+
struct mask32x16([u32; 16]);
255+
}
176256

177-
define_opaque_mask! {
178-
/// Mask for 2 64-bit lanes
179-
struct mask64x2([u64; 2]);
180-
}
257+
define_opaque_mask! {
258+
/// Mask for 2 64-bit lanes.
259+
///
260+
/// The layout of this type is unspecified.
261+
struct mask64x2([u64; 2]);
262+
}
181263

182-
define_opaque_mask! {
183-
/// Mask for 4 64-bit lanes
184-
struct mask64x4([u64; 4]);
185-
}
264+
define_opaque_mask! {
265+
/// Mask for 4 64-bit lanes.
266+
///
267+
/// The layout of this type is unspecified.
268+
struct mask64x4([u64; 4]);
269+
}
186270

187-
define_opaque_mask! {
188-
/// Mask for 8 64-bit lanes
189-
struct mask64x8([u64; 8]);
190-
}
271+
define_opaque_mask! {
272+
/// Mask for 8 64-bit lanes.
273+
///
274+
/// The layout of this type is unspecified.
275+
struct mask64x8([u64; 8]);
276+
}
191277

192-
define_opaque_mask! {
193-
/// Mask for 2 128-bit lanes
194-
struct mask128x2([u128; 2]);
195-
}
278+
define_opaque_mask! {
279+
/// Mask for 2 128-bit lanes.
280+
///
281+
/// The layout of this type is unspecified.
282+
struct mask128x2([u128; 2]);
283+
}
196284

197-
define_opaque_mask! {
198-
/// Mask for 4 128-bit lanes
199-
struct mask128x4([u128; 4]);
200-
}
285+
define_opaque_mask! {
286+
/// Mask for 4 128-bit lanes.
287+
///
288+
/// The layout of this type is unspecified.
289+
struct mask128x4([u128; 4]);
290+
}
201291

202-
define_opaque_mask! {
203-
/// Mask for 2 `isize`-wide lanes
204-
struct masksizex2([usize; 2]);
205-
}
292+
define_opaque_mask! {
293+
/// Mask for 2 `isize`-wide lanes.
294+
///
295+
/// The layout of this type is unspecified.
296+
struct masksizex2([usize; 2]);
297+
}
206298

207-
define_opaque_mask! {
208-
/// Mask for 4 `isize`-wide lanes
209-
struct masksizex4([usize; 4]);
210-
}
299+
define_opaque_mask! {
300+
/// Mask for 4 `isize`-wide lanes.
301+
///
302+
/// The layout of this type is unspecified.
303+
struct masksizex4([usize; 4]);
304+
}
211305

212-
define_opaque_mask! {
213-
/// Mask for 8 `isize`-wide lanes
214-
struct masksizex8([usize; 8]);
306+
define_opaque_mask! {
307+
/// Mask for 8 `isize`-wide lanes.
308+
///
309+
/// The layout of this type is unspecified.
310+
struct masksizex8([usize; 8]);
311+
}
215312
}

0 commit comments

Comments
 (0)