#[target_feature(enable = "avx2")]
#[allow(unused_unsafe)]
pub unsafe fn scan_quote_or_backslash(input: &[u8]) -> usize {
use core::arch::x86_64::*;
let quote = unsafe { _mm256_set1_epi8(b'"' as i8) };
let backslash = unsafe { _mm256_set1_epi8(b'\\' as i8) };
let mut i = 0usize;
while i + 32 <= input.len() {
let chunk = unsafe { _mm256_loadu_si256(input.as_ptr().add(i) as *const __m256i) };
let eq_q = unsafe { _mm256_cmpeq_epi8(chunk, quote) };
let eq_bs = unsafe { _mm256_cmpeq_epi8(chunk, backslash) };
let mask = unsafe { _mm256_movemask_epi8(_mm256_or_si256(eq_q, eq_bs)) as u32 };
if mask != 0 {
return i + mask.trailing_zeros() as usize;
}
i += 32;
}
i + super::scalar::scan_quote_or_backslash(&input[i..])
}
#[target_feature(enable = "avx2")]
#[allow(unused_unsafe)]
pub unsafe fn skip_whitespace(input: &[u8]) -> usize {
use core::arch::x86_64::*;
let sp = unsafe { _mm256_set1_epi8(b' ' as i8) };
let tab = unsafe { _mm256_set1_epi8(b'\t' as i8) };
let lf = unsafe { _mm256_set1_epi8(b'\n' as i8) };
let cr = unsafe { _mm256_set1_epi8(b'\r' as i8) };
let mut i = 0usize;
while i + 32 <= input.len() {
let chunk = unsafe { _mm256_loadu_si256(input.as_ptr().add(i) as *const __m256i) };
let is_sp = unsafe { _mm256_cmpeq_epi8(chunk, sp) };
let is_tab = unsafe { _mm256_cmpeq_epi8(chunk, tab) };
let is_lf = unsafe { _mm256_cmpeq_epi8(chunk, lf) };
let is_cr = unsafe { _mm256_cmpeq_epi8(chunk, cr) };
let is_ws = unsafe {
_mm256_or_si256(
_mm256_or_si256(is_sp, is_tab),
_mm256_or_si256(is_lf, is_cr),
)
};
let mask = unsafe { _mm256_movemask_epi8(is_ws) as u32 };
if mask != 0xFFFF_FFFF {
return i + (!mask).trailing_zeros() as usize;
}
i += 32;
}
i + super::scalar::skip_whitespace(&input[i..])
}
#[target_feature(enable = "avx2")]
#[allow(unused_unsafe)]
pub unsafe fn is_all_ascii(input: &[u8]) -> bool {
use core::arch::x86_64::*;
let mut i = 0usize;
let mut acc = unsafe { _mm256_setzero_si256() };
while i + 32 <= input.len() {
let chunk = unsafe { _mm256_loadu_si256(input.as_ptr().add(i) as *const __m256i) };
acc = unsafe { _mm256_or_si256(acc, chunk) };
i += 32;
}
let mask = unsafe { _mm256_movemask_epi8(acc) };
if mask != 0 {
return false;
}
input[i..].iter().all(|b| b.is_ascii())
}