compiler_builtins/int/
trailing_zeros.rs1#[cfg(feature = "unstable-public-internals")]
2pub use implementation::trailing_zeros;
3#[cfg(not(feature = "unstable-public-internals"))]
4pub(crate) use implementation::trailing_zeros;
5
6mod implementation {
7 use crate::int::{CastInto, Int};
8
9 #[allow(dead_code)]
11 pub fn trailing_zeros<T: Int + CastInto<u32> + CastInto<u16> + CastInto<u8>>(x: T) -> usize {
12 let mut x = x;
13 let mut r: u32 = 0;
14 let mut t: u32;
15
16 const { assert!(T::BITS <= 64) };
17 if T::BITS >= 64 {
18 r += ((CastInto::<u32>::cast(x) == 0) as u32) << 5; x >>= r; }
21
22 if T::BITS >= 32 {
23 t = ((CastInto::<u16>::cast(x) == 0) as u32) << 4; r += t;
25 x >>= t; }
27
28 const { assert!(T::BITS >= 16) };
29 t = ((CastInto::<u8>::cast(x) == 0) as u32) << 3;
30 x >>= t; r += t;
32
33 let mut x: u8 = x.cast();
34
35 t = (((x & 0x0F) == 0) as u32) << 2;
36 x >>= t; r += t;
38
39 t = (((x & 0x3) == 0) as u32) << 1;
40 x >>= t; r += t;
42
43 x &= 3;
44
45 r as usize + ((2 - (x >> 1) as usize) & (((x & 1) == 0) as usize).wrapping_neg())
46 }
47}
48
49intrinsics! {
50 pub extern "C" fn __ctzsi2(x: u32) -> usize {
52 trailing_zeros(x)
53 }
54
55 pub extern "C" fn __ctzdi2(x: u64) -> usize {
57 trailing_zeros(x)
58 }
59
60 pub extern "C" fn __ctzti2(x: u128) -> usize {
62 let lo = x as u64;
63 if lo == 0 {
64 64 + __ctzdi2((x >> 64) as u64)
65 } else {
66 __ctzdi2(lo)
67 }
68 }
69}