#![allow(unused_unsafe)]
#![allow(clippy::needless_return)]
#![allow(clippy::comparison_chain)]
#![allow(clippy::if_same_then_else)]
#![allow(clippy::needless_bool)]
#[macro_use]
mod norm_shift;
#[macro_use]
mod binary_long;
#[macro_use]
mod delegate;
#[allow(unused_imports)]
#[cfg(not(feature = "public-test-deps"))]
pub(crate) use self::delegate::u128_divide_sparc;
#[cfg(feature = "public-test-deps")]
pub use self::delegate::u128_divide_sparc;
#[macro_use]
mod trifecta;
#[macro_use]
mod asymmetric;
fn zero_div_fn() -> ! {
unsafe { core::intrinsics::unreachable() }
}
const USE_LZ: bool = {
if cfg!(target_arch = "arm") {
if cfg!(target_feature = "thumb-mode") {
cfg!(target_feature = "v6t2")
} else {
cfg!(target_feature = "v5te")
}
} else if cfg!(any(target_arch = "sparc", target_arch = "sparc64")) {
cfg!(target_feature = "vis3")
} else if cfg!(any(target_arch = "riscv32", target_arch = "riscv64")) {
cfg!(target_feature = "b")
} else {
true
}
};
impl_normalization_shift!(
u32_normalization_shift,
USE_LZ,
32,
u32,
i32,
allow(dead_code)
);
impl_normalization_shift!(
u64_normalization_shift,
USE_LZ,
64,
u64,
i64,
allow(dead_code)
);
#[inline]
fn u64_by_u64_div_rem(duo: u64, div: u64) -> (u64, u64) {
if let Some(quo) = duo.checked_div(div) {
if let Some(rem) = duo.checked_rem(div) {
return (quo, rem);
}
}
zero_div_fn()
}
#[cfg(all(
not(any(target_pointer_width = "16", target_pointer_width = "32")),
not(all(not(feature = "no-asm"), target_arch = "x86_64")),
not(any(target_arch = "sparc", target_arch = "sparc64"))
))]
impl_trifecta!(
u128_div_rem,
zero_div_fn,
u64_by_u64_div_rem,
32,
u32,
u64,
u128
);
#[cfg(all(
any(target_pointer_width = "16", target_pointer_width = "32"),
not(all(not(feature = "no-asm"), target_arch = "x86_64")),
not(any(target_arch = "sparc", target_arch = "sparc64"))
))]
impl_delegate!(
u128_div_rem,
zero_div_fn,
u64_normalization_shift,
u64_by_u64_div_rem,
32,
u32,
u64,
u128,
i128
);
#[cfg(all(not(feature = "no-asm"), target_arch = "x86_64"))]
#[inline]
unsafe fn u128_by_u64_div_rem(duo: u128, div: u64) -> (u64, u64) {
let duo_lo = duo as u64;
let duo_hi = (duo >> 64) as u64;
let quo: u64;
let rem: u64;
unsafe {
core::arch::asm!(
"div {0}",
in(reg) div,
inlateout("rax") duo_lo => quo,
inlateout("rdx") duo_hi => rem,
options(att_syntax, pure, nomem, nostack)
);
}
(quo, rem)
}
#[cfg(all(not(feature = "no-asm"), target_arch = "x86_64"))]
impl_asymmetric!(
u128_div_rem,
zero_div_fn,
u64_by_u64_div_rem,
u128_by_u64_div_rem,
32,
u32,
u64,
u128
);
#[inline]
#[allow(dead_code)]
fn u32_by_u32_div_rem(duo: u32, div: u32) -> (u32, u32) {
if let Some(quo) = duo.checked_div(div) {
if let Some(rem) = duo.checked_rem(div) {
return (quo, rem);
}
}
zero_div_fn()
}
#[cfg(all(
not(all(not(feature = "no-asm"), target_arch = "x86")),
not(target_pointer_width = "64")
))]
impl_delegate!(
u64_div_rem,
zero_div_fn,
u32_normalization_shift,
u32_by_u32_div_rem,
16,
u16,
u32,
u64,
i64
);
#[cfg(all(
not(all(not(feature = "no-asm"), target_arch = "x86")),
target_pointer_width = "64"
))]
impl_binary_long!(
u64_div_rem,
zero_div_fn,
u64_normalization_shift,
64,
u64,
i64
);
#[cfg(all(not(feature = "no-asm"), target_arch = "x86"))]
#[inline]
unsafe fn u64_by_u32_div_rem(duo: u64, div: u32) -> (u32, u32) {
let duo_lo = duo as u32;
let duo_hi = (duo >> 32) as u32;
let quo: u32;
let rem: u32;
unsafe {
core::arch::asm!(
"div {0}",
in(reg) div,
inlateout("rax") duo_lo => quo,
inlateout("rdx") duo_hi => rem,
options(att_syntax, pure, nomem, nostack)
);
}
(quo, rem)
}
#[cfg(all(not(feature = "no-asm"), target_arch = "x86"))]
impl_asymmetric!(
u64_div_rem,
zero_div_fn,
u32_by_u32_div_rem,
u64_by_u32_div_rem,
16,
u16,
u32,
u64
);
impl_binary_long!(
u32_div_rem,
zero_div_fn,
u32_normalization_shift,
32,
u32,
i32
);