use super::*;
#[inline(always)]
pub(crate) fn _unroll_loop<const N: usize, const STEP: usize, F>(
mut buf_ptr: *const u8,
end_ptr: *const u8,
mut f: F,
) -> (Option<usize>, *const u8)
where
F: FnMut(*const u8) -> Option<usize>,
{
while buf_ptr.is_not_over(end_ptr, STEP * N) {
for i in 0..N {
if let Some(r) = f(unsafe { buf_ptr.add(STEP * i) }) {
return (Some(r), buf_ptr);
}
}
buf_ptr = unsafe { buf_ptr.add(STEP * N) };
}
(None, buf_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_with_prefetch<const N: usize, const STEP: usize, F>(
mut buf_ptr: *const u8,
end_ptr: *const u8,
mut f: F,
) -> (Option<usize>, *const u8)
where
F: FnMut(*const u8) -> Option<usize>,
{
while buf_ptr.is_not_over(end_ptr, STEP * N) {
buf_ptr.prefetch_read_data();
for i in 0..N {
if let Some(r) = f(unsafe { buf_ptr.add(STEP * i) }) {
return (Some(r), buf_ptr);
}
}
buf_ptr = unsafe { buf_ptr.add(STEP * N) };
}
(None, buf_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_dual<const N: usize, const STEP: usize, R, F>(
mut a_ptr: *const u8,
mut b_ptr: *const u8,
end_ptr: *const u8,
mut f: F,
) -> (Option<R>, *const u8, *const u8)
where
F: FnMut(*const u8, *const u8) -> Option<R>,
{
while a_ptr.is_not_over(end_ptr, STEP * N) {
for i in 0..N {
if let Some(r) = f(unsafe { a_ptr.add(STEP * i) }, unsafe {
b_ptr.add(STEP * i)
}) {
return (Some(r), a_ptr, b_ptr);
}
}
a_ptr = unsafe { a_ptr.add(STEP * N) };
b_ptr = unsafe { b_ptr.add(STEP * N) };
}
(None, a_ptr, b_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_dual_with_prefetch<const N: usize, const STEP: usize, R, F>(
mut a_ptr: *const u8,
mut b_ptr: *const u8,
end_ptr: *const u8,
mut f: F,
) -> (Option<R>, *const u8, *const u8)
where
F: FnMut(*const u8, *const u8) -> Option<R>,
{
while a_ptr.is_not_over(end_ptr, STEP * N) {
a_ptr.prefetch_read_data();
b_ptr.prefetch_read_data();
for i in 0..N {
if let Some(r) = f(unsafe { a_ptr.add(STEP * i) }, unsafe {
b_ptr.add(STEP * i)
}) {
return (Some(r), a_ptr, b_ptr);
}
}
a_ptr = unsafe { a_ptr.add(STEP * N) };
b_ptr = unsafe { b_ptr.add(STEP * N) };
}
(None, a_ptr, b_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_dual_action<const N: usize, const STEP: usize, F>(
mut a_ptr: *mut u8,
mut b_ptr: *const u8,
end_ptr: *mut u8,
mut f: F,
) -> (*mut u8, *const u8)
where
F: FnMut(*mut u8, *const u8),
{
while a_ptr.is_not_over(end_ptr, STEP * N) {
for i in 0..N {
f(unsafe { a_ptr.add(STEP * i) }, unsafe {
b_ptr.add(STEP * i)
});
}
a_ptr = unsafe { a_ptr.add(STEP * N) };
b_ptr = unsafe { b_ptr.add(STEP * N) };
}
(a_ptr, b_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_dual_action_with_prefetch<const N: usize, const STEP: usize, F>(
mut a_ptr: *mut u8,
mut b_ptr: *const u8,
end_ptr: *mut u8,
mut f: F,
) -> (*mut u8, *const u8)
where
F: FnMut(*mut u8, *const u8),
{
while a_ptr.is_not_over(end_ptr, STEP * N) {
a_ptr.prefetch_read_data();
b_ptr.prefetch_read_data();
for i in 0..N {
f(unsafe { a_ptr.add(STEP * i) }, unsafe {
b_ptr.add(STEP * i)
});
}
a_ptr = unsafe { a_ptr.add(STEP * N) };
b_ptr = unsafe { b_ptr.add(STEP * N) };
}
(a_ptr, b_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_action<const N: usize, const STEP: usize, F>(
mut buf_ptr: *mut u8,
end_ptr: *const u8,
mut f: F,
) -> *mut u8
where
F: FnMut(*mut u8),
{
while buf_ptr.is_not_over(end_ptr, STEP * N) {
for i in 0..N {
f(unsafe { buf_ptr.add(STEP * i) });
}
buf_ptr = unsafe { buf_ptr.add(STEP * N) };
}
buf_ptr
}
#[inline(always)]
pub(crate) fn _unroll_loop_backward<const N: usize, const STEP: usize, F>(
mut buf_ptr: *const u8,
min_ptr: *const u8,
mut f: F,
) -> (Option<usize>, *const u8)
where
F: FnMut(*const u8) -> Option<usize>,
{
while buf_ptr.is_not_under(min_ptr, STEP * N) {
buf_ptr = unsafe { buf_ptr.sub(STEP * N) };
for i in (0..N).rev() {
if let Some(r) = f(unsafe { buf_ptr.add(STEP * i) }) {
return (Some(r), buf_ptr);
}
}
}
(None, buf_ptr)
}
#[inline(always)]
pub(crate) fn _unroll_loop_backward_with_prefetch<const N: usize, const STEP: usize, F>(
mut buf_ptr: *const u8,
min_ptr: *const u8,
mut f: F,
) -> (Option<usize>, *const u8)
where
F: FnMut(*const u8) -> Option<usize>,
{
while buf_ptr.is_not_under(min_ptr, STEP * N) {
buf_ptr = unsafe { buf_ptr.sub(STEP * N) };
buf_ptr.prefetch_read_data();
for i in (0..N).rev() {
if let Some(r) = f(unsafe { buf_ptr.add(STEP * i) }) {
return (Some(r), buf_ptr);
}
}
}
(None, buf_ptr)
}