1.27.0[−][src]Function core::arch::x86_64::_mm_cmpistri
pub unsafe fn _mm_cmpistri(a: __m128i, b: __m128i, imm8: i32) -> i32
This is supported on x86-64 and target feature
sse4.2
only.Compare 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
Find 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]);Run
The _mm_cmpistri
intrinsic may also be used to find the existance 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"); }Run
Find 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"); }Run
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!"); }Run