commit
1b28d626b4
5 changed files with 111 additions and 6 deletions
|
|
@ -171,6 +171,9 @@ rely on CI.
|
|||
- [x] clzti2.c
|
||||
- [x] comparedf2.c
|
||||
- [x] comparesf2.c
|
||||
- [x] ctzdi2.c
|
||||
- [x] ctzsi2.c
|
||||
- [x] ctzti2.c
|
||||
- [x] divdf3.c
|
||||
- [x] divdi3.c
|
||||
- [x] divmoddi4.c
|
||||
|
|
@ -395,9 +398,6 @@ These builtins are never called by LLVM.
|
|||
- ~~arm/switchu8.S~~
|
||||
- ~~cmpdi2.c~~
|
||||
- ~~cmpti2.c~~
|
||||
- ~~ctzdi2.c~~
|
||||
- ~~ctzsi2.c~~
|
||||
- ~~ctzti2.c~~
|
||||
- ~~ffssi2.c~~
|
||||
- ~~ffsdi2.c~~ - this is [called by gcc][jemalloc-fail] though!
|
||||
- ~~ffsti2.c~~
|
||||
|
|
|
|||
|
|
@ -345,8 +345,6 @@ mod c {
|
|||
("__addvdi3", "addvdi3.c"),
|
||||
("__addvsi3", "addvsi3.c"),
|
||||
("__cmpdi2", "cmpdi2.c"),
|
||||
("__ctzdi2", "ctzdi2.c"),
|
||||
("__ctzsi2", "ctzsi2.c"),
|
||||
("__int_util", "int_util.c"),
|
||||
("__mulvdi3", "mulvdi3.c"),
|
||||
("__mulvsi3", "mulvsi3.c"),
|
||||
|
|
@ -380,7 +378,6 @@ mod c {
|
|||
("__absvti2", "absvti2.c"),
|
||||
("__addvti3", "addvti3.c"),
|
||||
("__cmpti2", "cmpti2.c"),
|
||||
("__ctzti2", "ctzti2.c"),
|
||||
("__ffsti2", "ffsti2.c"),
|
||||
("__mulvti3", "mulvti3.c"),
|
||||
("__negti2", "negti2.c"),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ pub mod leading_zeros;
|
|||
pub mod mul;
|
||||
pub mod sdiv;
|
||||
pub mod shift;
|
||||
pub mod trailing_zeros;
|
||||
pub mod udiv;
|
||||
|
||||
pub use big::{i256, u256};
|
||||
|
|
|
|||
64
library/compiler-builtins/src/int/trailing_zeros.rs
Normal file
64
library/compiler-builtins/src/int/trailing_zeros.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
use crate::int::{CastInto, Int};
|
||||
|
||||
public_test_dep! {
|
||||
/// Returns number of trailing binary zeros in `x`.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn trailing_zeros<T: Int + CastInto<u32> + CastInto<u16> + CastInto<u8>>(x: T) -> usize {
|
||||
let mut x = x;
|
||||
let mut r: u32 = 0;
|
||||
let mut t: u32;
|
||||
|
||||
const { assert!(T::BITS <= 64) };
|
||||
if T::BITS >= 64 {
|
||||
r += ((CastInto::<u32>::cast(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
|
||||
x >>= r; // remove 32 zero bits
|
||||
}
|
||||
|
||||
if T::BITS >= 32 {
|
||||
t = ((CastInto::<u16>::cast(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
|
||||
r += t;
|
||||
x >>= t; // x = [0 - 0xFFFF] + higher garbage bits
|
||||
}
|
||||
|
||||
const { assert!(T::BITS >= 16) };
|
||||
t = ((CastInto::<u8>::cast(x) == 0) as u32) << 3;
|
||||
x >>= t; // x = [0 - 0xFF] + higher garbage bits
|
||||
r += t;
|
||||
|
||||
let mut x: u8 = x.cast();
|
||||
|
||||
t = (((x & 0x0F) == 0) as u32) << 2;
|
||||
x >>= t; // x = [0 - 0xF] + higher garbage bits
|
||||
r += t;
|
||||
|
||||
t = (((x & 0x3) == 0) as u32) << 1;
|
||||
x >>= t; // x = [0 - 0x3] + higher garbage bits
|
||||
r += t;
|
||||
|
||||
x &= 3;
|
||||
|
||||
r as usize + ((2 - (x >> 1) as usize) & (((x & 1) == 0) as usize).wrapping_neg())
|
||||
}
|
||||
}
|
||||
|
||||
intrinsics! {
|
||||
/// Returns the number of trailing binary zeros in `x` (32 bit version).
|
||||
pub extern "C" fn __ctzsi2(x: u32) -> usize {
|
||||
trailing_zeros(x)
|
||||
}
|
||||
|
||||
/// Returns the number of trailing binary zeros in `x` (64 bit version).
|
||||
pub extern "C" fn __ctzdi2(x: u64) -> usize {
|
||||
trailing_zeros(x)
|
||||
}
|
||||
|
||||
/// Returns the number of trailing binary zeros in `x` (128 bit version).
|
||||
pub extern "C" fn __ctzti2(x: u128) -> usize {
|
||||
let lo = x as u64;
|
||||
if lo == 0 {
|
||||
64 + __ctzdi2((x >> 64) as u64)
|
||||
} else {
|
||||
__ctzdi2(lo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -131,6 +131,49 @@ fn leading_zeros() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trailing_zeros() {
|
||||
use compiler_builtins::int::trailing_zeros::{__ctzdi2, __ctzsi2, __ctzti2, trailing_zeros};
|
||||
fuzz(N, |x: u32| {
|
||||
if x == 0 {
|
||||
return; // undefined value for an intrinsic
|
||||
}
|
||||
let tz = x.trailing_zeros() as usize;
|
||||
let tz0 = __ctzsi2(x);
|
||||
let tz1 = trailing_zeros(x);
|
||||
if tz0 != tz {
|
||||
panic!("__ctzsi2({}): std: {}, builtins: {}", x, tz, tz0);
|
||||
}
|
||||
if tz1 != tz {
|
||||
panic!("trailing_zeros({}): std: {}, builtins: {}", x, tz, tz1);
|
||||
}
|
||||
});
|
||||
fuzz(N, |x: u64| {
|
||||
if x == 0 {
|
||||
return; // undefined value for an intrinsic
|
||||
}
|
||||
let tz = x.trailing_zeros() as usize;
|
||||
let tz0 = __ctzdi2(x);
|
||||
let tz1 = trailing_zeros(x);
|
||||
if tz0 != tz {
|
||||
panic!("__ctzdi2({}): std: {}, builtins: {}", x, tz, tz0);
|
||||
}
|
||||
if tz1 != tz {
|
||||
panic!("trailing_zeros({}): std: {}, builtins: {}", x, tz, tz1);
|
||||
}
|
||||
});
|
||||
fuzz(N, |x: u128| {
|
||||
if x == 0 {
|
||||
return; // undefined value for an intrinsic
|
||||
}
|
||||
let tz = x.trailing_zeros() as usize;
|
||||
let tz0 = __ctzti2(x);
|
||||
if tz0 != tz {
|
||||
panic!("__ctzti2({}): std: {}, builtins: {}", x, tz, tz0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(target_arch = "avr"))]
|
||||
fn bswap() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue