// Copyright Mozilla Foundation. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
use any_all_workaround::all_mask16x8; use any_all_workaround::all_mask8x16; use any_all_workaround::any_mask16x8; use any_all_workaround::any_mask8x16; use core::simd::cmp::SimdPartialEq; use core::simd::cmp::SimdPartialOrd; use core::simd::mask16x8; use core::simd::mask8x16; use core::simd::simd_swizzle; use core::simd::u16x8; use core::simd::u8x16; use core::simd::ToBytes;
/// Safety invariant: ptr must be valid for an unaligned read of 16 bytes #[inline(always)] pubunsafefn load16_unaligned(ptr: *const u8) -> u8x16 { letmut simd = ::core::mem::MaybeUninit::<u8x16>::uninit();
::core::ptr::copy_nonoverlapping(ptr, simd.as_mut_ptr() as *mut u8, 16); // Safety: copied 16 bytes of initialized memory into this, it is now initialized
simd.assume_init()
}
/// Safety invariant: ptr must be valid for an aligned-for-u8x16 read of 16 bytes #[allow(dead_code)] #[inline(always)] pubunsafefn load16_aligned(ptr: *const u8) -> u8x16 {
*(ptr as *const u8x16)
}
/// Safety invariant: ptr must be valid for an unaligned store of 16 bytes #[inline(always)] pubunsafefn store16_unaligned(ptr: *mut u8, s: u8x16) {
::core::ptr::copy_nonoverlapping(&s as *const u8x16 as *const u8, ptr, 16);
}
/// Safety invariant: ptr must be valid for an aligned-for-u8x16 store of 16 bytes #[allow(dead_code)] #[inline(always)] pubunsafefn store16_aligned(ptr: *mut u8, s: u8x16) {
*(ptr as *mut u8x16) = s;
}
/// Safety invariant: ptr must be valid for an unaligned read of 16 bytes #[inline(always)] pubunsafefn load8_unaligned(ptr: *const u16) -> u16x8 { letmut simd = ::core::mem::MaybeUninit::<u16x8>::uninit();
::core::ptr::copy_nonoverlapping(ptr as *const u8, simd.as_mut_ptr() as *mut u8, 16); // Safety: copied 16 bytes of initialized memory into this, it is now initialized
simd.assume_init()
}
/// Safety invariant: ptr must be valid for an aligned-for-u16x8 read of 16 bytes #[allow(dead_code)] #[inline(always)] pubunsafefn load8_aligned(ptr: *const u16) -> u16x8 {
*(ptr as *const u16x8)
}
/// Safety invariant: ptr must be valid for an unaligned store of 16 bytes #[inline(always)] pubunsafefn store8_unaligned(ptr: *mut u16, s: u16x8) {
::core::ptr::copy_nonoverlapping(&s as *const u16x8 as *const u8, ptr as *mut u8, 16);
}
/// Safety invariant: ptr must be valid for an aligned-for-u16x8 store of 16 bytes #[allow(dead_code)] #[inline(always)] pubunsafefn store8_aligned(ptr: *mut u16, s: u16x8) {
*(ptr as *mut u16x8) = s;
}
cfg_if! { if#[cfg(all(target_feature = "sse2", target_arch = "x86_64"))] { use core::arch::x86_64::__m128i; use core::arch::x86_64::_mm_movemask_epi8; use core::arch::x86_64::_mm_packus_epi16;
} elseif#[cfg(all(target_feature = "sse2", target_arch = "x86"))] { use core::arch::x86::__m128i; use core::arch::x86::_mm_movemask_epi8; use core::arch::x86::_mm_packus_epi16;
} elseif#[cfg(target_arch = "aarch64")]{ use core::arch::aarch64::vmaxvq_u8; use core::arch::aarch64::vmaxvq_u16;
} else {
// Expose low-level mask instead of higher-level conclusion, // because the non-ASCII case would perform less well otherwise. // Safety-usable invariant: This returned value is whether each high bit is set #[inline(always)] pubfn mask_ascii(s: u8x16) -> i32 { unsafe {
_mm_movemask_epi8(s.into())
}
}
} else {
}
}
cfg_if! { if#[cfg(target_feature = "sse2")] { #[inline(always)] pubfn simd_is_ascii(s: u8x16) -> bool { unsafe { // Safety: We have cfg()d the correct platform
_mm_movemask_epi8(s.into()) == 0
}
}
} elseif#[cfg(target_arch = "aarch64")]{ #[inline(always)] pubfn simd_is_ascii(s: u8x16) -> bool { unsafe { // Safety: We have cfg()d the correct platform
vmaxvq_u8(s.into()) < 0x80
}
}
} else { #[inline(always)] pubfn simd_is_ascii(s: u8x16) -> bool { // This optimizes better on ARM than // the lt formulation. let highest_ascii = u8x16::splat(0x7F);
!any_mask8x16(s.simd_gt(highest_ascii))
}
}
}
cfg_if! { if#[cfg(target_arch = "aarch64")]{ #[inline(always)] pubfn simd_is_basic_latin(s: u16x8) -> bool { unsafe { // Safety: We have cfg()d the correct platform
vmaxvq_u16(s.into()) < 0x80
}
}
#[inline(always)] pubfn simd_is_latin1(s: u16x8) -> bool { unsafe { // Safety: We have cfg()d the correct platform
vmaxvq_u16(s.into()) < 0x100
}
}
} else { #[inline(always)] pubfn simd_is_basic_latin(s: u16x8) -> bool { let above_ascii = u16x8::splat(0x80);
all_mask16x8(s.simd_lt(above_ascii))
}
#[inline(always)] pubfn simd_is_latin1(s: u16x8) -> bool { // For some reason, on SSE2 this formulation // seems faster in this case while the above // function is better the other way round... let highest_latin1 = u16x8::splat(0xFF);
!any_mask16x8(s.simd_gt(highest_latin1))
}
}
}
#[inline(always)] pubfn contains_surrogates(s: u16x8) -> bool { let mask = u16x8::splat(0xF800); let surrogate_bits = u16x8::splat(0xD800);
any_mask16x8((s & mask).simd_eq(surrogate_bits))
}
cfg_if! { if#[cfg(target_arch = "aarch64")]{
macro_rules! aarch64_return_false_if_below_hebrew {
($s:ident) => ({ unsafe { // Safety: We have cfg()d the correct platform if vmaxvq_u16($s.into()) < 0x0590 { returnfalse;
}
}
})
}
macro_rules! in_range16x8 {
($s:ident, $start:expr, $end:expr) => {{ // SIMD sub is wrapping
($s - u16x8::splat($start)).simd_lt(u16x8::splat($end - $start))
}};
}
#[inline(always)] pubfn is_u16x8_bidi(s: u16x8) -> bool { // We try to first quickly refute the RTLness of the vector. If that // fails, we do the real RTL check, so in that case we end up wasting // the work for the up-front quick checks. Even the quick-check is // two-fold in order to return `false` ASAP if everything is below // Hebrew.
aarch64_return_false_if_below_hebrew!(s);
let below_hebrew = s.simd_lt(u16x8::splat(0x0590));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.