#[inline(always)]
unsafe fn load<const BE: bool>(p: *const u8, i: usize) -> u64 {
unsafe {
if BE {
u64::from_be_bytes(p.sub(8 * i + 8).cast::<[u8; 8]>().read())
} else {
u64::from_le_bytes(p.add(8 * i).cast::<[u8; 8]>().read())
}
}
}
#[inline(always)]
unsafe fn store<const BE: bool>(p: *mut u8, i: usize, v: u64) {
unsafe {
if BE {
p.sub(8 * i + 8).cast::<[u8; 8]>().write(v.to_be_bytes());
} else {
p.add(8 * i).cast::<[u8; 8]>().write(v.to_le_bytes());
}
}
}
#[inline(always)]
unsafe fn limb<const BE: bool, const SUB: bool>(
r: *mut u8,
x: *const u8,
y: *const u8,
i: usize,
c: bool,
) -> bool {
unsafe {
let (a, b) = (load::<BE>(x, i), load::<BE>(y, i));
let (v, c) = if SUB {
let (d, b1) = a.overflowing_sub(b);
let (d, b2) = d.overflowing_sub(u64::from(c));
(d, b1 | b2)
} else {
let (s, c1) = a.overflowing_add(b);
let (s, c2) = s.overflowing_add(u64::from(c));
(s, c1 | c2)
};
store::<BE>(r, i, v);
c
}
}
#[inline(always)]
unsafe fn run<const BE: bool, const SUB: bool>(
r: *mut u8,
x: *const u8,
y: *const u8,
n: usize,
mut c: bool,
) -> bool {
let mut i = 0;
unsafe {
while n - i >= 4 {
c = limb::<BE, SUB>(r, x, y, i, c);
c = limb::<BE, SUB>(r, x, y, i + 1, c);
c = limb::<BE, SUB>(r, x, y, i + 2, c);
c = limb::<BE, SUB>(r, x, y, i + 3, c);
i += 4;
}
while i < n {
c = limb::<BE, SUB>(r, x, y, i, c);
i += 1;
}
}
c
}
#[inline]
pub(super) unsafe fn add_n_le(
r: *mut u8,
x: *const u8,
y: *const u8,
n: usize,
carry: bool,
) -> bool {
unsafe { run::<false, false>(r, x, y, n, carry) }
}
#[inline]
pub(super) unsafe fn sub_n_le(
r: *mut u8,
x: *const u8,
y: *const u8,
n: usize,
borrow: bool,
) -> bool {
unsafe { run::<false, true>(r, x, y, n, borrow) }
}
#[inline]
pub(super) unsafe fn add_n_be(
r_end: *mut u8,
x_end: *const u8,
y_end: *const u8,
n: usize,
carry: bool,
) -> bool {
unsafe { run::<true, false>(r_end, x_end, y_end, n, carry) }
}
#[inline]
pub(super) unsafe fn sub_n_be(
r_end: *mut u8,
x_end: *const u8,
y_end: *const u8,
n: usize,
borrow: bool,
) -> bool {
unsafe { run::<true, true>(r_end, x_end, y_end, n, borrow) }
}