simdutf8/implementation/x86/
mod.rs1#[allow(dead_code)]
2pub(crate) mod avx2;
3
4#[allow(dead_code)]
5pub(crate) mod sse42;
6
7#[allow(unused_imports)]
8use super::helpers::SIMD_CHUNK_SIZE;
9
10#[cfg(all(feature = "std", not(target_feature = "avx2")))]
13#[inline]
14pub(crate) unsafe fn validate_utf8_basic(
15 input: &[u8],
16) -> core::result::Result<(), crate::basic::Utf8Error> {
17 use core::mem;
18 use std::sync::atomic::{AtomicPtr, Ordering};
19
20 type FnRaw = *mut ();
21
22 static FN: AtomicPtr<()> = AtomicPtr::new(get_fastest as FnRaw);
23
24 unsafe fn get_fastest(input: &[u8]) -> core::result::Result<(), crate::basic::Utf8Error> {
25 let fun = get_fastest_available_implementation_basic();
26 FN.store(fun as FnRaw, Ordering::Relaxed);
27 (fun)(input)
28 }
29
30 if input.len() < SIMD_CHUNK_SIZE {
31 return super::validate_utf8_basic_fallback(input);
32 }
33
34 let fun = FN.load(Ordering::Relaxed);
35 mem::transmute::<FnRaw, super::ValidateUtf8Fn>(fun)(input)
36}
37
38#[cfg(all(feature = "std", not(target_feature = "avx2")))]
39#[inline]
40fn get_fastest_available_implementation_basic() -> super::ValidateUtf8Fn {
41 if std::is_x86_feature_detected!("avx2") {
42 avx2::validate_utf8_basic
43 } else if std::is_x86_feature_detected!("sse4.2") {
44 sse42::validate_utf8_basic
45 } else {
46 super::validate_utf8_basic_fallback
47 }
48}
49
50#[cfg(target_feature = "avx2")]
53pub(crate) unsafe fn validate_utf8_basic(
54 input: &[u8],
55) -> core::result::Result<(), crate::basic::Utf8Error> {
56 if input.len() < SIMD_CHUNK_SIZE {
57 return super::validate_utf8_basic_fallback(input);
58 }
59
60 validate_utf8_basic_avx2(input)
61}
62
63#[cfg(target_feature = "avx2")]
64#[inline(never)]
65unsafe fn validate_utf8_basic_avx2(
66 input: &[u8],
67) -> core::result::Result<(), crate::basic::Utf8Error> {
68 avx2::validate_utf8_basic(input)
69}
70
71#[cfg(all(
72 not(feature = "std"),
73 not(target_feature = "avx2"),
74 target_feature = "sse4.2"
75))]
76pub(crate) unsafe fn validate_utf8_basic(
77 input: &[u8],
78) -> core::result::Result<(), crate::basic::Utf8Error> {
79 if input.len() < SIMD_CHUNK_SIZE {
80 return super::validate_utf8_basic_fallback(input);
81 }
82
83 validate_utf8_basic_sse42(input)
84}
85
86#[cfg(all(
87 not(feature = "std"),
88 not(target_feature = "avx2"),
89 target_feature = "sse4.2"
90))]
91#[inline(never)]
92unsafe fn validate_utf8_basic_sse42(
93 input: &[u8],
94) -> core::result::Result<(), crate::basic::Utf8Error> {
95 sse42::validate_utf8_basic(input)
96}
97
98#[cfg(all(
99 not(feature = "std"),
100 not(target_feature = "avx2"),
101 not(target_feature = "sse4.2")
102))]
103pub(crate) use super::validate_utf8_basic_fallback as validate_utf8_basic;
104
105#[cfg(all(feature = "std", not(target_feature = "avx2")))]
108#[cfg(feature = "std")]
109#[inline]
110pub(crate) unsafe fn validate_utf8_compat(
111 input: &[u8],
112) -> core::result::Result<(), crate::compat::Utf8Error> {
113 use core::mem;
114 use std::sync::atomic::{AtomicPtr, Ordering};
115
116 type FnRaw = *mut ();
117
118 static FN: AtomicPtr<()> = AtomicPtr::new(get_fastest as FnRaw);
119
120 unsafe fn get_fastest(input: &[u8]) -> core::result::Result<(), crate::compat::Utf8Error> {
121 let fun = get_fastest_available_implementation_compat();
122 FN.store(fun as FnRaw, Ordering::Relaxed);
123 (fun)(input)
124 }
125
126 if input.len() < SIMD_CHUNK_SIZE {
127 return super::validate_utf8_compat_fallback(input);
128 }
129
130 let fun = FN.load(Ordering::Relaxed);
131 mem::transmute::<FnRaw, super::ValidateUtf8CompatFn>(fun)(input)
132}
133
134#[cfg(all(feature = "std", not(target_feature = "avx2")))]
135#[inline]
136fn get_fastest_available_implementation_compat() -> super::ValidateUtf8CompatFn {
137 if std::is_x86_feature_detected!("avx2") {
138 avx2::validate_utf8_compat
139 } else if std::is_x86_feature_detected!("sse4.2") {
140 sse42::validate_utf8_compat
141 } else {
142 super::validate_utf8_compat_fallback
143 }
144}
145
146#[cfg(target_feature = "avx2")]
149pub(crate) unsafe fn validate_utf8_compat(
150 input: &[u8],
151) -> core::result::Result<(), crate::compat::Utf8Error> {
152 if input.len() < SIMD_CHUNK_SIZE {
153 return super::validate_utf8_compat_fallback(input);
154 }
155
156 validate_utf8_compat_avx2(input)
157}
158
159#[cfg(target_feature = "avx2")]
160#[inline(never)]
161unsafe fn validate_utf8_compat_avx2(
162 input: &[u8],
163) -> core::result::Result<(), crate::compat::Utf8Error> {
164 avx2::validate_utf8_compat(input)
165}
166
167#[cfg(all(
168 not(feature = "std"),
169 not(target_feature = "avx2"),
170 target_feature = "sse4.2"
171))]
172pub(crate) unsafe fn validate_utf8_compat(
173 input: &[u8],
174) -> core::result::Result<(), crate::compat::Utf8Error> {
175 if input.len() < SIMD_CHUNK_SIZE {
176 return super::validate_utf8_compat_fallback(input);
177 }
178
179 validate_utf8_compat_sse42(input)
180}
181
182#[cfg(all(
183 not(feature = "std"),
184 not(target_feature = "avx2"),
185 target_feature = "sse4.2"
186))]
187#[inline(never)]
188pub(crate) unsafe fn validate_utf8_compat_sse42(
189 input: &[u8],
190) -> core::result::Result<(), crate::compat::Utf8Error> {
191 sse42::validate_utf8_compat(input)
192}
193
194#[cfg(all(
195 not(feature = "std"),
196 not(target_feature = "avx2"),
197 not(target_feature = "sse4.2")
198))]
199pub(crate) use super::validate_utf8_compat_fallback as validate_utf8_compat;