commit
9710af9a33
@ -300,3 +300,68 @@ macro_rules! impl_wide_int {
|
|||||||
|
|
||||||
impl_wide_int!(u32, u64, 32);
|
impl_wide_int!(u32, u64, 32);
|
||||||
impl_wide_int!(u64, u128, 64);
|
impl_wide_int!(u64, u128, 64);
|
||||||
|
|
||||||
|
intrinsics! {
|
||||||
|
#[cfg(any(
|
||||||
|
target_pointer_width = "16",
|
||||||
|
target_pointer_width = "32",
|
||||||
|
target_pointer_width = "64"
|
||||||
|
))]
|
||||||
|
pub extern "C" fn __clzsi2(x: usize) -> usize {
|
||||||
|
// TODO: const this? Would require const-if
|
||||||
|
// Note(Lokathor): the `intrinsics!` macro can't process mut inputs
|
||||||
|
let mut x = x;
|
||||||
|
let mut y: usize;
|
||||||
|
let mut n: usize = {
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
{
|
||||||
|
64
|
||||||
|
}
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
{
|
||||||
|
32
|
||||||
|
}
|
||||||
|
#[cfg(target_pointer_width = "16")]
|
||||||
|
{
|
||||||
|
16
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
{
|
||||||
|
y = x >> 32;
|
||||||
|
if y != 0 {
|
||||||
|
n -= 32;
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
|
||||||
|
{
|
||||||
|
y = x >> 16;
|
||||||
|
if y != 0 {
|
||||||
|
n -= 16;
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y = x >> 8;
|
||||||
|
if y != 0 {
|
||||||
|
n -= 8;
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
y = x >> 4;
|
||||||
|
if y != 0 {
|
||||||
|
n -= 4;
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
y = x >> 2;
|
||||||
|
if y != 0 {
|
||||||
|
n -= 2;
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
y = x >> 1;
|
||||||
|
if y != 0 {
|
||||||
|
n - 2
|
||||||
|
} else {
|
||||||
|
n - x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
25
testcrate/tests/count_leading_zeros.rs
Normal file
25
testcrate/tests/count_leading_zeros.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#![feature(compiler_builtins_lib)]
|
||||||
|
|
||||||
|
extern crate compiler_builtins;
|
||||||
|
|
||||||
|
use compiler_builtins::int::__clzsi2;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn __clzsi2_test() {
|
||||||
|
let mut i: usize = core::usize::MAX;
|
||||||
|
// Check all values above 0
|
||||||
|
while i > 0 {
|
||||||
|
assert_eq!(__clzsi2(i) as u32, i.leading_zeros());
|
||||||
|
i >>= 1;
|
||||||
|
}
|
||||||
|
// check 0 also
|
||||||
|
i = 0;
|
||||||
|
assert_eq!(__clzsi2(i) as u32, i.leading_zeros());
|
||||||
|
// double check for bit patterns that aren't just solid 1s
|
||||||
|
i = 1;
|
||||||
|
for _ in 0..63 {
|
||||||
|
assert_eq!(__clzsi2(i) as u32, i.leading_zeros());
|
||||||
|
i <<= 2;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user