Function core::arch::x86::_mm_cmpistri

1.27.0 · source ·
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 only.
Expand description

使用 IMM8 中的控件比较 ab 中隐含长度的包装字符串,并返回生成的索引。 与 _mm_cmpestri 相似,不同之处在于 _mm_cmpestri 需要明确指定 ab 的长度。

控制方式

IMM8 指定的控件可以是以下一种或多种。

数据大小和签名

比较选项

结果极性

返回位

Examples

使用 _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();

// 将 haystack 分成 16 个字节的块,并在该块中找到第一个 "\r\n\t"。
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

_mm_cmpistri 内部函数也可用于在 haystack 中查找一个或多个给定字符集的存在。

#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;

// 确保您的输入是 16 字节对齐的
let password = b"hunter2\0\0\0\0\0\0\0\0\0";
let special_chars = b"!@#$%^&*()[]:;<>";

// 加载输入
let a = _mm_loadu_si128(special_chars.as_ptr() as *const _);
let b = _mm_loadu_si128(password.as_ptr() as *const _);

// 使用 _SIDD_CMP_EQUAL_ANY 查找 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

查找字符范围内的 haystack 中第一个字符的索引。

#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;


// 指定要搜索的值的范围 [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 _);

// 使用 _SIDD_CMP_RANGES 查找范围内第一个字节的索引。
// 在这种情况下,它将是字符串中找到的第一个字母数字字节。
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

使用 16 位字符。

#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;

// 加载输入
let a = _mm_loadu_si128(some_utf16_words.as_ptr() as *const _);
let b = _mm_loadu_si128(more_utf16_words.as_ptr() as *const _);

// 指定 _SIDD_UWORD_OPS 以比较单词而不是字节,并使用 _SIDD_CMP_EQUAL_EACH 比较两个字符串。
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