#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
use crate::{DelimiterResult, classify_byte};
#[target_feature(enable = "sse4.2")]
#[cfg(target_arch = "x86_64")]
pub unsafe fn find_delimiters(haystack: &[u8]) -> DelimiterResult {
let len = haystack.len();
let ptr = haystack.as_ptr();
let mut offset = 0;
unsafe {
let lt = _mm_set1_epi8(b'<' as i8);
let gt = _mm_set1_epi8(b'>' as i8);
let amp = _mm_set1_epi8(b'&' as i8);
let quot = _mm_set1_epi8(b'"' as i8);
let apos = _mm_set1_epi8(b'\'' as i8);
let eq = _mm_set1_epi8(b'=' as i8);
let slash = _mm_set1_epi8(b'/' as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(ptr.add(offset) as *const __m128i);
let m = _mm_or_si128(
_mm_or_si128(
_mm_or_si128(_mm_cmpeq_epi8(chunk, lt), _mm_cmpeq_epi8(chunk, gt)),
_mm_or_si128(_mm_cmpeq_epi8(chunk, amp), _mm_cmpeq_epi8(chunk, quot)),
),
_mm_or_si128(
_mm_or_si128(_mm_cmpeq_epi8(chunk, apos), _mm_cmpeq_epi8(chunk, eq)),
_mm_cmpeq_epi8(chunk, slash),
),
);
let mask = _mm_movemask_epi8(m) as u16;
if mask != 0 {
let pos = offset + mask.trailing_zeros() as usize;
return DelimiterResult::Found {
pos,
byte: *ptr.add(pos),
};
}
offset += 16;
}
}
crate::scalar::find_delimiters_safe(&haystack[offset..]).offset_by(offset)
}
#[target_feature(enable = "sse4.2")]
#[cfg(target_arch = "x86_64")]
pub unsafe fn classify_bytes(input: &[u8]) -> Vec<u8> {
let len = input.len();
let mut result = Vec::with_capacity(len);
let ptr = input.as_ptr();
let out_ptr: *mut u8 = result.as_mut_ptr();
let mut offset = 0;
unsafe {
while offset + 16 <= len {
let chunk = _mm_loadu_si128(ptr.add(offset) as *const __m128i);
let space = _mm_set1_epi8(b' ' as i8);
let tab = _mm_set1_epi8(b'\t' as i8);
let nl = _mm_set1_epi8(b'\n' as i8);
let cr = _mm_set1_epi8(b'\r' as i8);
let ws_mask = _mm_or_si128(
_mm_or_si128(_mm_cmpeq_epi8(chunk, space), _mm_cmpeq_epi8(chunk, tab)),
_mm_or_si128(_mm_cmpeq_epi8(chunk, nl), _mm_cmpeq_epi8(chunk, cr)),
);
let or_mask = _mm_set1_epi8(0x20);
let lower = _mm_or_si128(chunk, or_mask); let a_val = _mm_set1_epi8(b'a' as i8);
let sub = _mm_sub_epi8(lower, a_val); let bound = _mm_set1_epi8(25); let clamped = _mm_min_epu8(sub, bound);
let alpha_mask = _mm_cmpeq_epi8(sub, clamped);
let zero = _mm_set1_epi8(b'0' as i8);
let sub_d = _mm_sub_epi8(chunk, zero);
let dbound = _mm_set1_epi8(9);
let dclamped = _mm_min_epu8(sub_d, dbound);
let digit_mask = _mm_cmpeq_epi8(sub_d, dclamped);
let lt = _mm_set1_epi8(b'<' as i8);
let gt = _mm_set1_epi8(b'>' as i8);
let amp = _mm_set1_epi8(b'&' as i8);
let quot = _mm_set1_epi8(b'"' as i8);
let apos = _mm_set1_epi8(b'\'' as i8);
let eq = _mm_set1_epi8(b'=' as i8);
let slash = _mm_set1_epi8(b'/' as i8);
let delim_mask = _mm_or_si128(
_mm_or_si128(
_mm_or_si128(_mm_cmpeq_epi8(chunk, lt), _mm_cmpeq_epi8(chunk, gt)),
_mm_or_si128(_mm_cmpeq_epi8(chunk, amp), _mm_cmpeq_epi8(chunk, quot)),
),
_mm_or_si128(
_mm_or_si128(_mm_cmpeq_epi8(chunk, apos), _mm_cmpeq_epi8(chunk, eq)),
_mm_cmpeq_epi8(chunk, slash),
),
);
let ws_class = _mm_and_si128(ws_mask, _mm_set1_epi8(crate::class::WHITESPACE as i8));
let al_class = _mm_and_si128(alpha_mask, _mm_set1_epi8(crate::class::ALPHA as i8));
let di_class = _mm_and_si128(digit_mask, _mm_set1_epi8(crate::class::DIGIT as i8));
let de_class = _mm_and_si128(delim_mask, _mm_set1_epi8(crate::class::DELIMITER as i8));
let combined = _mm_or_si128(
_mm_or_si128(ws_class, al_class),
_mm_or_si128(di_class, de_class),
);
_mm_storeu_si128(out_ptr.add(offset) as *mut __m128i, combined);
offset += 16;
}
while offset < len {
*out_ptr.add(offset) = classify_byte(*ptr.add(offset));
offset += 1;
}
result.set_len(len);
}
result
}
#[target_feature(enable = "sse4.2")]
#[cfg(target_arch = "x86_64")]
pub unsafe fn skip_whitespace(input: &[u8]) -> usize {
let len = input.len();
let ptr = input.as_ptr();
let mut offset = 0;
unsafe {
let space = _mm_set1_epi8(b' ' as i8);
let tab = _mm_set1_epi8(b'\t' as i8);
let nl = _mm_set1_epi8(b'\n' as i8);
let cr = _mm_set1_epi8(b'\r' as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(ptr.add(offset) as *const __m128i);
let ws = _mm_or_si128(
_mm_or_si128(_mm_cmpeq_epi8(chunk, space), _mm_cmpeq_epi8(chunk, tab)),
_mm_or_si128(_mm_cmpeq_epi8(chunk, nl), _mm_cmpeq_epi8(chunk, cr)),
);
let mask = _mm_movemask_epi8(ws) as u16;
if mask != 0xFFFF {
return offset + (!mask).trailing_zeros() as usize;
}
offset += 16;
}
}
offset + crate::scalar::skip_whitespace_safe(&input[offset..])
}
#[target_feature(enable = "sse4.2")]
#[cfg(target_arch = "x86_64")]
pub unsafe fn compute_byte_mask(block: &[u8], byte: u8) -> u64 {
let len = block.len().min(64);
let ptr = block.as_ptr();
let mut result: u64 = 0;
let mut offset = 0;
unsafe {
let target = _mm_set1_epi8(byte as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(ptr.add(offset) as *const __m128i);
let cmp = _mm_cmpeq_epi8(chunk, target);
let mask = _mm_movemask_epi8(cmp) as u16;
result |= (mask as u64) << offset;
offset += 16;
}
}
while offset < len {
if unsafe { *ptr.add(offset) } == byte {
result |= 1u64 << offset;
}
offset += 1;
}
result
}
#[cfg(all(test, target_arch = "x86_64"))]
mod tests {
use super::*;
use crate::class;
fn has_sse42() -> bool {
is_x86_feature_detected!("sse4.2")
}
#[test]
fn find_delimiters_basic() {
if !has_sse42() {
return;
}
let input = b"hello world <div>";
let result = unsafe { find_delimiters(input) };
assert_eq!(
result,
DelimiterResult::Found {
pos: 12,
byte: b'<'
}
);
}
#[test]
fn find_delimiters_not_found() {
if !has_sse42() {
return;
}
let input = b"hello world no delimiters here";
let result = unsafe { find_delimiters(input) };
assert_eq!(result, DelimiterResult::NotFound);
}
#[test]
fn classify_bytes_basic() {
if !has_sse42() {
return;
}
let input = b"a1 <b2\t>Zz09&\"'/=\nhello world...";
let result = unsafe { classify_bytes(input) };
assert_eq!(result[0], class::ALPHA);
assert_eq!(result[1], class::DIGIT);
assert_eq!(result[2], class::WHITESPACE);
assert_eq!(result[3], class::DELIMITER);
}
#[test]
fn skip_whitespace_basic() {
if !has_sse42() {
return;
}
let result = unsafe { skip_whitespace(b" \t\nhello") };
assert_eq!(result, 5);
}
#[test]
fn skip_whitespace_all_ws() {
if !has_sse42() {
return;
}
let result = unsafe { skip_whitespace(b" ") };
assert_eq!(result, 20);
}
#[test]
fn find_delimiters_after_nul_in_simd_block() {
if !has_sse42() {
return;
}
let input = b"abc\0def<ghijklmn"; let result = unsafe { find_delimiters(input) };
assert_eq!(result, DelimiterResult::Found { pos: 7, byte: b'<' });
}
#[test]
fn skip_whitespace_stops_at_nul() {
if !has_sse42() {
return;
}
let input = b" \0Xhelloworld!"; let result = unsafe { skip_whitespace(input) };
assert_eq!(result, 3);
}
}