core::arch::x86::_mm_cmpistri - Rust
Description: API documentation for the Rust `_mm_cmpistri` fn in crate `core`.
Keywords: rust, rustlang, rust-lang, _mm_cmpistri

# 1.27.0[−][src]Function core::arch::x86::_mm_cmpistri

    pub unsafe fn _mm_cmpistri(a: __m128i, b: __m128i, imm8: i32) -> i32

This is supported on x86 and target feature `sse4.2` only.

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

- `_SIDD_UBYTE_OPS` - Default
- `_SIDD_UWORD_OPS`
- `_SIDD_SBYTE_OPS`
- `_SIDD_SWORD_OPS`

## Comparison options

- `_SIDD_CMP_EQUAL_ANY` - Default
- `_SIDD_CMP_RANGES`
- `_SIDD_CMP_EQUAL_EACH`
- `_SIDD_CMP_EQUAL_ORDERED`

## Result polarity

- `_SIDD_POSITIVE_POLARITY` - Default
- `_SIDD_NEGATIVE_POLARITY`

## Bit returned

- `_SIDD_LEAST_SIGNIFICANT` - Default
- `_SIDD_MOST_SIGNIFICANT`

# 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]);

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

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");
    }

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

Intel's documentation