Merge pull request #267 from Lokathor/master

Adding __clzsi2
master
Alex Crichton 2019-01-07 09:36:45 -06:00 committed by GitHub
commit 9710af9a33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 0 deletions

View File

@ -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
}
}
}

View 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;
}
}