@@ -58,7 +58,9 @@ pub unsafe fn _mm_cmpistrm(
58
58
}
59
59
60
60
/// Compare packed strings with implicit lengths in `a` and `b` using the
61
- /// control in `imm8`, and return the generated index.
61
+ /// control in `imm8`, and return the generated index. Similar to [`_mm_cmpestri`]
62
+ /// with the excception that [`_mm_cmpestri`] requires the lengths of `a` and
63
+ /// `b` to be explicitly specified.
62
64
///
63
65
/// # Control modes
64
66
///
@@ -87,6 +89,8 @@ pub unsafe fn _mm_cmpistrm(
87
89
///
88
90
/// # Examples
89
91
///
92
+ /// Find a substring using [`_SIDD_CMP_EQUAL_ORDERED`]
93
+ ///
90
94
/// ```
91
95
/// # #![feature(cfg_target_feature)]
92
96
/// # #![feature(target_feature)]
@@ -126,6 +130,89 @@ pub unsafe fn _mm_cmpistrm(
126
130
/// # }
127
131
/// ```
128
132
///
133
+ /// The `_mm_cmpistri` intrinsic may also be used to find the existance of
134
+ /// one or more of a given set of characters in the haystack.
135
+ ///
136
+ /// ```
137
+ /// # #![feature(cfg_target_feature)]
138
+ /// # #![feature(target_feature)]
139
+ /// #
140
+ /// # #[macro_use] extern crate stdsimd;
141
+ /// #
142
+ /// # fn main() {
143
+ /// # if cfg_feature_enabled!("sse4.2") {
144
+ /// # #[target_feature = "+sse4.2"]
145
+ /// # fn worker() {
146
+ /// use stdsimd::simd::u8x16;
147
+ /// use stdsimd::vendor::{__m128i, _mm_cmpistri, _SIDD_CMP_EQUAL_ANY};
148
+ ///
149
+ /// // Ensure your input is 16 byte aligned
150
+ /// let password = b"hunter2\0\0\0\0\0\0\0\0\0";
151
+ /// let special_chars = b"!@#$%^&*()[]:;<>";
152
+ ///
153
+ /// // Load the input
154
+ /// let a = __m128i::from(u8x16::load(special_chars, 0));
155
+ /// let b = __m128i::from(u8x16::load(password, 0));
156
+ ///
157
+ /// // Use _SIDD_CMP_EQUAL_ANY to find the index of any bytes in b
158
+ /// let idx = unsafe {
159
+ /// _mm_cmpistri(a, b, _SIDD_CMP_EQUAL_ANY)
160
+ /// };
161
+ ///
162
+ /// if idx < 16 {
163
+ /// println!("Congrats! Your password contains a special character");
164
+ /// # panic!("{:?} does not contain a special character", password);
165
+ /// } else {
166
+ /// println!("Your password should contain a special character");
167
+ /// }
168
+ /// # }
169
+ /// # worker();
170
+ /// # }
171
+ /// # }
172
+ /// ```
173
+ ///
174
+ /// Working with 16-bit characters.
175
+ ///
176
+ /// ```
177
+ /// # #![feature(cfg_target_feature)]
178
+ /// # #![feature(target_feature)]
179
+ /// #
180
+ /// # #[macro_use] extern crate stdsimd;
181
+ /// #
182
+ /// # fn main() {
183
+ /// # if cfg_feature_enabled!("sse4.2") {
184
+ /// # #[target_feature = "+sse4.2"]
185
+ /// # fn worker() {
186
+ /// use stdsimd::simd::u16x8;
187
+ /// use stdsimd::vendor::{__m128i, _mm_cmpistri};
188
+ /// use stdsimd::vendor::{_SIDD_UWORD_OPS, _SIDD_CMP_EQUAL_EACH};
189
+ ///
190
+ /// # let mut some_utf16_words = [0u16; 8];
191
+ /// # let mut more_utf16_words = [0u16; 8];
192
+ /// # '❤'.encode_utf16(&mut some_utf16_words);
193
+ /// # '𝕊'.encode_utf16(&mut more_utf16_words);
194
+ /// // Load the input
195
+ /// let a = __m128i::from(u16x8::load(&some_utf16_words, 0));
196
+ /// let b = __m128i::from(u16x8::load(&more_utf16_words, 0));
197
+ ///
198
+ /// // Specify _SIDD_UWORD_OPS to compare words instead of bytes, and
199
+ /// // use _SIDD_CMP_EQUAL_EACH to compare the two strings.
200
+ /// let idx = unsafe {
201
+ /// _mm_cmpistri(a, b, _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH)
202
+ /// };
203
+ ///
204
+ /// if idx == 0 {
205
+ /// println!("16-bit unicode strings were equal!");
206
+ /// # panic!("Strings should not be equal!")
207
+ /// } else {
208
+ /// println!("16-bit unicode strings were not equal!");
209
+ /// }
210
+ /// # }
211
+ /// # worker();
212
+ /// # }
213
+ /// # }
214
+ /// ```
215
+ ///
129
216
/// [`_SIDD_UBYTE_OPS`]: constant._SIDD_UBYTE_OPS.html
130
217
/// [`_SIDD_UWORD_OPS`]: constant._SIDD_UWORD_OPS.html
131
218
/// [`_SIDD_SBYTE_OPS`]: constant._SIDD_SBYTE_OPS.html
@@ -138,6 +225,7 @@ pub unsafe fn _mm_cmpistrm(
138
225
/// [`_SIDD_NEGATIVE_POLARITY`]: constant._SIDD_NEGATIVE_POLARITY.html
139
226
/// [`_SIDD_LEAST_SIGNIFICANT`]: constant._SIDD_LEAST_SIGNIFICANT.html
140
227
/// [`_SIDD_MOST_SIGNIFICANT`]: constant._SIDD_MOST_SIGNIFICANT.html
228
+ /// [`_mm_cmpestri`]: fn._mm_cmpestri.html
141
229
#[ inline( always) ]
142
230
#[ target_feature = "+sse4.2" ]
143
231
#[ cfg_attr( test, assert_instr( pcmpistri, imm8 = 0 ) ) ]
@@ -255,7 +343,87 @@ pub unsafe fn _mm_cmpestrm(
255
343
}
256
344
257
345
/// Compare packed strings `a` and `b` with lengths `la` and `lb` using the
258
- /// control in `imm8`, and return the generated index.
346
+ /// control in `imm8`, and return the generated index. Similar to [`_mm_cmpistri`]
347
+ /// with the excception that [`_mm_cmpistri`] implicityly determines the length of
348
+ /// `a` and `b`.
349
+ ///
350
+ /// # Control modes
351
+ ///
352
+ /// The control specified by `imm8` may be one or more of the following.
353
+ ///
354
+ /// ## Data size and signedness
355
+ ///
356
+ /// - [`_SIDD_UBYTE_OPS`] - Default
357
+ /// - [`_SIDD_UWORD_OPS`]
358
+ /// - [`_SIDD_SBYTE_OPS`]
359
+ /// - [`_SIDD_SWORD_OPS`]
360
+ ///
361
+ /// ## Comparison options
362
+ /// - [`_SIDD_CMP_EQUAL_ANY`] - Default
363
+ /// - [`_SIDD_CMP_RANGES`]
364
+ /// - [`_SIDD_CMP_EQUAL_EACH`]
365
+ /// - [`_SIDD_CMP_EQUAL_ORDERED`]
366
+ ///
367
+ /// ## Result polarity
368
+ /// - [`_SIDD_POSITIVE_POLARITY`] - Default
369
+ /// - [`_SIDD_NEGATIVE_POLARITY`]
370
+ ///
371
+ /// ## Bit returned
372
+ /// - [`_SIDD_LEAST_SIGNIFICANT`] - Default
373
+ /// - [`_SIDD_MOST_SIGNIFICANT`]
374
+ ///
375
+ /// # Examples
376
+ ///
377
+ /// ```
378
+ /// # #![feature(cfg_target_feature)]
379
+ /// # #![feature(target_feature)]
380
+ /// #
381
+ /// # #[macro_use] extern crate stdsimd;
382
+ /// #
383
+ /// # fn main() {
384
+ /// # if cfg_feature_enabled!("sse4.2") {
385
+ /// # #[target_feature = "+sse4.2"]
386
+ /// # fn worker() {
387
+ ///
388
+ /// use stdsimd::simd::u8x16;
389
+ /// use stdsimd::vendor::{__m128i, _mm_cmpestri, _SIDD_CMP_EQUAL_ORDERED};
390
+ ///
391
+ /// // The string we want to find a substring in
392
+ /// let haystack = b"Split \r\n\t line ";
393
+ ///
394
+ /// // The string we want to search for with some
395
+ /// // extra bytes we do not want to search for.
396
+ /// let needle = b"\r\n\t ignore this ";
397
+ ///
398
+ /// let a = __m128i::from(u8x16::load(needle, 0));
399
+ /// let b = __m128i::from(u8x16::load(haystack, 0));
400
+ ///
401
+ /// // Note: We explicitly specify we only want to search `b` for the
402
+ /// // first 3 characters of a.
403
+ /// let idx = unsafe {
404
+ /// _mm_cmpestri(a, 3, b, 15, _SIDD_CMP_EQUAL_ORDERED)
405
+ /// };
406
+ ///
407
+ /// assert_eq!(idx, 6);
408
+ /// # }
409
+ /// # worker();
410
+ /// # }
411
+ /// # }
412
+ /// ```
413
+ ///
414
+ /// [`_SIDD_UBYTE_OPS`]: constant._SIDD_UBYTE_OPS.html
415
+ /// [`_SIDD_UWORD_OPS`]: constant._SIDD_UWORD_OPS.html
416
+ /// [`_SIDD_SBYTE_OPS`]: constant._SIDD_SBYTE_OPS.html
417
+ /// [`_SIDD_SWORD_OPS`]: constant._SIDD_SWORD_OPS.html
418
+ /// [`_SIDD_CMP_EQUAL_ANY`]: constant._SIDD_CMP_EQUAL_ANY.html
419
+ /// [`_SIDD_CMP_RANGES`]: constant._SIDD_CMP_RANGES.html
420
+ /// [`_SIDD_CMP_EQUAL_EACH`]: constant._SIDD_CMP_EQUAL_EACH.html
421
+ /// [`_SIDD_CMP_EQUAL_ORDERED`]: constant._SIDD_CMP_EQUAL_ORDERED.html
422
+ /// [`_SIDD_POSITIVE_POLARITY`]: constant._SIDD_POSITIVE_POLARITY.html
423
+ /// [`_SIDD_NEGATIVE_POLARITY`]: constant._SIDD_NEGATIVE_POLARITY.html
424
+ /// [`_SIDD_LEAST_SIGNIFICANT`]: constant._SIDD_LEAST_SIGNIFICANT.html
425
+ /// [`_SIDD_MOST_SIGNIFICANT`]: constant._SIDD_MOST_SIGNIFICANT.html
426
+ /// [`_mm_cmpistri`]: fn._mm_cmpistri.html
259
427
#[ inline( always) ]
260
428
#[ target_feature = "+sse4.2" ]
261
429
#[ cfg_attr( test, assert_instr( pcmpestri, imm8 = 0 ) ) ]
0 commit comments