Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0682c31

Browse files
authoredApr 9, 2021
Merge pull request rust-lang#80 from rust-lang/feature/comparisons
Add classification functions
2 parents 4e6d440 + e6a5309 commit 0682c31

File tree

22 files changed

+537
-299
lines changed

22 files changed

+537
-299
lines changed
 

‎crates/core_simd/src/comparisons.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use crate::LanesAtMost32;
2+
3+
macro_rules! implement_mask_ops {
4+
{ $($vector:ident => $mask:ident ($inner_mask_ty:ident, $inner_ty:ident),)* } => {
5+
$(
6+
impl<const LANES: usize> crate::$vector<LANES>
7+
where
8+
crate::$vector<LANES>: LanesAtMost32,
9+
crate::$inner_ty<LANES>: LanesAtMost32,
10+
{
11+
/// Test if each lane is equal to the corresponding lane in `other`.
12+
#[inline]
13+
pub fn lanes_eq(self, other: Self) -> crate::$mask<LANES> {
14+
unsafe {
15+
crate::$inner_mask_ty::from_int_unchecked(crate::intrinsics::simd_eq(self, other))
16+
.into()
17+
}
18+
}
19+
20+
/// Test if each lane is not equal to the corresponding lane in `other`.
21+
#[inline]
22+
pub fn lanes_ne(self, other: Self) -> crate::$mask<LANES> {
23+
unsafe {
24+
crate::$inner_mask_ty::from_int_unchecked(crate::intrinsics::simd_ne(self, other))
25+
.into()
26+
}
27+
}
28+
29+
/// Test if each lane is less than the corresponding lane in `other`.
30+
#[inline]
31+
pub fn lanes_lt(self, other: Self) -> crate::$mask<LANES> {
32+
unsafe {
33+
crate::$inner_mask_ty::from_int_unchecked(crate::intrinsics::simd_lt(self, other))
34+
.into()
35+
}
36+
}
37+
38+
/// Test if each lane is greater than the corresponding lane in `other`.
39+
#[inline]
40+
pub fn lanes_gt(self, other: Self) -> crate::$mask<LANES> {
41+
unsafe {
42+
crate::$inner_mask_ty::from_int_unchecked(crate::intrinsics::simd_gt(self, other))
43+
.into()
44+
}
45+
}
46+
47+
/// Test if each lane is less than or equal to the corresponding lane in `other`.
48+
#[inline]
49+
pub fn lanes_le(self, other: Self) -> crate::$mask<LANES> {
50+
unsafe {
51+
crate::$inner_mask_ty::from_int_unchecked(crate::intrinsics::simd_le(self, other))
52+
.into()
53+
}
54+
}
55+
56+
/// Test if each lane is greater than or equal to the corresponding lane in `other`.
57+
#[inline]
58+
pub fn lanes_ge(self, other: Self) -> crate::$mask<LANES> {
59+
unsafe {
60+
crate::$inner_mask_ty::from_int_unchecked(crate::intrinsics::simd_ge(self, other))
61+
.into()
62+
}
63+
}
64+
}
65+
)*
66+
}
67+
}
68+
69+
implement_mask_ops! {
70+
SimdI8 => Mask8 (SimdMask8, SimdI8),
71+
SimdI16 => Mask16 (SimdMask16, SimdI16),
72+
SimdI32 => Mask32 (SimdMask32, SimdI32),
73+
SimdI64 => Mask64 (SimdMask64, SimdI64),
74+
SimdI128 => Mask128 (SimdMask128, SimdI128),
75+
SimdIsize => MaskSize (SimdMaskSize, SimdIsize),
76+
77+
SimdU8 => Mask8 (SimdMask8, SimdI8),
78+
SimdU16 => Mask16 (SimdMask16, SimdI16),
79+
SimdU32 => Mask32 (SimdMask32, SimdI32),
80+
SimdU64 => Mask64 (SimdMask64, SimdI64),
81+
SimdU128 => Mask128 (SimdMask128, SimdI128),
82+
SimdUsize => MaskSize (SimdMaskSize, SimdIsize),
83+
84+
SimdF32 => Mask32 (SimdMask32, SimdI32),
85+
SimdF64 => Mask64 (SimdMask64, SimdI64),
86+
}

‎crates/core_simd/src/first.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`.
22
macro_rules! impl_vector {
33
{ $name:ident, $type:ty } => {
4-
impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost64 {
4+
impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {
55
/// Construct a SIMD vector by setting all lanes to the given value.
66
pub const fn splat(value: $type) -> Self {
77
Self([value; LANES])
@@ -44,31 +44,31 @@ macro_rules! impl_vector {
4444
}
4545
}
4646

47-
impl<const LANES: usize> Copy for $name<LANES> where Self: crate::LanesAtMost64 {}
47+
impl<const LANES: usize> Copy for $name<LANES> where Self: crate::LanesAtMost32 {}
4848

49-
impl<const LANES: usize> Clone for $name<LANES> where Self: crate::LanesAtMost64 {
49+
impl<const LANES: usize> Clone for $name<LANES> where Self: crate::LanesAtMost32 {
5050
#[inline]
5151
fn clone(&self) -> Self {
5252
*self
5353
}
5454
}
5555

56-
impl<const LANES: usize> Default for $name<LANES> where Self: crate::LanesAtMost64 {
56+
impl<const LANES: usize> Default for $name<LANES> where Self: crate::LanesAtMost32 {
5757
#[inline]
5858
fn default() -> Self {
5959
Self::splat(<$type>::default())
6060
}
6161
}
6262

63-
impl<const LANES: usize> PartialEq for $name<LANES> where Self: crate::LanesAtMost64 {
63+
impl<const LANES: usize> PartialEq for $name<LANES> where Self: crate::LanesAtMost32 {
6464
#[inline]
6565
fn eq(&self, other: &Self) -> bool {
6666
// TODO use SIMD equality
6767
self.to_array() == other.to_array()
6868
}
6969
}
7070

71-
impl<const LANES: usize> PartialOrd for $name<LANES> where Self: crate::LanesAtMost64 {
71+
impl<const LANES: usize> PartialOrd for $name<LANES> where Self: crate::LanesAtMost32 {
7272
#[inline]
7373
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
7474
// TODO use SIMD equalitya
@@ -77,43 +77,43 @@ macro_rules! impl_vector {
7777
}
7878

7979
// array references
80-
impl<const LANES: usize> AsRef<[$type; LANES]> for $name<LANES> where Self: crate::LanesAtMost64 {
80+
impl<const LANES: usize> AsRef<[$type; LANES]> for $name<LANES> where Self: crate::LanesAtMost32 {
8181
#[inline]
8282
fn as_ref(&self) -> &[$type; LANES] {
8383
&self.0
8484
}
8585
}
8686

87-
impl<const LANES: usize> AsMut<[$type; LANES]> for $name<LANES> where Self: crate::LanesAtMost64 {
87+
impl<const LANES: usize> AsMut<[$type; LANES]> for $name<LANES> where Self: crate::LanesAtMost32 {
8888
#[inline]
8989
fn as_mut(&mut self) -> &mut [$type; LANES] {
9090
&mut self.0
9191
}
9292
}
9393

9494
// slice references
95-
impl<const LANES: usize> AsRef<[$type]> for $name<LANES> where Self: crate::LanesAtMost64 {
95+
impl<const LANES: usize> AsRef<[$type]> for $name<LANES> where Self: crate::LanesAtMost32 {
9696
#[inline]
9797
fn as_ref(&self) -> &[$type] {
9898
&self.0
9999
}
100100
}
101101

102-
impl<const LANES: usize> AsMut<[$type]> for $name<LANES> where Self: crate::LanesAtMost64 {
102+
impl<const LANES: usize> AsMut<[$type]> for $name<LANES> where Self: crate::LanesAtMost32 {
103103
#[inline]
104104
fn as_mut(&mut self) -> &mut [$type] {
105105
&mut self.0
106106
}
107107
}
108108

109109
// vector/array conversion
110-
impl<const LANES: usize> From<[$type; LANES]> for $name<LANES> where Self: crate::LanesAtMost64 {
110+
impl<const LANES: usize> From<[$type; LANES]> for $name<LANES> where Self: crate::LanesAtMost32 {
111111
fn from(array: [$type; LANES]) -> Self {
112112
Self(array)
113113
}
114114
}
115115

116-
impl <const LANES: usize> From<$name<LANES>> for [$type; LANES] where $name<LANES>: crate::LanesAtMost64 {
116+
impl <const LANES: usize> From<$name<LANES>> for [$type; LANES] where $name<LANES>: crate::LanesAtMost32 {
117117
fn from(vector: $name<LANES>) -> Self {
118118
vector.to_array()
119119
}

‎crates/core_simd/src/fmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ macro_rules! impl_fmt_trait {
3535
$( // repeat trait
3636
impl<const LANES: usize> core::fmt::$trait for crate::$type<LANES>
3737
where
38-
Self: crate::LanesAtMost64,
38+
Self: crate::LanesAtMost32,
3939
{
4040
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
4141
$format(self.as_ref(), f)

‎crates/core_simd/src/intrinsics.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ extern "platform-intrinsic" {
6161
pub(crate) fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
6262
pub(crate) fn simd_shuffle16<T, U>(x: T, y: T, idx: [u32; 16]) -> U;
6363
pub(crate) fn simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U;
64-
pub(crate) fn simd_shuffle64<T, U>(x: T, y: T, idx: [u32; 64]) -> U;
6564

6665
// {s,u}add.sat
6766
pub(crate) fn simd_saturating_add<T>(x: T, y: T) -> T;

‎crates/core_simd/src/lanes_at_most_64.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
/// Implemented for bitmask sizes that are supported by the implementation.
2-
pub trait LanesAtMost64 {}
2+
pub trait LanesAtMost32 {}
33

44
macro_rules! impl_for {
55
{ $name:ident } => {
6-
impl LanesAtMost64 for $name<1> {}
7-
impl LanesAtMost64 for $name<2> {}
8-
impl LanesAtMost64 for $name<4> {}
9-
impl LanesAtMost64 for $name<8> {}
10-
impl LanesAtMost64 for $name<16> {}
11-
impl LanesAtMost64 for $name<32> {}
12-
impl LanesAtMost64 for $name<64> {}
6+
impl LanesAtMost32 for $name<1> {}
7+
impl LanesAtMost32 for $name<2> {}
8+
impl LanesAtMost32 for $name<4> {}
9+
impl LanesAtMost32 for $name<8> {}
10+
impl LanesAtMost32 for $name<16> {}
11+
impl LanesAtMost32 for $name<32> {}
1312
}
1413
}
1514

‎crates/core_simd/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod permute;
1212
#[macro_use]
1313
mod transmute;
1414

15+
mod comparisons;
1516
mod fmt;
1617
mod intrinsics;
1718
mod ops;
@@ -20,7 +21,7 @@ mod round;
2021
mod math;
2122

2223
mod lanes_at_most_64;
23-
pub use lanes_at_most_64::LanesAtMost64;
24+
pub use lanes_at_most_64::LanesAtMost32;
2425

2526
mod masks;
2627
pub use masks::*;

‎crates/core_simd/src/masks/bitmask.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
use crate::LanesAtMost64;
1+
use crate::LanesAtMost32;
22

33
/// A mask where each lane is represented by a single bit.
44
#[derive(Copy, Clone, Debug)]
55
#[repr(transparent)]
66
pub struct BitMask<const LANES: usize>(u64)
77
where
8-
BitMask<LANES>: LanesAtMost64;
8+
BitMask<LANES>: LanesAtMost32;
99

1010
impl<const LANES: usize> BitMask<LANES>
1111
where
12-
Self: LanesAtMost64,
12+
Self: LanesAtMost32,
1313
{
1414
/// Construct a mask by setting all lanes to the given value.
1515
pub fn splat(value: bool) -> Self {
@@ -43,7 +43,7 @@ where
4343

4444
impl<const LANES: usize> core::ops::BitAnd for BitMask<LANES>
4545
where
46-
Self: LanesAtMost64,
46+
Self: LanesAtMost32,
4747
{
4848
type Output = Self;
4949
#[inline]
@@ -54,7 +54,7 @@ where
5454

5555
impl<const LANES: usize> core::ops::BitAnd<bool> for BitMask<LANES>
5656
where
57-
Self: LanesAtMost64,
57+
Self: LanesAtMost32,
5858
{
5959
type Output = Self;
6060
#[inline]
@@ -65,7 +65,7 @@ where
6565

6666
impl<const LANES: usize> core::ops::BitAnd<BitMask<LANES>> for bool
6767
where
68-
BitMask<LANES>: LanesAtMost64,
68+
BitMask<LANES>: LanesAtMost32,
6969
{
7070
type Output = BitMask<LANES>;
7171
#[inline]
@@ -76,7 +76,7 @@ where
7676

7777
impl<const LANES: usize> core::ops::BitOr for BitMask<LANES>
7878
where
79-
Self: LanesAtMost64,
79+
Self: LanesAtMost32,
8080
{
8181
type Output = Self;
8282
#[inline]
@@ -87,7 +87,7 @@ where
8787

8888
impl<const LANES: usize> core::ops::BitOr<bool> for BitMask<LANES>
8989
where
90-
Self: LanesAtMost64,
90+
Self: LanesAtMost32,
9191
{
9292
type Output = Self;
9393
#[inline]
@@ -98,7 +98,7 @@ where
9898

9999
impl<const LANES: usize> core::ops::BitOr<BitMask<LANES>> for bool
100100
where
101-
BitMask<LANES>: LanesAtMost64,
101+
BitMask<LANES>: LanesAtMost32,
102102
{
103103
type Output = BitMask<LANES>;
104104
#[inline]
@@ -109,7 +109,7 @@ where
109109

110110
impl<const LANES: usize> core::ops::BitXor for BitMask<LANES>
111111
where
112-
Self: LanesAtMost64,
112+
Self: LanesAtMost32,
113113
{
114114
type Output = Self;
115115
#[inline]
@@ -120,7 +120,7 @@ where
120120

121121
impl<const LANES: usize> core::ops::BitXor<bool> for BitMask<LANES>
122122
where
123-
Self: LanesAtMost64,
123+
Self: LanesAtMost32,
124124
{
125125
type Output = Self;
126126
#[inline]
@@ -131,7 +131,7 @@ where
131131

132132
impl<const LANES: usize> core::ops::BitXor<BitMask<LANES>> for bool
133133
where
134-
BitMask<LANES>: LanesAtMost64,
134+
BitMask<LANES>: LanesAtMost32,
135135
{
136136
type Output = BitMask<LANES>;
137137
#[inline]
@@ -142,7 +142,7 @@ where
142142

143143
impl<const LANES: usize> core::ops::Not for BitMask<LANES>
144144
where
145-
Self: LanesAtMost64,
145+
Self: LanesAtMost32,
146146
{
147147
type Output = BitMask<LANES>;
148148
#[inline]
@@ -153,7 +153,7 @@ where
153153

154154
impl<const LANES: usize> core::ops::BitAndAssign for BitMask<LANES>
155155
where
156-
Self: LanesAtMost64,
156+
Self: LanesAtMost32,
157157
{
158158
#[inline]
159159
fn bitand_assign(&mut self, rhs: Self) {
@@ -163,7 +163,7 @@ where
163163

164164
impl<const LANES: usize> core::ops::BitAndAssign<bool> for BitMask<LANES>
165165
where
166-
Self: LanesAtMost64,
166+
Self: LanesAtMost32,
167167
{
168168
#[inline]
169169
fn bitand_assign(&mut self, rhs: bool) {
@@ -173,7 +173,7 @@ where
173173

174174
impl<const LANES: usize> core::ops::BitOrAssign for BitMask<LANES>
175175
where
176-
Self: LanesAtMost64,
176+
Self: LanesAtMost32,
177177
{
178178
#[inline]
179179
fn bitor_assign(&mut self, rhs: Self) {
@@ -183,7 +183,7 @@ where
183183

184184
impl<const LANES: usize> core::ops::BitOrAssign<bool> for BitMask<LANES>
185185
where
186-
Self: LanesAtMost64,
186+
Self: LanesAtMost32,
187187
{
188188
#[inline]
189189
fn bitor_assign(&mut self, rhs: bool) {
@@ -193,7 +193,7 @@ where
193193

194194
impl<const LANES: usize> core::ops::BitXorAssign for BitMask<LANES>
195195
where
196-
Self: LanesAtMost64,
196+
Self: LanesAtMost32,
197197
{
198198
#[inline]
199199
fn bitxor_assign(&mut self, rhs: Self) {
@@ -203,7 +203,7 @@ where
203203

204204
impl<const LANES: usize> core::ops::BitXorAssign<bool> for BitMask<LANES>
205205
where
206-
Self: LanesAtMost64,
206+
Self: LanesAtMost32,
207207
{
208208
#[inline]
209209
fn bitxor_assign(&mut self, rhs: bool) {

‎crates/core_simd/src/masks/full_masks.rs

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ macro_rules! define_mask {
2020
#[repr(transparent)]
2121
pub struct $name<const $lanes: usize>($type)
2222
where
23-
$type: crate::LanesAtMost64;
23+
$type: crate::LanesAtMost32;
2424

2525
impl<const LANES: usize> Copy for $name<LANES>
2626
where
27-
$type: crate::LanesAtMost64,
27+
$type: crate::LanesAtMost32,
2828
{}
2929

3030
impl<const LANES: usize> Clone for $name<LANES>
3131
where
32-
$type: crate::LanesAtMost64,
32+
$type: crate::LanesAtMost32,
3333
{
3434
#[inline]
3535
fn clone(&self) -> Self {
@@ -39,7 +39,7 @@ macro_rules! define_mask {
3939

4040
impl<const $lanes: usize> $name<$lanes>
4141
where
42-
$type: crate::LanesAtMost64,
42+
$type: crate::LanesAtMost32,
4343
{
4444
/// Construct a mask by setting all lanes to the given value.
4545
pub fn splat(value: bool) -> Self {
@@ -75,11 +75,30 @@ macro_rules! define_mask {
7575
0
7676
}
7777
}
78+
79+
/// Creates a mask from an integer vector.
80+
///
81+
/// # Safety
82+
/// All lanes must be either 0 or -1.
83+
#[inline]
84+
pub unsafe fn from_int_unchecked(value: $type) -> Self {
85+
Self(value)
86+
}
87+
88+
/// Creates a mask from an integer vector.
89+
///
90+
/// # Panics
91+
/// Panics if any lane is not 0 or -1.
92+
#[inline]
93+
pub fn from_int(value: $type) -> Self {
94+
use core::convert::TryInto;
95+
value.try_into().unwrap()
96+
}
7897
}
7998

8099
impl<const $lanes: usize> core::convert::From<bool> for $name<$lanes>
81100
where
82-
$type: crate::LanesAtMost64,
101+
$type: crate::LanesAtMost32,
83102
{
84103
fn from(value: bool) -> Self {
85104
Self::splat(value)
@@ -88,7 +107,7 @@ macro_rules! define_mask {
88107

89108
impl<const $lanes: usize> core::convert::TryFrom<$type> for $name<$lanes>
90109
where
91-
$type: crate::LanesAtMost64,
110+
$type: crate::LanesAtMost32,
92111
{
93112
type Error = TryFromMaskError;
94113
fn try_from(value: $type) -> Result<Self, Self::Error> {
@@ -102,7 +121,7 @@ macro_rules! define_mask {
102121

103122
impl<const $lanes: usize> core::convert::From<$name<$lanes>> for $type
104123
where
105-
$type: crate::LanesAtMost64,
124+
$type: crate::LanesAtMost32,
106125
{
107126
fn from(value: $name<$lanes>) -> Self {
108127
value.0
@@ -111,8 +130,8 @@ macro_rules! define_mask {
111130

112131
impl<const $lanes: usize> core::convert::From<crate::BitMask<$lanes>> for $name<$lanes>
113132
where
114-
$type: crate::LanesAtMost64,
115-
crate::BitMask<$lanes>: crate::LanesAtMost64,
133+
$type: crate::LanesAtMost32,
134+
crate::BitMask<$lanes>: crate::LanesAtMost32,
116135
{
117136
fn from(value: crate::BitMask<$lanes>) -> Self {
118137
// TODO use an intrinsic to do this efficiently (with LLVM's sext instruction)
@@ -126,8 +145,8 @@ macro_rules! define_mask {
126145

127146
impl<const $lanes: usize> core::convert::From<$name<$lanes>> for crate::BitMask<$lanes>
128147
where
129-
$type: crate::LanesAtMost64,
130-
crate::BitMask<$lanes>: crate::LanesAtMost64,
148+
$type: crate::LanesAtMost32,
149+
crate::BitMask<$lanes>: crate::LanesAtMost32,
131150
{
132151
fn from(value: $name<$lanes>) -> Self {
133152
// TODO use an intrinsic to do this efficiently (with LLVM's trunc instruction)
@@ -141,7 +160,7 @@ macro_rules! define_mask {
141160

142161
impl<const $lanes: usize> core::fmt::Debug for $name<$lanes>
143162
where
144-
$type: crate::LanesAtMost64,
163+
$type: crate::LanesAtMost32,
145164
{
146165
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
147166
f.debug_list()
@@ -152,7 +171,7 @@ macro_rules! define_mask {
152171

153172
impl<const $lanes: usize> core::fmt::Binary for $name<$lanes>
154173
where
155-
$type: crate::LanesAtMost64,
174+
$type: crate::LanesAtMost32,
156175
{
157176
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
158177
core::fmt::Binary::fmt(&self.0, f)
@@ -161,7 +180,7 @@ macro_rules! define_mask {
161180

162181
impl<const $lanes: usize> core::fmt::Octal for $name<$lanes>
163182
where
164-
$type: crate::LanesAtMost64,
183+
$type: crate::LanesAtMost32,
165184
{
166185
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
167186
core::fmt::Octal::fmt(&self.0, f)
@@ -170,7 +189,7 @@ macro_rules! define_mask {
170189

171190
impl<const $lanes: usize> core::fmt::LowerHex for $name<$lanes>
172191
where
173-
$type: crate::LanesAtMost64,
192+
$type: crate::LanesAtMost32,
174193
{
175194
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
176195
core::fmt::LowerHex::fmt(&self.0, f)
@@ -179,7 +198,7 @@ macro_rules! define_mask {
179198

180199
impl<const $lanes: usize> core::fmt::UpperHex for $name<$lanes>
181200
where
182-
$type: crate::LanesAtMost64,
201+
$type: crate::LanesAtMost32,
183202
{
184203
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
185204
core::fmt::UpperHex::fmt(&self.0, f)
@@ -188,7 +207,7 @@ macro_rules! define_mask {
188207

189208
impl<const LANES: usize> core::ops::BitAnd for $name<LANES>
190209
where
191-
$type: crate::LanesAtMost64,
210+
$type: crate::LanesAtMost32,
192211
{
193212
type Output = Self;
194213
#[inline]
@@ -199,7 +218,7 @@ macro_rules! define_mask {
199218

200219
impl<const LANES: usize> core::ops::BitAnd<bool> for $name<LANES>
201220
where
202-
$type: crate::LanesAtMost64,
221+
$type: crate::LanesAtMost32,
203222
{
204223
type Output = Self;
205224
#[inline]
@@ -210,7 +229,7 @@ macro_rules! define_mask {
210229

211230
impl<const LANES: usize> core::ops::BitAnd<$name<LANES>> for bool
212231
where
213-
$type: crate::LanesAtMost64,
232+
$type: crate::LanesAtMost32,
214233
{
215234
type Output = $name<LANES>;
216235
#[inline]
@@ -221,7 +240,7 @@ macro_rules! define_mask {
221240

222241
impl<const LANES: usize> core::ops::BitOr for $name<LANES>
223242
where
224-
$type: crate::LanesAtMost64,
243+
$type: crate::LanesAtMost32,
225244
{
226245
type Output = Self;
227246
#[inline]
@@ -232,7 +251,7 @@ macro_rules! define_mask {
232251

233252
impl<const LANES: usize> core::ops::BitOr<bool> for $name<LANES>
234253
where
235-
$type: crate::LanesAtMost64,
254+
$type: crate::LanesAtMost32,
236255
{
237256
type Output = Self;
238257
#[inline]
@@ -243,7 +262,7 @@ macro_rules! define_mask {
243262

244263
impl<const LANES: usize> core::ops::BitOr<$name<LANES>> for bool
245264
where
246-
$type: crate::LanesAtMost64,
265+
$type: crate::LanesAtMost32,
247266
{
248267
type Output = $name<LANES>;
249268
#[inline]
@@ -254,7 +273,7 @@ macro_rules! define_mask {
254273

255274
impl<const LANES: usize> core::ops::BitXor for $name<LANES>
256275
where
257-
$type: crate::LanesAtMost64,
276+
$type: crate::LanesAtMost32,
258277
{
259278
type Output = Self;
260279
#[inline]
@@ -265,7 +284,7 @@ macro_rules! define_mask {
265284

266285
impl<const LANES: usize> core::ops::BitXor<bool> for $name<LANES>
267286
where
268-
$type: crate::LanesAtMost64,
287+
$type: crate::LanesAtMost32,
269288
{
270289
type Output = Self;
271290
#[inline]
@@ -276,7 +295,7 @@ macro_rules! define_mask {
276295

277296
impl<const LANES: usize> core::ops::BitXor<$name<LANES>> for bool
278297
where
279-
$type: crate::LanesAtMost64,
298+
$type: crate::LanesAtMost32,
280299
{
281300
type Output = $name<LANES>;
282301
#[inline]
@@ -287,7 +306,7 @@ macro_rules! define_mask {
287306

288307
impl<const LANES: usize> core::ops::Not for $name<LANES>
289308
where
290-
$type: crate::LanesAtMost64,
309+
$type: crate::LanesAtMost32,
291310
{
292311
type Output = $name<LANES>;
293312
#[inline]
@@ -298,7 +317,7 @@ macro_rules! define_mask {
298317

299318
impl<const LANES: usize> core::ops::BitAndAssign for $name<LANES>
300319
where
301-
$type: crate::LanesAtMost64,
320+
$type: crate::LanesAtMost32,
302321
{
303322
#[inline]
304323
fn bitand_assign(&mut self, rhs: Self) {
@@ -308,7 +327,7 @@ macro_rules! define_mask {
308327

309328
impl<const LANES: usize> core::ops::BitAndAssign<bool> for $name<LANES>
310329
where
311-
$type: crate::LanesAtMost64,
330+
$type: crate::LanesAtMost32,
312331
{
313332
#[inline]
314333
fn bitand_assign(&mut self, rhs: bool) {
@@ -318,7 +337,7 @@ macro_rules! define_mask {
318337

319338
impl<const LANES: usize> core::ops::BitOrAssign for $name<LANES>
320339
where
321-
$type: crate::LanesAtMost64,
340+
$type: crate::LanesAtMost32,
322341
{
323342
#[inline]
324343
fn bitor_assign(&mut self, rhs: Self) {
@@ -328,7 +347,7 @@ macro_rules! define_mask {
328347

329348
impl<const LANES: usize> core::ops::BitOrAssign<bool> for $name<LANES>
330349
where
331-
$type: crate::LanesAtMost64,
350+
$type: crate::LanesAtMost32,
332351
{
333352
#[inline]
334353
fn bitor_assign(&mut self, rhs: bool) {
@@ -338,7 +357,7 @@ macro_rules! define_mask {
338357

339358
impl<const LANES: usize> core::ops::BitXorAssign for $name<LANES>
340359
where
341-
$type: crate::LanesAtMost64,
360+
$type: crate::LanesAtMost32,
342361
{
343362
#[inline]
344363
fn bitxor_assign(&mut self, rhs: Self) {
@@ -348,7 +367,7 @@ macro_rules! define_mask {
348367

349368
impl<const LANES: usize> core::ops::BitXorAssign<bool> for $name<LANES>
350369
where
351-
$type: crate::LanesAtMost64,
370+
$type: crate::LanesAtMost32,
352371
{
353372
#[inline]
354373
fn bitxor_assign(&mut self, rhs: bool) {

‎crates/core_simd/src/masks/mod.rs

Lines changed: 66 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub use full_masks::*;
77
mod bitmask;
88
pub use bitmask::*;
99

10-
use crate::LanesAtMost64;
10+
use crate::LanesAtMost32;
1111

1212
macro_rules! define_opaque_mask {
1313
{
@@ -17,17 +17,39 @@ macro_rules! define_opaque_mask {
1717
} => {
1818
$(#[$attr])*
1919
#[allow(non_camel_case_types)]
20-
pub struct $name<const $lanes: usize>($inner_ty) where $bits_ty: LanesAtMost64;
20+
pub struct $name<const $lanes: usize>($inner_ty) where $bits_ty: LanesAtMost32;
2121

2222
impl<const $lanes: usize> $name<$lanes>
2323
where
24-
$bits_ty: LanesAtMost64
24+
$bits_ty: LanesAtMost32
2525
{
2626
/// Construct a mask by setting all lanes to the given value.
2727
pub fn splat(value: bool) -> Self {
2828
Self(<$inner_ty>::splat(value))
2929
}
3030

31+
/// Converts an array to a SIMD vector.
32+
pub fn from_array(array: [bool; LANES]) -> Self {
33+
let mut vector = Self::splat(false);
34+
let mut i = 0;
35+
while i < $lanes {
36+
vector.set(i, array[i]);
37+
i += 1;
38+
}
39+
vector
40+
}
41+
42+
/// Converts a SIMD vector to an array.
43+
pub fn to_array(self) -> [bool; LANES] {
44+
let mut array = [false; LANES];
45+
let mut i = 0;
46+
while i < $lanes {
47+
array[i] = self.test(i);
48+
i += 1;
49+
}
50+
array
51+
}
52+
3153
/// Tests the value of the specified lane.
3254
///
3355
/// # Panics
@@ -49,8 +71,8 @@ macro_rules! define_opaque_mask {
4971

5072
impl<const $lanes: usize> From<BitMask<$lanes>> for $name<$lanes>
5173
where
52-
$bits_ty: LanesAtMost64,
53-
BitMask<$lanes>: LanesAtMost64,
74+
$bits_ty: LanesAtMost32,
75+
BitMask<$lanes>: LanesAtMost32,
5476
{
5577
fn from(value: BitMask<$lanes>) -> Self {
5678
Self(value.into())
@@ -59,8 +81,8 @@ macro_rules! define_opaque_mask {
5981

6082
impl<const $lanes: usize> From<$name<$lanes>> for crate::BitMask<$lanes>
6183
where
62-
$bits_ty: LanesAtMost64,
63-
BitMask<$lanes>: LanesAtMost64,
84+
$bits_ty: LanesAtMost32,
85+
BitMask<$lanes>: LanesAtMost32,
6486
{
6587
fn from(value: $name<$lanes>) -> Self {
6688
value.0.into()
@@ -69,7 +91,7 @@ macro_rules! define_opaque_mask {
6991

7092
impl<const $lanes: usize> From<$inner_ty> for $name<$lanes>
7193
where
72-
$bits_ty: LanesAtMost64,
94+
$bits_ty: LanesAtMost32,
7395
{
7496
fn from(value: $inner_ty) -> Self {
7597
Self(value)
@@ -78,22 +100,35 @@ macro_rules! define_opaque_mask {
78100

79101
impl<const $lanes: usize> From<$name<$lanes>> for $inner_ty
80102
where
81-
$bits_ty: LanesAtMost64,
103+
$bits_ty: LanesAtMost32,
82104
{
83105
fn from(value: $name<$lanes>) -> Self {
84106
value.0
85107
}
86108
}
87109

110+
// vector/array conversion
111+
impl<const $lanes: usize> From<[bool; $lanes]> for $name<$lanes> where $bits_ty: crate::LanesAtMost32 {
112+
fn from(array: [bool; $lanes]) -> Self {
113+
Self::from_array(array)
114+
}
115+
}
116+
117+
impl <const $lanes: usize> From<$name<$lanes>> for [bool; $lanes] where $bits_ty: crate::LanesAtMost32 {
118+
fn from(vector: $name<$lanes>) -> Self {
119+
vector.to_array()
120+
}
121+
}
122+
88123
impl<const $lanes: usize> Copy for $name<$lanes>
89124
where
90125
$inner_ty: Copy,
91-
$bits_ty: LanesAtMost64,
126+
$bits_ty: LanesAtMost32,
92127
{}
93128

94129
impl<const $lanes: usize> Clone for $name<$lanes>
95130
where
96-
$bits_ty: LanesAtMost64,
131+
$bits_ty: LanesAtMost32,
97132
{
98133
#[inline]
99134
fn clone(&self) -> Self {
@@ -103,7 +138,7 @@ macro_rules! define_opaque_mask {
103138

104139
impl<const $lanes: usize> Default for $name<$lanes>
105140
where
106-
$bits_ty: LanesAtMost64,
141+
$bits_ty: LanesAtMost32,
107142
{
108143
#[inline]
109144
fn default() -> Self {
@@ -113,7 +148,7 @@ macro_rules! define_opaque_mask {
113148

114149
impl<const $lanes: usize> PartialEq for $name<$lanes>
115150
where
116-
$bits_ty: LanesAtMost64,
151+
$bits_ty: LanesAtMost32,
117152
{
118153
#[inline]
119154
fn eq(&self, other: &Self) -> bool {
@@ -123,7 +158,7 @@ macro_rules! define_opaque_mask {
123158

124159
impl<const $lanes: usize> PartialOrd for $name<$lanes>
125160
where
126-
$bits_ty: LanesAtMost64,
161+
$bits_ty: LanesAtMost32,
127162
{
128163
#[inline]
129164
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
@@ -133,7 +168,7 @@ macro_rules! define_opaque_mask {
133168

134169
impl<const $lanes: usize> core::fmt::Debug for $name<$lanes>
135170
where
136-
$bits_ty: LanesAtMost64,
171+
$bits_ty: LanesAtMost32,
137172
{
138173
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
139174
core::fmt::Debug::fmt(&self.0, f)
@@ -142,7 +177,7 @@ macro_rules! define_opaque_mask {
142177

143178
impl<const LANES: usize> core::ops::BitAnd for $name<LANES>
144179
where
145-
$bits_ty: LanesAtMost64,
180+
$bits_ty: LanesAtMost32,
146181
{
147182
type Output = Self;
148183
#[inline]
@@ -153,7 +188,7 @@ macro_rules! define_opaque_mask {
153188

154189
impl<const LANES: usize> core::ops::BitAnd<bool> for $name<LANES>
155190
where
156-
$bits_ty: LanesAtMost64,
191+
$bits_ty: LanesAtMost32,
157192
{
158193
type Output = Self;
159194
#[inline]
@@ -164,7 +199,7 @@ macro_rules! define_opaque_mask {
164199

165200
impl<const LANES: usize> core::ops::BitAnd<$name<LANES>> for bool
166201
where
167-
$bits_ty: LanesAtMost64,
202+
$bits_ty: LanesAtMost32,
168203
{
169204
type Output = $name<LANES>;
170205
#[inline]
@@ -175,7 +210,7 @@ macro_rules! define_opaque_mask {
175210

176211
impl<const LANES: usize> core::ops::BitOr for $name<LANES>
177212
where
178-
$bits_ty: LanesAtMost64,
213+
$bits_ty: LanesAtMost32,
179214
{
180215
type Output = Self;
181216
#[inline]
@@ -186,7 +221,7 @@ macro_rules! define_opaque_mask {
186221

187222
impl<const LANES: usize> core::ops::BitOr<bool> for $name<LANES>
188223
where
189-
$bits_ty: LanesAtMost64,
224+
$bits_ty: LanesAtMost32,
190225
{
191226
type Output = Self;
192227
#[inline]
@@ -197,7 +232,7 @@ macro_rules! define_opaque_mask {
197232

198233
impl<const LANES: usize> core::ops::BitOr<$name<LANES>> for bool
199234
where
200-
$bits_ty: LanesAtMost64,
235+
$bits_ty: LanesAtMost32,
201236
{
202237
type Output = $name<LANES>;
203238
#[inline]
@@ -208,7 +243,7 @@ macro_rules! define_opaque_mask {
208243

209244
impl<const LANES: usize> core::ops::BitXor for $name<LANES>
210245
where
211-
$bits_ty: LanesAtMost64,
246+
$bits_ty: LanesAtMost32,
212247
{
213248
type Output = Self;
214249
#[inline]
@@ -219,7 +254,7 @@ macro_rules! define_opaque_mask {
219254

220255
impl<const LANES: usize> core::ops::BitXor<bool> for $name<LANES>
221256
where
222-
$bits_ty: LanesAtMost64,
257+
$bits_ty: LanesAtMost32,
223258
{
224259
type Output = Self;
225260
#[inline]
@@ -230,7 +265,7 @@ macro_rules! define_opaque_mask {
230265

231266
impl<const LANES: usize> core::ops::BitXor<$name<LANES>> for bool
232267
where
233-
$bits_ty: LanesAtMost64,
268+
$bits_ty: LanesAtMost32,
234269
{
235270
type Output = $name<LANES>;
236271
#[inline]
@@ -241,7 +276,7 @@ macro_rules! define_opaque_mask {
241276

242277
impl<const LANES: usize> core::ops::Not for $name<LANES>
243278
where
244-
$bits_ty: LanesAtMost64,
279+
$bits_ty: LanesAtMost32,
245280
{
246281
type Output = $name<LANES>;
247282
#[inline]
@@ -252,7 +287,7 @@ macro_rules! define_opaque_mask {
252287

253288
impl<const LANES: usize> core::ops::BitAndAssign for $name<LANES>
254289
where
255-
$bits_ty: LanesAtMost64,
290+
$bits_ty: LanesAtMost32,
256291
{
257292
#[inline]
258293
fn bitand_assign(&mut self, rhs: Self) {
@@ -262,7 +297,7 @@ macro_rules! define_opaque_mask {
262297

263298
impl<const LANES: usize> core::ops::BitAndAssign<bool> for $name<LANES>
264299
where
265-
$bits_ty: LanesAtMost64,
300+
$bits_ty: LanesAtMost32,
266301
{
267302
#[inline]
268303
fn bitand_assign(&mut self, rhs: bool) {
@@ -272,7 +307,7 @@ macro_rules! define_opaque_mask {
272307

273308
impl<const LANES: usize> core::ops::BitOrAssign for $name<LANES>
274309
where
275-
$bits_ty: LanesAtMost64,
310+
$bits_ty: LanesAtMost32,
276311
{
277312
#[inline]
278313
fn bitor_assign(&mut self, rhs: Self) {
@@ -282,7 +317,7 @@ macro_rules! define_opaque_mask {
282317

283318
impl<const LANES: usize> core::ops::BitOrAssign<bool> for $name<LANES>
284319
where
285-
$bits_ty: LanesAtMost64,
320+
$bits_ty: LanesAtMost32,
286321
{
287322
#[inline]
288323
fn bitor_assign(&mut self, rhs: bool) {
@@ -292,7 +327,7 @@ macro_rules! define_opaque_mask {
292327

293328
impl<const LANES: usize> core::ops::BitXorAssign for $name<LANES>
294329
where
295-
$bits_ty: LanesAtMost64,
330+
$bits_ty: LanesAtMost32,
296331
{
297332
#[inline]
298333
fn bitxor_assign(&mut self, rhs: Self) {
@@ -302,7 +337,7 @@ macro_rules! define_opaque_mask {
302337

303338
impl<const LANES: usize> core::ops::BitXorAssign<bool> for $name<LANES>
304339
where
305-
$bits_ty: LanesAtMost64,
340+
$bits_ty: LanesAtMost32,
306341
{
307342
#[inline]
308343
fn bitxor_assign(&mut self, rhs: bool) {
@@ -360,73 +395,6 @@ define_opaque_mask! {
360395
@bits crate::SimdIsize<LANES>
361396
}
362397

363-
macro_rules! implement_mask_ops {
364-
{ $($vector:ident => $mask:ident ($inner_ty:ident),)* } => {
365-
$(
366-
impl<const LANES: usize> crate::$vector<LANES>
367-
where
368-
crate::$vector<LANES>: LanesAtMost64,
369-
crate::$inner_ty<LANES>: LanesAtMost64,
370-
{
371-
/// Test if each lane is equal to the corresponding lane in `other`.
372-
#[inline]
373-
pub fn lanes_eq(&self, other: &Self) -> $mask<LANES> {
374-
unsafe { $mask(crate::intrinsics::simd_eq(self, other)) }
375-
}
376-
377-
/// Test if each lane is not equal to the corresponding lane in `other`.
378-
#[inline]
379-
pub fn lanes_ne(&self, other: &Self) -> $mask<LANES> {
380-
unsafe { $mask(crate::intrinsics::simd_ne(self, other)) }
381-
}
382-
383-
/// Test if each lane is less than the corresponding lane in `other`.
384-
#[inline]
385-
pub fn lanes_lt(&self, other: &Self) -> $mask<LANES> {
386-
unsafe { $mask(crate::intrinsics::simd_lt(self, other)) }
387-
}
388-
389-
/// Test if each lane is greater than the corresponding lane in `other`.
390-
#[inline]
391-
pub fn lanes_gt(&self, other: &Self) -> $mask<LANES> {
392-
unsafe { $mask(crate::intrinsics::simd_gt(self, other)) }
393-
}
394-
395-
/// Test if each lane is less than or equal to the corresponding lane in `other`.
396-
#[inline]
397-
pub fn lanes_le(&self, other: &Self) -> $mask<LANES> {
398-
unsafe { $mask(crate::intrinsics::simd_le(self, other)) }
399-
}
400-
401-
/// Test if each lane is greater than or equal to the corresponding lane in `other`.
402-
#[inline]
403-
pub fn lanes_ge(&self, other: &Self) -> $mask<LANES> {
404-
unsafe { $mask(crate::intrinsics::simd_ge(self, other)) }
405-
}
406-
}
407-
)*
408-
}
409-
}
410-
411-
implement_mask_ops! {
412-
SimdI8 => Mask8 (SimdI8),
413-
SimdI16 => Mask16 (SimdI16),
414-
SimdI32 => Mask32 (SimdI32),
415-
SimdI64 => Mask64 (SimdI64),
416-
SimdI128 => Mask128 (SimdI128),
417-
SimdIsize => MaskSize (SimdIsize),
418-
419-
SimdU8 => Mask8 (SimdI8),
420-
SimdU16 => Mask16 (SimdI16),
421-
SimdU32 => Mask32 (SimdI32),
422-
SimdU64 => Mask64 (SimdI64),
423-
SimdU128 => Mask128 (SimdI128),
424-
SimdUsize => MaskSize (SimdIsize),
425-
426-
SimdF32 => Mask32 (SimdI32),
427-
SimdF64 => Mask64 (SimdI64),
428-
}
429-
430398
/// Vector of eight 8-bit masks
431399
pub type mask8x8 = Mask8<8>;
432400

‎crates/core_simd/src/math.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! impl_uint_arith {
22
($(($name:ident, $n:ty)),+) => {
3-
$( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost64 {
3+
$( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {
44

55
/// Lanewise saturating add.
66
///
@@ -42,7 +42,7 @@ macro_rules! impl_uint_arith {
4242

4343
macro_rules! impl_int_arith {
4444
($(($name:ident, $n:ty)),+) => {
45-
$( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost64 {
45+
$( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {
4646

4747
/// Lanewise saturating add.
4848
///

‎crates/core_simd/src/ops.rs

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::LanesAtMost64;
1+
use crate::LanesAtMost32;
22

33
/// Checks if the right-hand side argument of a left- or right-shift would cause overflow.
44
fn invalid_shift_rhs<T>(rhs: T) -> bool
@@ -16,7 +16,7 @@ macro_rules! impl_ref_ops {
1616
{
1717
impl<const $lanes:ident: usize> core::ops::$trait:ident<$rhs:ty> for $type:ty
1818
where
19-
$($bound:path: LanesAtMost64,)*
19+
$($bound:path: LanesAtMost32,)*
2020
{
2121
type Output = $output:ty;
2222

@@ -26,7 +26,7 @@ macro_rules! impl_ref_ops {
2626
} => {
2727
impl<const $lanes: usize> core::ops::$trait<$rhs> for $type
2828
where
29-
$($bound: LanesAtMost64,)*
29+
$($bound: LanesAtMost32,)*
3030
{
3131
type Output = $output;
3232

@@ -36,7 +36,7 @@ macro_rules! impl_ref_ops {
3636

3737
impl<const $lanes: usize> core::ops::$trait<&'_ $rhs> for $type
3838
where
39-
$($bound: LanesAtMost64,)*
39+
$($bound: LanesAtMost32,)*
4040
{
4141
type Output = <$type as core::ops::$trait<$rhs>>::Output;
4242

@@ -48,7 +48,7 @@ macro_rules! impl_ref_ops {
4848

4949
impl<const $lanes: usize> core::ops::$trait<$rhs> for &'_ $type
5050
where
51-
$($bound: LanesAtMost64,)*
51+
$($bound: LanesAtMost32,)*
5252
{
5353
type Output = <$type as core::ops::$trait<$rhs>>::Output;
5454

@@ -60,7 +60,7 @@ macro_rules! impl_ref_ops {
6060

6161
impl<const $lanes: usize> core::ops::$trait<&'_ $rhs> for &'_ $type
6262
where
63-
$($bound: LanesAtMost64,)*
63+
$($bound: LanesAtMost32,)*
6464
{
6565
type Output = <$type as core::ops::$trait<$rhs>>::Output;
6666

@@ -75,23 +75,23 @@ macro_rules! impl_ref_ops {
7575
{
7676
impl<const $lanes:ident: usize> core::ops::$trait:ident<$rhs:ty> for $type:ty
7777
where
78-
$($bound:path: LanesAtMost64,)*
78+
$($bound:path: LanesAtMost32,)*
7979
{
8080
$(#[$attrs:meta])*
8181
fn $fn:ident(&mut $self_tok:ident, $rhs_arg:ident: $rhs_arg_ty:ty) $body:tt
8282
}
8383
} => {
8484
impl<const $lanes: usize> core::ops::$trait<$rhs> for $type
8585
where
86-
$($bound: LanesAtMost64,)*
86+
$($bound: LanesAtMost32,)*
8787
{
8888
$(#[$attrs])*
8989
fn $fn(&mut $self_tok, $rhs_arg: $rhs_arg_ty) $body
9090
}
9191

9292
impl<const $lanes: usize> core::ops::$trait<&'_ $rhs> for $type
9393
where
94-
$($bound: LanesAtMost64,)*
94+
$($bound: LanesAtMost32,)*
9595
{
9696
$(#[$attrs])*
9797
fn $fn(&mut $self_tok, $rhs_arg: &$rhs_arg_ty) {
@@ -104,23 +104,23 @@ macro_rules! impl_ref_ops {
104104
{
105105
impl<const $lanes:ident: usize> core::ops::$trait:ident for $type:ty
106106
where
107-
$($bound:path: LanesAtMost64,)*
107+
$($bound:path: LanesAtMost32,)*
108108
{
109109
type Output = $output:ty;
110110
fn $fn:ident($self_tok:ident) -> Self::Output $body:tt
111111
}
112112
} => {
113113
impl<const $lanes: usize> core::ops::$trait for $type
114114
where
115-
$($bound: LanesAtMost64,)*
115+
$($bound: LanesAtMost32,)*
116116
{
117117
type Output = $output;
118118
fn $fn($self_tok) -> Self::Output $body
119119
}
120120

121121
impl<const $lanes: usize> core::ops::$trait for &'_ $type
122122
where
123-
$($bound: LanesAtMost64,)*
123+
$($bound: LanesAtMost32,)*
124124
{
125125
type Output = <$type as core::ops::$trait>::Output;
126126
fn $fn($self_tok) -> Self::Output {
@@ -167,7 +167,7 @@ macro_rules! impl_op {
167167
impl_ref_ops! {
168168
impl<const LANES: usize> core::ops::Not for crate::$type<LANES>
169169
where
170-
crate::$type<LANES>: LanesAtMost64,
170+
crate::$type<LANES>: LanesAtMost32,
171171
{
172172
type Output = Self;
173173
fn not(self) -> Self::Output {
@@ -181,7 +181,7 @@ macro_rules! impl_op {
181181
impl_ref_ops! {
182182
impl<const LANES: usize> core::ops::Neg for crate::$type<LANES>
183183
where
184-
crate::$type<LANES>: LanesAtMost64,
184+
crate::$type<LANES>: LanesAtMost32,
185185
{
186186
type Output = Self;
187187
fn neg(self) -> Self::Output {
@@ -195,9 +195,9 @@ macro_rules! impl_op {
195195
impl_ref_ops! {
196196
impl<const LANES: usize> core::ops::Neg for crate::$type<LANES>
197197
where
198-
crate::$type<LANES>: LanesAtMost64,
199-
crate::SimdU32<LANES>: LanesAtMost64,
200-
crate::SimdU64<LANES>: LanesAtMost64,
198+
crate::$type<LANES>: LanesAtMost32,
199+
crate::SimdU32<LANES>: LanesAtMost32,
200+
crate::SimdU64<LANES>: LanesAtMost32,
201201
{
202202
type Output = Self;
203203
fn neg(self) -> Self::Output {
@@ -212,7 +212,7 @@ macro_rules! impl_op {
212212
{ impl Index for $type:ident, $scalar:ty } => {
213213
impl<I, const LANES: usize> core::ops::Index<I> for crate::$type<LANES>
214214
where
215-
Self: LanesAtMost64,
215+
Self: LanesAtMost32,
216216
I: core::slice::SliceIndex<[$scalar]>,
217217
{
218218
type Output = I::Output;
@@ -224,7 +224,7 @@ macro_rules! impl_op {
224224

225225
impl<I, const LANES: usize> core::ops::IndexMut<I> for crate::$type<LANES>
226226
where
227-
Self: LanesAtMost64,
227+
Self: LanesAtMost32,
228228
I: core::slice::SliceIndex<[$scalar]>,
229229
{
230230
fn index_mut(&mut self, index: I) -> &mut Self::Output {
@@ -239,7 +239,7 @@ macro_rules! impl_op {
239239
impl_ref_ops! {
240240
impl<const LANES: usize> core::ops::$trait<Self> for crate::$type<LANES>
241241
where
242-
crate::$type<LANES>: LanesAtMost64,
242+
crate::$type<LANES>: LanesAtMost32,
243243
{
244244
type Output = Self;
245245

@@ -255,7 +255,7 @@ macro_rules! impl_op {
255255
impl_ref_ops! {
256256
impl<const LANES: usize> core::ops::$trait<$scalar> for crate::$type<LANES>
257257
where
258-
crate::$type<LANES>: LanesAtMost64,
258+
crate::$type<LANES>: LanesAtMost32,
259259
{
260260
type Output = Self;
261261

@@ -269,7 +269,7 @@ macro_rules! impl_op {
269269
impl_ref_ops! {
270270
impl<const LANES: usize> core::ops::$trait<crate::$type<LANES>> for $scalar
271271
where
272-
crate::$type<LANES>: LanesAtMost64,
272+
crate::$type<LANES>: LanesAtMost32,
273273
{
274274
type Output = crate::$type<LANES>;
275275

@@ -283,7 +283,7 @@ macro_rules! impl_op {
283283
impl_ref_ops! {
284284
impl<const LANES: usize> core::ops::$assign_trait<Self> for crate::$type<LANES>
285285
where
286-
crate::$type<LANES>: LanesAtMost64,
286+
crate::$type<LANES>: LanesAtMost32,
287287
{
288288
#[inline]
289289
fn $assign_trait_fn(&mut self, rhs: Self) {
@@ -297,7 +297,7 @@ macro_rules! impl_op {
297297
impl_ref_ops! {
298298
impl<const LANES: usize> core::ops::$assign_trait<$scalar> for crate::$type<LANES>
299299
where
300-
crate::$type<LANES>: LanesAtMost64,
300+
crate::$type<LANES>: LanesAtMost32,
301301
{
302302
#[inline]
303303
fn $assign_trait_fn(&mut self, rhs: $scalar) {
@@ -343,7 +343,7 @@ macro_rules! impl_unsigned_int_ops {
343343
impl_ref_ops! {
344344
impl<const LANES: usize> core::ops::Div<Self> for crate::$vector<LANES>
345345
where
346-
crate::$vector<LANES>: LanesAtMost64,
346+
crate::$vector<LANES>: LanesAtMost32,
347347
{
348348
type Output = Self;
349349

@@ -371,7 +371,7 @@ macro_rules! impl_unsigned_int_ops {
371371
impl_ref_ops! {
372372
impl<const LANES: usize> core::ops::Div<$scalar> for crate::$vector<LANES>
373373
where
374-
crate::$vector<LANES>: LanesAtMost64,
374+
crate::$vector<LANES>: LanesAtMost32,
375375
{
376376
type Output = Self;
377377

@@ -394,7 +394,7 @@ macro_rules! impl_unsigned_int_ops {
394394
impl_ref_ops! {
395395
impl<const LANES: usize> core::ops::Div<crate::$vector<LANES>> for $scalar
396396
where
397-
crate::$vector<LANES>: LanesAtMost64,
397+
crate::$vector<LANES>: LanesAtMost32,
398398
{
399399
type Output = crate::$vector<LANES>;
400400

@@ -408,7 +408,7 @@ macro_rules! impl_unsigned_int_ops {
408408
impl_ref_ops! {
409409
impl<const LANES: usize> core::ops::DivAssign<Self> for crate::$vector<LANES>
410410
where
411-
crate::$vector<LANES>: LanesAtMost64,
411+
crate::$vector<LANES>: LanesAtMost32,
412412
{
413413
#[inline]
414414
fn div_assign(&mut self, rhs: Self) {
@@ -420,7 +420,7 @@ macro_rules! impl_unsigned_int_ops {
420420
impl_ref_ops! {
421421
impl<const LANES: usize> core::ops::DivAssign<$scalar> for crate::$vector<LANES>
422422
where
423-
crate::$vector<LANES>: LanesAtMost64,
423+
crate::$vector<LANES>: LanesAtMost32,
424424
{
425425
#[inline]
426426
fn div_assign(&mut self, rhs: $scalar) {
@@ -433,7 +433,7 @@ macro_rules! impl_unsigned_int_ops {
433433
impl_ref_ops! {
434434
impl<const LANES: usize> core::ops::Rem<Self> for crate::$vector<LANES>
435435
where
436-
crate::$vector<LANES>: LanesAtMost64,
436+
crate::$vector<LANES>: LanesAtMost32,
437437
{
438438
type Output = Self;
439439

@@ -461,7 +461,7 @@ macro_rules! impl_unsigned_int_ops {
461461
impl_ref_ops! {
462462
impl<const LANES: usize> core::ops::Rem<$scalar> for crate::$vector<LANES>
463463
where
464-
crate::$vector<LANES>: LanesAtMost64,
464+
crate::$vector<LANES>: LanesAtMost32,
465465
{
466466
type Output = Self;
467467

@@ -484,7 +484,7 @@ macro_rules! impl_unsigned_int_ops {
484484
impl_ref_ops! {
485485
impl<const LANES: usize> core::ops::Rem<crate::$vector<LANES>> for $scalar
486486
where
487-
crate::$vector<LANES>: LanesAtMost64,
487+
crate::$vector<LANES>: LanesAtMost32,
488488
{
489489
type Output = crate::$vector<LANES>;
490490

@@ -498,7 +498,7 @@ macro_rules! impl_unsigned_int_ops {
498498
impl_ref_ops! {
499499
impl<const LANES: usize> core::ops::RemAssign<Self> for crate::$vector<LANES>
500500
where
501-
crate::$vector<LANES>: LanesAtMost64,
501+
crate::$vector<LANES>: LanesAtMost32,
502502
{
503503
#[inline]
504504
fn rem_assign(&mut self, rhs: Self) {
@@ -510,7 +510,7 @@ macro_rules! impl_unsigned_int_ops {
510510
impl_ref_ops! {
511511
impl<const LANES: usize> core::ops::RemAssign<$scalar> for crate::$vector<LANES>
512512
where
513-
crate::$vector<LANES>: LanesAtMost64,
513+
crate::$vector<LANES>: LanesAtMost32,
514514
{
515515
#[inline]
516516
fn rem_assign(&mut self, rhs: $scalar) {
@@ -523,7 +523,7 @@ macro_rules! impl_unsigned_int_ops {
523523
impl_ref_ops! {
524524
impl<const LANES: usize> core::ops::Shl<Self> for crate::$vector<LANES>
525525
where
526-
crate::$vector<LANES>: LanesAtMost64,
526+
crate::$vector<LANES>: LanesAtMost32,
527527
{
528528
type Output = Self;
529529

@@ -545,7 +545,7 @@ macro_rules! impl_unsigned_int_ops {
545545
impl_ref_ops! {
546546
impl<const LANES: usize> core::ops::Shl<$scalar> for crate::$vector<LANES>
547547
where
548-
crate::$vector<LANES>: LanesAtMost64,
548+
crate::$vector<LANES>: LanesAtMost32,
549549
{
550550
type Output = Self;
551551

@@ -564,7 +564,7 @@ macro_rules! impl_unsigned_int_ops {
564564
impl_ref_ops! {
565565
impl<const LANES: usize> core::ops::ShlAssign<Self> for crate::$vector<LANES>
566566
where
567-
crate::$vector<LANES>: LanesAtMost64,
567+
crate::$vector<LANES>: LanesAtMost32,
568568
{
569569
#[inline]
570570
fn shl_assign(&mut self, rhs: Self) {
@@ -576,7 +576,7 @@ macro_rules! impl_unsigned_int_ops {
576576
impl_ref_ops! {
577577
impl<const LANES: usize> core::ops::ShlAssign<$scalar> for crate::$vector<LANES>
578578
where
579-
crate::$vector<LANES>: LanesAtMost64,
579+
crate::$vector<LANES>: LanesAtMost32,
580580
{
581581
#[inline]
582582
fn shl_assign(&mut self, rhs: $scalar) {
@@ -588,7 +588,7 @@ macro_rules! impl_unsigned_int_ops {
588588
impl_ref_ops! {
589589
impl<const LANES: usize> core::ops::Shr<Self> for crate::$vector<LANES>
590590
where
591-
crate::$vector<LANES>: LanesAtMost64,
591+
crate::$vector<LANES>: LanesAtMost32,
592592
{
593593
type Output = Self;
594594

@@ -610,7 +610,7 @@ macro_rules! impl_unsigned_int_ops {
610610
impl_ref_ops! {
611611
impl<const LANES: usize> core::ops::Shr<$scalar> for crate::$vector<LANES>
612612
where
613-
crate::$vector<LANES>: LanesAtMost64,
613+
crate::$vector<LANES>: LanesAtMost32,
614614
{
615615
type Output = Self;
616616

@@ -629,7 +629,7 @@ macro_rules! impl_unsigned_int_ops {
629629
impl_ref_ops! {
630630
impl<const LANES: usize> core::ops::ShrAssign<Self> for crate::$vector<LANES>
631631
where
632-
crate::$vector<LANES>: LanesAtMost64,
632+
crate::$vector<LANES>: LanesAtMost32,
633633
{
634634
#[inline]
635635
fn shr_assign(&mut self, rhs: Self) {
@@ -641,7 +641,7 @@ macro_rules! impl_unsigned_int_ops {
641641
impl_ref_ops! {
642642
impl<const LANES: usize> core::ops::ShrAssign<$scalar> for crate::$vector<LANES>
643643
where
644-
crate::$vector<LANES>: LanesAtMost64,
644+
crate::$vector<LANES>: LanesAtMost32,
645645
{
646646
#[inline]
647647
fn shr_assign(&mut self, rhs: $scalar) {

‎crates/core_simd/src/permute.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,5 @@ macro_rules! impl_shuffle_2pow_lanes {
2424
impl_shuffle_lane!{ $name, simd_shuffle8, 8 }
2525
impl_shuffle_lane!{ $name, simd_shuffle16, 16 }
2626
impl_shuffle_lane!{ $name, simd_shuffle32, 32 }
27-
impl_shuffle_lane!{ $name, simd_shuffle64, 64 }
2827
}
2928
}

‎crates/core_simd/src/round.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ macro_rules! implement {
44
} => {
55
impl<const LANES: usize> crate::$type<LANES>
66
where
7-
Self: crate::LanesAtMost64,
7+
Self: crate::LanesAtMost32,
88
{
99
/// Returns the largest integer less than or equal to each lane.
1010
#[cfg(feature = "std")]
@@ -25,8 +25,8 @@ macro_rules! implement {
2525

2626
impl<const LANES: usize> crate::$type<LANES>
2727
where
28-
Self: crate::LanesAtMost64,
29-
crate::$int_type<LANES>: crate::LanesAtMost64,
28+
Self: crate::LanesAtMost32,
29+
crate::$int_type<LANES>: crate::LanesAtMost32,
3030
{
3131
/// Rounds toward zero and converts to the same-width integer type, assuming that
3232
/// the value is finite and fits in that type.

‎crates/core_simd/src/vector/float.rs

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
/// `$lanes` of float `$type`, which uses `$bits_ty` as its binary
55
/// representation. Called from `define_float_vector!`.
66
macro_rules! impl_float_vector {
7-
{ $name:ident, $type:ty, $bits_ty:ident } => {
7+
{ $name:ident, $type:ty, $bits_ty:ident, $mask_ty:ident, $mask_impl_ty:ident } => {
88
impl_vector! { $name, $type }
99

1010
impl<const LANES: usize> $name<LANES>
1111
where
12-
Self: crate::LanesAtMost64,
13-
crate::$bits_ty<LANES>: crate::LanesAtMost64,
12+
Self: crate::LanesAtMost32,
13+
crate::$bits_ty<LANES>: crate::LanesAtMost32,
1414
{
1515
/// Raw transmutation to an unsigned integer vector type with the
1616
/// same size and number of lanes.
@@ -36,17 +36,69 @@ macro_rules! impl_float_vector {
3636
Self::from_bits(self.to_bits() & no_sign)
3737
}
3838
}
39+
40+
impl<const LANES: usize> $name<LANES>
41+
where
42+
Self: crate::LanesAtMost32,
43+
crate::$bits_ty<LANES>: crate::LanesAtMost32,
44+
crate::$mask_impl_ty<LANES>: crate::LanesAtMost32,
45+
{
46+
/// Returns true for each lane if it has a positive sign, including
47+
/// `+0.0`, `NaN`s with positive sign bit and positive infinity.
48+
#[inline]
49+
pub fn is_sign_positive(self) -> crate::$mask_ty<LANES> {
50+
!self.is_sign_negative()
51+
}
52+
53+
/// Returns true for each lane if it has a negative sign, including
54+
/// `-0.0`, `NaN`s with negative sign bit and negative infinity.
55+
#[inline]
56+
pub fn is_sign_negative(self) -> crate::$mask_ty<LANES> {
57+
let sign_bits = self.to_bits() & crate::$bits_ty::splat((!0 >> 1) + 1);
58+
sign_bits.lanes_gt(crate::$bits_ty::splat(0))
59+
}
60+
61+
/// Returns true for each lane if its value is `NaN`.
62+
#[inline]
63+
pub fn is_nan(self) -> crate::$mask_ty<LANES> {
64+
self.lanes_ne(self)
65+
}
66+
67+
/// Returns true for each lane if its value is positive infinity or negative infinity.
68+
#[inline]
69+
pub fn is_infinite(self) -> crate::$mask_ty<LANES> {
70+
self.abs().lanes_eq(Self::splat(<$type>::INFINITY))
71+
}
72+
73+
/// Returns true for each lane if its value is neither infinite nor `NaN`.
74+
#[inline]
75+
pub fn is_finite(self) -> crate::$mask_ty<LANES> {
76+
self.abs().lanes_lt(Self::splat(<$type>::INFINITY))
77+
}
78+
79+
/// Returns true for each lane if its value is subnormal.
80+
#[inline]
81+
pub fn is_subnormal(self) -> crate::$mask_ty<LANES> {
82+
self.abs().lanes_ne(Self::splat(0.0)) & (self.to_bits() & Self::splat(<$type>::INFINITY).to_bits()).lanes_eq(crate::$bits_ty::splat(0))
83+
}
84+
85+
/// Returns true for each lane if its value is neither neither zero, infinite,
86+
/// subnormal, or `NaN`.
87+
#[inline]
88+
pub fn is_normal(self) -> crate::$mask_ty<LANES> {
89+
!(self.abs().lanes_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite())
90+
}
91+
}
3992
};
4093
}
4194

42-
4395
/// A SIMD vector of containing `LANES` `f32` values.
4496
#[repr(simd)]
4597
pub struct SimdF32<const LANES: usize>([f32; LANES])
4698
where
47-
Self: crate::LanesAtMost64;
99+
Self: crate::LanesAtMost32;
48100

49-
impl_float_vector! { SimdF32, f32, SimdU32 }
101+
impl_float_vector! { SimdF32, f32, SimdU32, Mask32, SimdI32 }
50102

51103
from_transmute_x86! { unsafe f32x4 => __m128 }
52104
from_transmute_x86! { unsafe f32x8 => __m256 }
@@ -56,9 +108,9 @@ from_transmute_x86! { unsafe f32x8 => __m256 }
56108
#[repr(simd)]
57109
pub struct SimdF64<const LANES: usize>([f64; LANES])
58110
where
59-
Self: crate::LanesAtMost64;
111+
Self: crate::LanesAtMost32;
60112

61-
impl_float_vector! { SimdF64, f64, SimdU64 }
113+
impl_float_vector! { SimdF64, f64, SimdU64, Mask64, SimdI64 }
62114

63115
from_transmute_x86! { unsafe f64x2 => __m128d }
64116
from_transmute_x86! { unsafe f64x4 => __m256d }

‎crates/core_simd/src/vector/int.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22

33
/// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`.
44
macro_rules! impl_integer_vector {
5-
{ $name:ident, $type:ty } => {
5+
{ $name:ident, $type:ty, $mask_ty:ident, $mask_impl_ty:ident } => {
66
impl_vector! { $name, $type }
77

8-
impl<const LANES: usize> Eq for $name<LANES> where Self: crate::LanesAtMost64 {}
8+
impl<const LANES: usize> Eq for $name<LANES> where Self: crate::LanesAtMost32 {}
99

10-
impl<const LANES: usize> Ord for $name<LANES> where Self: crate::LanesAtMost64 {
10+
impl<const LANES: usize> Ord for $name<LANES> where Self: crate::LanesAtMost32 {
1111
#[inline]
1212
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1313
// TODO use SIMD cmp
1414
self.to_array().cmp(other.as_ref())
1515
}
1616
}
1717

18-
impl<const LANES: usize> core::hash::Hash for $name<LANES> where Self: crate::LanesAtMost64 {
18+
impl<const LANES: usize> core::hash::Hash for $name<LANES> where Self: crate::LanesAtMost32 {
1919
#[inline]
2020
fn hash<H>(&self, state: &mut H)
2121
where
@@ -24,16 +24,32 @@ macro_rules! impl_integer_vector {
2424
self.as_slice().hash(state)
2525
}
2626
}
27+
28+
impl<const LANES: usize> $name<LANES>
29+
where
30+
Self: crate::LanesAtMost32,
31+
crate::$mask_impl_ty<LANES>: crate::LanesAtMost32,
32+
{
33+
/// Returns true for each positive lane and false if it is zero or negative.
34+
pub fn is_positive(self) -> crate::$mask_ty<LANES> {
35+
self.lanes_gt(Self::splat(0))
36+
}
37+
38+
/// Returns true for each negative lane and false if it is zero or positive.
39+
pub fn is_negative(self) -> crate::$mask_ty<LANES> {
40+
self.lanes_lt(Self::splat(0))
41+
}
42+
}
2743
}
2844
}
2945

3046
/// A SIMD vector of containing `LANES` `isize` values.
3147
#[repr(simd)]
3248
pub struct SimdIsize<const LANES: usize>([isize; LANES])
3349
where
34-
Self: crate::LanesAtMost64;
50+
Self: crate::LanesAtMost32;
3551

36-
impl_integer_vector! { SimdIsize, isize }
52+
impl_integer_vector! { SimdIsize, isize, MaskSize, SimdIsize }
3753

3854
#[cfg(target_pointer_width = "32")]
3955
from_transmute_x86! { unsafe isizex4 => __m128i }
@@ -51,9 +67,9 @@ from_transmute_x86! { unsafe isizex4 => __m256i }
5167
#[repr(simd)]
5268
pub struct SimdI128<const LANES: usize>([i128; LANES])
5369
where
54-
Self: crate::LanesAtMost64;
70+
Self: crate::LanesAtMost32;
5571

56-
impl_integer_vector! { SimdI128, i128 }
72+
impl_integer_vector! { SimdI128, i128, Mask128, SimdI128 }
5773

5874
from_transmute_x86! { unsafe i128x2 => __m256i }
5975
//from_transmute_x86! { unsafe i128x4 => __m512i }
@@ -62,9 +78,9 @@ from_transmute_x86! { unsafe i128x2 => __m256i }
6278
#[repr(simd)]
6379
pub struct SimdI16<const LANES: usize>([i16; LANES])
6480
where
65-
Self: crate::LanesAtMost64;
81+
Self: crate::LanesAtMost32;
6682

67-
impl_integer_vector! { SimdI16, i16 }
83+
impl_integer_vector! { SimdI16, i16, Mask16, SimdI16 }
6884

6985
from_transmute_x86! { unsafe i16x8 => __m128i }
7086
from_transmute_x86! { unsafe i16x16 => __m256i }
@@ -74,9 +90,9 @@ from_transmute_x86! { unsafe i16x16 => __m256i }
7490
#[repr(simd)]
7591
pub struct SimdI32<const LANES: usize>([i32; LANES])
7692
where
77-
Self: crate::LanesAtMost64;
93+
Self: crate::LanesAtMost32;
7894

79-
impl_integer_vector! { SimdI32, i32 }
95+
impl_integer_vector! { SimdI32, i32, Mask32, SimdI32 }
8096

8197
from_transmute_x86! { unsafe i32x4 => __m128i }
8298
from_transmute_x86! { unsafe i32x8 => __m256i }
@@ -86,9 +102,9 @@ from_transmute_x86! { unsafe i32x8 => __m256i }
86102
#[repr(simd)]
87103
pub struct SimdI64<const LANES: usize>([i64; LANES])
88104
where
89-
Self: crate::LanesAtMost64;
105+
Self: crate::LanesAtMost32;
90106

91-
impl_integer_vector! { SimdI64, i64 }
107+
impl_integer_vector! { SimdI64, i64, Mask64, SimdI64 }
92108

93109
from_transmute_x86! { unsafe i64x2 => __m128i }
94110
from_transmute_x86! { unsafe i64x4 => __m256i }
@@ -98,9 +114,9 @@ from_transmute_x86! { unsafe i64x4 => __m256i }
98114
#[repr(simd)]
99115
pub struct SimdI8<const LANES: usize>([i8; LANES])
100116
where
101-
Self: crate::LanesAtMost64;
117+
Self: crate::LanesAtMost32;
102118

103-
impl_integer_vector! { SimdI8, i8 }
119+
impl_integer_vector! { SimdI8, i8, Mask8, SimdI8 }
104120

105121
from_transmute_x86! { unsafe i8x16 => __m128i }
106122
from_transmute_x86! { unsafe i8x32 => __m256i }

‎crates/core_simd/src/vector/uint.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ macro_rules! impl_unsigned_vector {
66
{ $name:ident, $type:ty } => {
77
impl_vector! { $name, $type }
88

9-
impl<const LANES: usize> Eq for $name<LANES> where Self: crate::LanesAtMost64 {}
9+
impl<const LANES: usize> Eq for $name<LANES> where Self: crate::LanesAtMost32 {}
1010

11-
impl<const LANES: usize> Ord for $name<LANES> where Self: crate::LanesAtMost64 {
11+
impl<const LANES: usize> Ord for $name<LANES> where Self: crate::LanesAtMost32 {
1212
#[inline]
1313
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1414
// TODO use SIMD cmp
1515
self.to_array().cmp(other.as_ref())
1616
}
1717
}
1818

19-
impl<const LANES: usize> core::hash::Hash for $name<LANES> where Self: crate::LanesAtMost64 {
19+
impl<const LANES: usize> core::hash::Hash for $name<LANES> where Self: crate::LanesAtMost32 {
2020
#[inline]
2121
fn hash<H>(&self, state: &mut H)
2222
where
@@ -32,7 +32,7 @@ macro_rules! impl_unsigned_vector {
3232
#[repr(simd)]
3333
pub struct SimdUsize<const LANES: usize>([usize; LANES])
3434
where
35-
Self: crate::LanesAtMost64;
35+
Self: crate::LanesAtMost32;
3636

3737
impl_unsigned_vector! { SimdUsize, usize }
3838

@@ -52,7 +52,7 @@ from_transmute_x86! { unsafe usizex4 => __m256i }
5252
#[repr(simd)]
5353
pub struct SimdU128<const LANES: usize>([u128; LANES])
5454
where
55-
Self: crate::LanesAtMost64;
55+
Self: crate::LanesAtMost32;
5656

5757
impl_unsigned_vector! { SimdU128, u128 }
5858

@@ -63,7 +63,7 @@ from_transmute_x86! { unsafe u128x2 => __m256i }
6363
#[repr(simd)]
6464
pub struct SimdU16<const LANES: usize>([u16; LANES])
6565
where
66-
Self: crate::LanesAtMost64;
66+
Self: crate::LanesAtMost32;
6767

6868
impl_unsigned_vector! { SimdU16, u16 }
6969

@@ -75,7 +75,7 @@ from_transmute_x86! { unsafe u16x16 => __m256i }
7575
#[repr(simd)]
7676
pub struct SimdU32<const LANES: usize>([u32; LANES])
7777
where
78-
Self: crate::LanesAtMost64;
78+
Self: crate::LanesAtMost32;
7979

8080
impl_unsigned_vector! { SimdU32, u32 }
8181

@@ -87,7 +87,7 @@ from_transmute_x86! { unsafe u32x8 => __m256i }
8787
#[repr(simd)]
8888
pub struct SimdU64<const LANES: usize>([u64; LANES])
8989
where
90-
Self: crate::LanesAtMost64;
90+
Self: crate::LanesAtMost32;
9191

9292
impl_unsigned_vector! { SimdU64, u64 }
9393

@@ -99,7 +99,7 @@ from_transmute_x86! { unsafe u64x4 => __m256i }
9999
#[repr(simd)]
100100
pub struct SimdU8<const LANES: usize>([u8; LANES])
101101
where
102-
Self: crate::LanesAtMost64;
102+
Self: crate::LanesAtMost32;
103103

104104
impl_unsigned_vector! { SimdU8, u8 }
105105

‎crates/core_simd/tests/f32_ops.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(is_subnormal)]
2+
13
#[macro_use]
24
mod ops_macros;
35
impl_float_tests! { SimdF32, f32, i32 }

‎crates/core_simd/tests/f64_ops.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(is_subnormal)]
2+
13
#[macro_use]
24
mod ops_macros;
35
impl_float_tests! { SimdF64, f64, i64 }
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
mask_tests! { mask8x8, 8 }
22
mask_tests! { mask8x16, 16 }
33
mask_tests! { mask8x32, 32 }
4-
mask_tests! { mask8x64, 64 }

‎crates/core_simd/tests/ops_macros.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,27 @@ macro_rules! impl_signed_tests {
147147
test_helpers::test_lanes! {
148148
fn neg<const LANES: usize>() {
149149
test_helpers::test_unary_elementwise(
150-
&<Vector<LANES> as core::ops::Neg>::neg,
150+
&<Vector::<LANES> as core::ops::Neg>::neg,
151151
&<Scalar as core::ops::Neg>::neg,
152152
&|x| !x.contains(&Scalar::MIN),
153153
);
154154
}
155+
156+
fn is_positive<const LANES: usize>() {
157+
test_helpers::test_unary_mask_elementwise(
158+
&Vector::<LANES>::is_positive,
159+
&Scalar::is_positive,
160+
&|_| true,
161+
);
162+
}
163+
164+
fn is_negative<const LANES: usize>() {
165+
test_helpers::test_unary_mask_elementwise(
166+
&Vector::<LANES>::is_negative,
167+
&Scalar::is_negative,
168+
&|_| true,
169+
);
170+
}
155171
}
156172

157173
test_helpers::test_lanes_panic! {
@@ -285,6 +301,62 @@ macro_rules! impl_float_tests {
285301
}
286302

287303
test_helpers::test_lanes! {
304+
fn is_sign_positive<const LANES: usize>() {
305+
test_helpers::test_unary_mask_elementwise(
306+
&Vector::<LANES>::is_sign_positive,
307+
&Scalar::is_sign_positive,
308+
&|_| true,
309+
);
310+
}
311+
312+
fn is_sign_negative<const LANES: usize>() {
313+
test_helpers::test_unary_mask_elementwise(
314+
&Vector::<LANES>::is_sign_negative,
315+
&Scalar::is_sign_negative,
316+
&|_| true,
317+
);
318+
}
319+
320+
fn is_finite<const LANES: usize>() {
321+
test_helpers::test_unary_mask_elementwise(
322+
&Vector::<LANES>::is_finite,
323+
&Scalar::is_finite,
324+
&|_| true,
325+
);
326+
}
327+
328+
fn is_infinite<const LANES: usize>() {
329+
test_helpers::test_unary_mask_elementwise(
330+
&Vector::<LANES>::is_infinite,
331+
&Scalar::is_infinite,
332+
&|_| true,
333+
);
334+
}
335+
336+
fn is_nan<const LANES: usize>() {
337+
test_helpers::test_unary_mask_elementwise(
338+
&Vector::<LANES>::is_nan,
339+
&Scalar::is_nan,
340+
&|_| true,
341+
);
342+
}
343+
344+
fn is_normal<const LANES: usize>() {
345+
test_helpers::test_unary_mask_elementwise(
346+
&Vector::<LANES>::is_normal,
347+
&Scalar::is_normal,
348+
&|_| true,
349+
);
350+
}
351+
352+
fn is_subnormal<const LANES: usize>() {
353+
test_helpers::test_unary_mask_elementwise(
354+
&Vector::<LANES>::is_subnormal,
355+
&Scalar::is_subnormal,
356+
&|_| true,
357+
);
358+
}
359+
288360
fn abs<const LANES: usize>() {
289361
test_helpers::test_unary_elementwise(
290362
&Vector::<LANES>::abs,

‎crates/test_helpers/src/biteq.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ pub trait BitEq {
55
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result;
66
}
77

8+
impl BitEq for bool {
9+
fn biteq(&self, other: &Self) -> bool {
10+
self == other
11+
}
12+
13+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
14+
write!(f, "{:?}", self)
15+
}
16+
}
17+
818
macro_rules! impl_integer_biteq {
919
{ $($type:ty),* } => {
1020
$(

‎crates/test_helpers/src/lib.rs

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,32 @@ pub fn test_unary_elementwise<Scalar, ScalarResult, Vector, VectorResult, const
124124
});
125125
}
126126

127+
/// Test a unary vector function against a unary scalar function, applied elementwise.
128+
#[inline(never)]
129+
pub fn test_unary_mask_elementwise<Scalar, Vector, Mask, const LANES: usize>(
130+
fv: &dyn Fn(Vector) -> Mask,
131+
fs: &dyn Fn(Scalar) -> bool,
132+
check: &dyn Fn([Scalar; LANES]) -> bool,
133+
) where
134+
Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy,
135+
Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy,
136+
Mask: Into<[bool; LANES]> + From<[bool; LANES]> + Copy,
137+
{
138+
test_1(&|x: [Scalar; LANES]| {
139+
proptest::prop_assume!(check(x));
140+
let result_1: [bool; LANES] = fv(x.into()).into();
141+
let result_2: [bool; LANES] = {
142+
let mut result = [false; LANES];
143+
for (i, o) in x.iter().zip(result.iter_mut()) {
144+
*o = fs(*i);
145+
}
146+
result
147+
};
148+
crate::prop_assert_biteq!(result_1, result_2);
149+
Ok(())
150+
});
151+
}
152+
127153
/// Test a binary vector function against a binary scalar function, applied elementwise.
128154
#[inline(never)]
129155
pub fn test_binary_elementwise<
@@ -243,21 +269,21 @@ macro_rules! test_lanes {
243269

244270
fn implementation<const $lanes: usize>()
245271
where
246-
core_simd::SimdU8<$lanes>: core_simd::LanesAtMost64,
247-
core_simd::SimdU16<$lanes>: core_simd::LanesAtMost64,
248-
core_simd::SimdU32<$lanes>: core_simd::LanesAtMost64,
249-
core_simd::SimdU64<$lanes>: core_simd::LanesAtMost64,
250-
core_simd::SimdU128<$lanes>: core_simd::LanesAtMost64,
251-
core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost64,
252-
core_simd::SimdI8<$lanes>: core_simd::LanesAtMost64,
253-
core_simd::SimdI16<$lanes>: core_simd::LanesAtMost64,
254-
core_simd::SimdI32<$lanes>: core_simd::LanesAtMost64,
255-
core_simd::SimdI64<$lanes>: core_simd::LanesAtMost64,
256-
core_simd::SimdI128<$lanes>: core_simd::LanesAtMost64,
257-
core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost64,
258-
core_simd::SimdF32<$lanes>: core_simd::LanesAtMost64,
259-
core_simd::SimdF64<$lanes>: core_simd::LanesAtMost64,
260-
core_simd::BitMask<$lanes>: core_simd::LanesAtMost64,
272+
core_simd::SimdU8<$lanes>: core_simd::LanesAtMost32,
273+
core_simd::SimdU16<$lanes>: core_simd::LanesAtMost32,
274+
core_simd::SimdU32<$lanes>: core_simd::LanesAtMost32,
275+
core_simd::SimdU64<$lanes>: core_simd::LanesAtMost32,
276+
core_simd::SimdU128<$lanes>: core_simd::LanesAtMost32,
277+
core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost32,
278+
core_simd::SimdI8<$lanes>: core_simd::LanesAtMost32,
279+
core_simd::SimdI16<$lanes>: core_simd::LanesAtMost32,
280+
core_simd::SimdI32<$lanes>: core_simd::LanesAtMost32,
281+
core_simd::SimdI64<$lanes>: core_simd::LanesAtMost32,
282+
core_simd::SimdI128<$lanes>: core_simd::LanesAtMost32,
283+
core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost32,
284+
core_simd::SimdF32<$lanes>: core_simd::LanesAtMost32,
285+
core_simd::SimdF64<$lanes>: core_simd::LanesAtMost32,
286+
core_simd::BitMask<$lanes>: core_simd::LanesAtMost32,
261287
$body
262288

263289
#[cfg(target_arch = "wasm32")]
@@ -298,16 +324,10 @@ macro_rules! test_lanes {
298324
fn lanes_32() {
299325
implementation::<32>();
300326
}
301-
302-
#[test]
303-
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
304-
fn lanes_64() {
305-
implementation::<64>();
306-
}
307327
}
308328
)*
309329
}
310-
}
330+
}
311331

312332
/// Expand a const-generic `#[should_panic]` test into separate tests for each possible lane count.
313333
#[macro_export]
@@ -321,21 +341,21 @@ macro_rules! test_lanes_panic {
321341

322342
fn implementation<const $lanes: usize>()
323343
where
324-
core_simd::SimdU8<$lanes>: core_simd::LanesAtMost64,
325-
core_simd::SimdU16<$lanes>: core_simd::LanesAtMost64,
326-
core_simd::SimdU32<$lanes>: core_simd::LanesAtMost64,
327-
core_simd::SimdU64<$lanes>: core_simd::LanesAtMost64,
328-
core_simd::SimdU128<$lanes>: core_simd::LanesAtMost64,
329-
core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost64,
330-
core_simd::SimdI8<$lanes>: core_simd::LanesAtMost64,
331-
core_simd::SimdI16<$lanes>: core_simd::LanesAtMost64,
332-
core_simd::SimdI32<$lanes>: core_simd::LanesAtMost64,
333-
core_simd::SimdI64<$lanes>: core_simd::LanesAtMost64,
334-
core_simd::SimdI128<$lanes>: core_simd::LanesAtMost64,
335-
core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost64,
336-
core_simd::SimdF32<$lanes>: core_simd::LanesAtMost64,
337-
core_simd::SimdF64<$lanes>: core_simd::LanesAtMost64,
338-
core_simd::BitMask<$lanes>: core_simd::LanesAtMost64,
344+
core_simd::SimdU8<$lanes>: core_simd::LanesAtMost32,
345+
core_simd::SimdU16<$lanes>: core_simd::LanesAtMost32,
346+
core_simd::SimdU32<$lanes>: core_simd::LanesAtMost32,
347+
core_simd::SimdU64<$lanes>: core_simd::LanesAtMost32,
348+
core_simd::SimdU128<$lanes>: core_simd::LanesAtMost32,
349+
core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost32,
350+
core_simd::SimdI8<$lanes>: core_simd::LanesAtMost32,
351+
core_simd::SimdI16<$lanes>: core_simd::LanesAtMost32,
352+
core_simd::SimdI32<$lanes>: core_simd::LanesAtMost32,
353+
core_simd::SimdI64<$lanes>: core_simd::LanesAtMost32,
354+
core_simd::SimdI128<$lanes>: core_simd::LanesAtMost32,
355+
core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost32,
356+
core_simd::SimdF32<$lanes>: core_simd::LanesAtMost32,
357+
core_simd::SimdF64<$lanes>: core_simd::LanesAtMost32,
358+
core_simd::BitMask<$lanes>: core_simd::LanesAtMost32,
339359
$body
340360

341361
#[test]
@@ -373,13 +393,7 @@ macro_rules! test_lanes_panic {
373393
fn lanes_32() {
374394
implementation::<32>();
375395
}
376-
377-
#[test]
378-
#[should_panic]
379-
fn lanes_64() {
380-
implementation::<64>();
381-
}
382396
}
383397
)*
384398
}
385-
}
399+
}

0 commit comments

Comments
 (0)
This repository has been archived.