1 use core::arch::x86_64::__m128i;
2 
3 use crate::memmem::{
4     prefilter::{PrefilterFnTy, PrefilterState},
5     NeedleInfo,
6 };
7 
8 // Check that the functions below satisfy the Prefilter function type.
9 const _: PrefilterFnTy = find;
10 
11 /// An SSE2 accelerated candidate finder for single-substring search.
12 ///
13 /// # Safety
14 ///
15 /// Callers must ensure that the sse2 CPU feature is enabled in the current
16 /// environment. This feature should be enabled in all x86_64 targets.
17 #[target_feature(enable = "sse2")]
find( prestate: &mut PrefilterState, ninfo: &NeedleInfo, haystack: &[u8], needle: &[u8], ) -> Option<usize>18 pub(crate) unsafe fn find(
19     prestate: &mut PrefilterState,
20     ninfo: &NeedleInfo,
21     haystack: &[u8],
22     needle: &[u8],
23 ) -> Option<usize> {
24     // If the haystack is too small for SSE2, then just run memchr on the
25     // rarest byte and be done with it. (It is likely that this code path is
26     // rarely exercised, since a higher level routine will probably dispatch to
27     // Rabin-Karp for such a small haystack.)
28     fn simple_memchr_fallback(
29         _prestate: &mut PrefilterState,
30         ninfo: &NeedleInfo,
31         haystack: &[u8],
32         needle: &[u8],
33     ) -> Option<usize> {
34         let (rare, _) = ninfo.rarebytes.as_rare_ordered_usize();
35         crate::memchr(needle[rare], haystack).map(|i| i.saturating_sub(rare))
36     }
37     super::super::genericsimd::find::<__m128i>(
38         prestate,
39         ninfo,
40         haystack,
41         needle,
42         simple_memchr_fallback,
43     )
44 }
45 
46 #[cfg(all(test, feature = "std"))]
47 mod tests {
48     #[test]
49     #[cfg(not(miri))]
prefilter_permutations()50     fn prefilter_permutations() {
51         use crate::memmem::prefilter::tests::PrefilterTest;
52         // SAFETY: super::find is safe to call for all inputs on x86.
53         unsafe { PrefilterTest::run_all_tests(super::find) };
54     }
55 }
56