($SelfT:ty, $ActualT:ty, $BITS:expr,
$ctpop:path,
$ctlz:path,
+ $ctlz_nonzero:path,
$cttz:path,
$bswap:path,
$add_with_overflow:path,
// This method cannot overflow, as in the `next_power_of_two`
// overflow cases it instead ends up returning the maximum value
// of the type, and can return 0 for 0.
+ #[inline]
fn one_less_than_next_power_of_two(self) -> Self {
if self <= 1 { return 0; }
// (such as intel pre-haswell) have more efficient ctlz
// intrinsics when the argument is non-zero.
let p = self - 1;
- let z = p.leading_zeros();
+ let z = unsafe { $ctlz_nonzero(p) };
<$SelfT>::max_value() >> z
}
}
}
+#[cfg(stage0)]
+unsafe fn ctlz_nonzero<T>(x: T) -> T { intrinsics::ctlz(x) }
+#[cfg(not(stage0))]
+unsafe fn ctlz_nonzero<T>(x: T) -> T { intrinsics::ctlz_nonzero(x) }
+
#[lang = "u8"]
impl u8 {
uint_impl! { u8, u8, 8,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { u16, u16, 16,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { u32, u32, 32,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { u64, u64, 64,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { u128, u128, 128,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { usize, u16, 16,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { usize, u32, 32,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
uint_impl! { usize, u64, 64,
intrinsics::ctpop,
intrinsics::ctlz,
+ ctlz_nonzero,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,