1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*!
Wrapper routines for `memchr` and friends.

These routines choose the best implementation at compile time. (This is
different from `x86_64` because it is expected that `neon` is almost always
available for `aarch64` targets.)
*/

macro_rules! defraw {
    ($ty:ident, $find:ident, $start:ident, $end:ident, $($needles:ident),+) => {{
        #[cfg(target_feature = "neon")]
        {
            use crate::arch::aarch64::neon::memchr::$ty;

            debug!("chose neon for {}", stringify!($ty));
            debug_assert!($ty::is_available());
            // SAFETY: We know that wasm memchr is always available whenever
            // code is compiled for `aarch64` with the `neon` target feature
            // enabled.
            $ty::new_unchecked($($needles),+).$find($start, $end)
        }
        #[cfg(not(target_feature = "neon"))]
        {
            use crate::arch::all::memchr::$ty;

            debug!(
                "no neon feature available, using fallback for {}",
                stringify!($ty),
            );
            $ty::new($($needles),+).$find($start, $end)
        }
    }}
}

/// memchr, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `One::find_raw`.
#[inline(always)]
pub(crate) unsafe fn memchr_raw(
    n1: u8,
    start: *const u8,
    end: *const u8,
) -> Option<*const u8> {
    defraw!(One, find_raw, start, end, n1)
}

/// memrchr, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `One::rfind_raw`.
#[inline(always)]
pub(crate) unsafe fn memrchr_raw(
    n1: u8,
    start: *const u8,
    end: *const u8,
) -> Option<*const u8> {
    defraw!(One, rfind_raw, start, end, n1)
}

/// memchr2, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `Two::find_raw`.
#[inline(always)]
pub(crate) unsafe fn memchr2_raw(
    n1: u8,
    n2: u8,
    start: *const u8,
    end: *const u8,
) -> Option<*const u8> {
    defraw!(Two, find_raw, start, end, n1, n2)
}

/// memrchr2, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `Two::rfind_raw`.
#[inline(always)]
pub(crate) unsafe fn memrchr2_raw(
    n1: u8,
    n2: u8,
    start: *const u8,
    end: *const u8,
) -> Option<*const u8> {
    defraw!(Two, rfind_raw, start, end, n1, n2)
}

/// memchr3, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `Three::find_raw`.
#[inline(always)]
pub(crate) unsafe fn memchr3_raw(
    n1: u8,
    n2: u8,
    n3: u8,
    start: *const u8,
    end: *const u8,
) -> Option<*const u8> {
    defraw!(Three, find_raw, start, end, n1, n2, n3)
}

/// memrchr3, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `Three::rfind_raw`.
#[inline(always)]
pub(crate) unsafe fn memrchr3_raw(
    n1: u8,
    n2: u8,
    n3: u8,
    start: *const u8,
    end: *const u8,
) -> Option<*const u8> {
    defraw!(Three, rfind_raw, start, end, n1, n2, n3)
}

/// Count all matching bytes, but using raw pointers to represent the haystack.
///
/// # Safety
///
/// Pointers must be valid. See `One::count_raw`.
#[inline(always)]
pub(crate) unsafe fn count_raw(
    n1: u8,
    start: *const u8,
    end: *const u8,
) -> usize {
    defraw!(One, count_raw, start, end, n1)
}