Skip to content

Adding __clzsi2 #267

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 11 commits into from
Jan 7, 2019
65 changes: 65 additions & 0 deletions src/int/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,68 @@ macro_rules! impl_wide_int {

impl_wide_int!(u32, u64, 32);
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 changes: 25 additions & 0 deletions testcrate/tests/count_leading_zeros.rs
Original file line number Diff line number Diff line change
@@ -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;
}
}