]> git.proxmox.com Git - cargo.git/blob - vendor/memchr/src/memmem/x86/sse.rs
New upstream version 0.52.0
[cargo.git] / vendor / memchr / src / memmem / x86 / sse.rs
1 use core::arch::x86_64::__m128i;
2
3 use crate::memmem::{genericsimd, NeedleInfo};
4
5 /// An SSE accelerated vectorized substring search routine that only works on
6 /// small needles.
7 #[derive(Clone, Copy, Debug)]
8 pub(crate) struct Forward(genericsimd::Forward);
9
10 impl Forward {
11 /// Create a new "generic simd" forward searcher. If one could not be
12 /// created from the given inputs, then None is returned.
13 pub(crate) fn new(ninfo: &NeedleInfo, needle: &[u8]) -> Option<Forward> {
14 if !cfg!(memchr_runtime_sse2) {
15 return None;
16 }
17 genericsimd::Forward::new(ninfo, needle).map(Forward)
18 }
19
20 /// Returns the minimum length of haystack that is needed for this searcher
21 /// to work. Passing a haystack with a length smaller than this will cause
22 /// `find` to panic.
23 #[inline(always)]
24 pub(crate) fn min_haystack_len(&self) -> usize {
25 self.0.min_haystack_len::<__m128i>()
26 }
27
28 #[inline(always)]
29 pub(crate) fn find(
30 &self,
31 haystack: &[u8],
32 needle: &[u8],
33 ) -> Option<usize> {
34 // SAFETY: sse2 is enabled on all x86_64 targets, so this is always
35 // safe to call.
36 unsafe { self.find_impl(haystack, needle) }
37 }
38
39 /// The implementation of find marked with the appropriate target feature.
40 ///
41 /// # Safety
42 ///
43 /// This is safe to call in all cases since sse2 is guaranteed to be part
44 /// of x86_64. It is marked as unsafe because of the target feature
45 /// attribute.
46 #[target_feature(enable = "sse2")]
47 unsafe fn find_impl(
48 &self,
49 haystack: &[u8],
50 needle: &[u8],
51 ) -> Option<usize> {
52 genericsimd::fwd_find::<__m128i>(&self.0, haystack, needle)
53 }
54 }
55
56 #[cfg(all(test, feature = "std", not(miri)))]
57 mod tests {
58 use crate::memmem::{prefilter::PrefilterState, NeedleInfo};
59
60 fn find(
61 _: &mut PrefilterState,
62 ninfo: &NeedleInfo,
63 haystack: &[u8],
64 needle: &[u8],
65 ) -> Option<usize> {
66 super::Forward::new(ninfo, needle).unwrap().find(haystack, needle)
67 }
68
69 #[test]
70 fn prefilter_permutations() {
71 use crate::memmem::prefilter::tests::PrefilterTest;
72
73 // SAFETY: sse2 is enabled on all x86_64 targets, so this is always
74 // safe to call.
75 unsafe {
76 PrefilterTest::run_all_tests_filter(find, |t| {
77 // This substring searcher only works on certain configs, so
78 // filter our tests such that Forward::new will be guaranteed
79 // to succeed. (And also remove tests with a haystack that is
80 // too small.)
81 let fwd = match super::Forward::new(&t.ninfo, &t.needle) {
82 None => return false,
83 Some(fwd) => fwd,
84 };
85 t.haystack.len() >= fwd.min_haystack_len()
86 })
87 }
88 }
89 }