#[cfg(feature = "verus")]
use crate::spec::*;
#[cfg(feature = "verus")]
use verus_builtin_macros::{proof, verus_spec, verus_verify};
#[cfg(feature = "verus")]
#[allow(unused_imports)]
use vstd::prelude::*;
#[cfg(all(
target_arch = "x86_64",
target_feature = "avx2",
not(feature = "verus")
))]
mod imp {
use core::arch::x86_64::{_mm256_loadu_si256, _mm256_movemask_epi8};
pub const STEP: usize = 32;
#[inline]
pub fn skip(buf: &[u8], start: usize, end: usize) -> usize {
let mut p = start;
while end - p >= STEP {
let v = unsafe { _mm256_loadu_si256(buf.as_ptr().add(p).cast()) };
let m = unsafe { _mm256_movemask_epi8(v) } as u32;
if m != 0 {
return p + m.trailing_zeros() as usize;
}
p += STEP;
}
p
}
}
#[cfg(all(
target_arch = "aarch64",
target_feature = "neon",
not(feature = "verus")
))]
mod imp {
use core::arch::aarch64::{vld1q_u8, vmaxvq_u8, vorrq_u8};
pub const STEP: usize = 32;
#[inline]
pub fn skip(buf: &[u8], start: usize, end: usize) -> usize {
let mut p = start;
while end - p >= STEP {
let a = unsafe { vld1q_u8(buf.as_ptr().add(p)) };
let b = unsafe { vld1q_u8(buf.as_ptr().add(p + 16)) };
if unsafe { vmaxvq_u8(vorrq_u8(a, b)) } >= 0x80 {
return p;
}
p += STEP;
}
p
}
}
#[cfg(not(any(
all(
target_arch = "x86_64",
target_feature = "avx2",
not(feature = "verus")
),
all(
target_arch = "aarch64",
target_feature = "neon",
not(feature = "verus")
),
)))]
mod imp {
#[allow(unused_imports)]
use super::*;
use crate::{load64, SIGN_BITS};
#[cfg_attr(feature = "verus", verus_verify)]
pub const STEP: usize = 16;
#[cfg_attr(feature = "verus", verus_spec(q =>
requires start <= end, end <= buf@.len(),
ensures start <= q, q <= end, all_ascii(buf@, start as int, q as int),
))]
#[inline]
pub fn skip(buf: &[u8], start: usize, end: usize) -> usize {
let mut p = start;
#[cfg_attr(feature = "verus", verus_spec(
invariant
start <= p, p <= end, end <= buf@.len(),
all_ascii(buf@, start as int, p as int),
decreases end - p
))]
while end - p >= STEP {
let a = unsafe { load64(buf, p) };
let b = unsafe { load64(buf, p + 8) };
if (a | b) & SIGN_BITS != 0 {
return p;
}
#[cfg(feature = "verus")]
proof! {
lemma_signbits16(buf@, p as int);
lemma_ascii_extend(buf@, start as int, p as int, p as int + 16);
}
p += STEP;
}
p
}
}
pub use imp::{skip, STEP};