Skip to content

Commit 9710af9

Browse files
authored
Merge pull request #267 from Lokathor/master
Adding __clzsi2
2 parents 0c5dffb + 9a68e74 commit 9710af9

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

src/int/mod.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,68 @@ macro_rules! impl_wide_int {
300300

301301
impl_wide_int!(u32, u64, 32);
302302
impl_wide_int!(u64, u128, 64);
303+
304+
intrinsics! {
305+
#[cfg(any(
306+
target_pointer_width = "16",
307+
target_pointer_width = "32",
308+
target_pointer_width = "64"
309+
))]
310+
pub extern "C" fn __clzsi2(x: usize) -> usize {
311+
// TODO: const this? Would require const-if
312+
// Note(Lokathor): the `intrinsics!` macro can't process mut inputs
313+
let mut x = x;
314+
let mut y: usize;
315+
let mut n: usize = {
316+
#[cfg(target_pointer_width = "64")]
317+
{
318+
64
319+
}
320+
#[cfg(target_pointer_width = "32")]
321+
{
322+
32
323+
}
324+
#[cfg(target_pointer_width = "16")]
325+
{
326+
16
327+
}
328+
};
329+
#[cfg(target_pointer_width = "64")]
330+
{
331+
y = x >> 32;
332+
if y != 0 {
333+
n -= 32;
334+
x = y;
335+
}
336+
}
337+
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
338+
{
339+
y = x >> 16;
340+
if y != 0 {
341+
n -= 16;
342+
x = y;
343+
}
344+
}
345+
y = x >> 8;
346+
if y != 0 {
347+
n -= 8;
348+
x = y;
349+
}
350+
y = x >> 4;
351+
if y != 0 {
352+
n -= 4;
353+
x = y;
354+
}
355+
y = x >> 2;
356+
if y != 0 {
357+
n -= 2;
358+
x = y;
359+
}
360+
y = x >> 1;
361+
if y != 0 {
362+
n - 2
363+
} else {
364+
n - x
365+
}
366+
}
367+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(compiler_builtins_lib)]
2+
3+
extern crate compiler_builtins;
4+
5+
use compiler_builtins::int::__clzsi2;
6+
7+
#[test]
8+
fn __clzsi2_test() {
9+
let mut i: usize = core::usize::MAX;
10+
// Check all values above 0
11+
while i > 0 {
12+
assert_eq!(__clzsi2(i) as u32, i.leading_zeros());
13+
i >>= 1;
14+
}
15+
// check 0 also
16+
i = 0;
17+
assert_eq!(__clzsi2(i) as u32, i.leading_zeros());
18+
// double check for bit patterns that aren't just solid 1s
19+
i = 1;
20+
for _ in 0..63 {
21+
assert_eq!(__clzsi2(i) as u32, i.leading_zeros());
22+
i <<= 2;
23+
i += 1;
24+
}
25+
}

0 commit comments

Comments
 (0)