pub unsafe fn _mm_cmpistri(a: __m128i, b: __m128i, const IMM8: i32) -> i32
Available on (x86 or x86-64) and target feature
sse4.2
and x86-64 only.Expand description
Compares packed strings with implicit lengths in a
and b
using the
control in IMM8
and return the generated index. Similar to
_mm_cmpestri
with the exception that _mm_cmpestri
requires the
lengths of a
and b
to be explicitly specified.
§Control modes
The control specified by IMM8
may be one or more of the following.
§Data size and signedness
§Comparison options
§Result polarity
§Bit returned
§Examples
Finds a substring using _SIDD_CMP_EQUAL_ORDERED
#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
let haystack = b"This is a long string of text data\r\n\tthat extends
multiple lines";
let needle = b"\r\n\t\0\0\0\0\0\0\0\0\0\0\0\0\0";
let a = _mm_loadu_si128(needle.as_ptr() as *const _);
let hop = 16;
let mut indexes = Vec::new();
// Chunk the haystack into 16 byte chunks and find
// the first "\r\n\t" in the chunk.
for (i, chunk) in haystack.chunks(hop).enumerate() {
let b = _mm_loadu_si128(chunk.as_ptr() as *const _);
let idx = _mm_cmpistri(a, b, _SIDD_CMP_EQUAL_ORDERED);
if idx != 16 {
indexes.push((idx as usize) + (i * hop));
}
}
assert_eq!(indexes, vec![34]);
The _mm_cmpistri
intrinsic may also be used to find the existence of
one or more of a given set of characters in the haystack.
#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
// Ensure your input is 16 byte aligned
let password = b"hunter2\0\0\0\0\0\0\0\0\0";
let special_chars = b"!@#$%^&*()[]:;<>";
// Load the input
let a = _mm_loadu_si128(special_chars.as_ptr() as *const _);
let b = _mm_loadu_si128(password.as_ptr() as *const _);
// Use _SIDD_CMP_EQUAL_ANY to find the index of any bytes in b
let idx = _mm_cmpistri(a.into(), b.into(), _SIDD_CMP_EQUAL_ANY);
if idx < 16 {
println!("Congrats! Your password contains a special character");
} else {
println!("Your password should contain a special character");
}
Finds the index of the first character in the haystack that is within a range of characters.
#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
// Specify the ranges of values to be searched for [A-Za-z0-9].
let a = b"AZaz09\0\0\0\0\0\0\0\0\0\0";
let a = _mm_loadu_si128(a.as_ptr() as *const _);
// Use _SIDD_CMP_RANGES to find the index of first byte in ranges.
// Which in this case will be the first alpha numeric byte found
// in the string.
let idx = _mm_cmpistri(a, b, _SIDD_CMP_RANGES);
if idx < 16 {
println!("Found an alpha numeric character");
} else {
println!("Did not find an alpha numeric character");
}
Working with 16-bit characters.
#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
// Load the input
let a = _mm_loadu_si128(some_utf16_words.as_ptr() as *const _);
let b = _mm_loadu_si128(more_utf16_words.as_ptr() as *const _);
// Specify _SIDD_UWORD_OPS to compare words instead of bytes, and
// use _SIDD_CMP_EQUAL_EACH to compare the two strings.
let idx = _mm_cmpistri(a, b, _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH);
if idx == 0 {
println!("16-bit unicode strings were equal!");
} else {
println!("16-bit unicode strings were not equal!");
}