#[cfg(target_arch = "x86_64")]
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn addcarry_u32(x: u32, y: u32, c: u8) -> (u32, u8) {
use core::arch::x86_64::_addcarry_u32;
unsafe {
let mut d = 0u32;
let cc = _addcarry_u32(c, x, y, &mut d);
(d, cc)
}
}
#[cfg(not(target_arch = "x86_64"))]
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn addcarry_u32(x: u32, y: u32, c: u8) -> (u32, u8) {
let z = (x as u64).wrapping_add(y as u64).wrapping_add(c as u64);
(z as u32, (z >> 32) as u8)
}
#[cfg(target_arch = "x86_64")]
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn subborrow_u32(x: u32, y: u32, c: u8) -> (u32, u8) {
use core::arch::x86_64::_subborrow_u32;
unsafe {
let mut d = 0u32;
let cc = _subborrow_u32(c, x, y, &mut d);
(d, cc)
}
}
#[cfg(not(target_arch = "x86_64"))]
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn subborrow_u32(x: u32, y: u32, c: u8) -> (u32, u8) {
let z = (x as u64).wrapping_sub(y as u64).wrapping_sub(c as u64);
(z as u32, (z >> 63) as u8)
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn umull(x: u32, y: u32) -> (u32, u32) {
let z = (x as u64) * (y as u64);
(z as u32, (z >> 32) as u32)
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn umull_add(x: u32, y: u32, z: u32) -> (u32, u32) {
let t = ((x as u64) * (y as u64)).wrapping_add(z as u64);
(t as u32, (t >> 32) as u32)
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn umull_add2(x: u32, y: u32, z1: u32, z2: u32) -> (u32, u32) {
let t = ((x as u64) * (y as u64))
.wrapping_add(z1 as u64).wrapping_add(z2 as u64);
(t as u32, (t >> 32) as u32)
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn umull_x2(x1: u32, y1: u32, x2: u32, y2: u32) -> (u32, u32) {
let z1 = (x1 as u64) * (y1 as u64);
let z2 = (x2 as u64) * (y2 as u64);
let z = z1.wrapping_add(z2);
(z as u32, (z >> 32) as u32)
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn umull_x2_add(x1: u32, y1: u32, x2: u32, y2: u32, z3: u32) -> (u32, u32) {
let z1 = (x1 as u64) * (y1 as u64);
let z2 = (x2 as u64) * (y2 as u64);
let z = z1.wrapping_add(z2).wrapping_add(z3 as u64);
(z as u32, (z >> 32) as u32)
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn sgnw(x: u32) -> u32 {
((x as i32) >> 31) as u32
}
#[cfg(any(
all(target_arch = "x86_64", target_feature = "lzcnt"),
target_arch = "aarch64",
))]
#[allow(dead_code)]
#[inline(always)]
pub(crate) const fn lzcnt(x: u32) -> u32 {
x.leading_zeros()
}
#[cfg(not(any(
all(target_arch = "x86_64", target_feature = "lzcnt"),
target_arch = "aarch64",
)))]
#[allow(dead_code)]
pub(crate) const fn lzcnt(x: u32) -> u32 {
let m = sgnw((x >> 16).wrapping_sub(1));
let s = m & 16;
let x = (x >> 16) ^ (m & (x ^ (x >> 16)));
let m = sgnw((x >> 8).wrapping_sub(1));
let s = s | (m & 8);
let x = (x >> 8) ^ (m & (x ^ (x >> 8)));
let m = sgnw((x >> 4).wrapping_sub(1));
let s = s | (m & 4);
let x = (x >> 4) ^ (m & (x ^ (x >> 4)));
let m = sgnw((x >> 2).wrapping_sub(1));
let s = s | (m & 2);
let x = (x >> 2) ^ (m & (x ^ (x >> 2)));
let s = s.wrapping_add(2u32.wrapping_sub(x) & ((x.wrapping_sub(3) >> 2)));
s as u32
}