From e64f80e4793e55f65ecb7ce2bb9e0fc2cecd8d54 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 19 Sep 2017 22:15:17 +0200 Subject: [PATCH] [abm] use lzcnt and popcnt features --- library/stdarch/src/x86/abm.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/library/stdarch/src/x86/abm.rs b/library/stdarch/src/x86/abm.rs index cefd973dd9e1..7479bf2f17ef 100644 --- a/library/stdarch/src/x86/abm.rs +++ b/library/stdarch/src/x86/abm.rs @@ -1,10 +1,6 @@ //! Advanced Bit Manipulation (ABM) instructions //! -//! That is, POPCNT and LZCNT. These instructions have their own CPUID bits to -//! indicate support. -//! -//! TODO: it is unclear which target feature to use here. SSE4.2 should be good -//! enough but we might need to use BMI for LZCNT if there are any problems. +//! The POPCNT and LZCNT have their own CPUID bits to indicate support. //! //! The references are: //! @@ -19,50 +15,50 @@ /// /// When the operand is zero, it returns its size in bits. #[inline(always)] -#[target_feature = "+sse4.2"] +#[target_feature = "+lzcnt"] pub fn _lzcnt_u32(x: u32) -> u32 { x.leading_zeros() } /// Counts the leading most significant zero bits. /// /// When the operand is zero, it returns its size in bits. #[inline(always)] -#[target_feature = "+sse4.2"] +#[target_feature = "+lzcnt"] pub fn _lzcnt_u64(x: u64) -> u64 { x.leading_zeros() as u64 } /// Counts the bits that are set. #[inline(always)] -#[target_feature = "+sse4.2"] +#[target_feature = "+popcnt"] pub fn _popcnt32(x: u32) -> u32 { x.count_ones() } /// Counts the bits that are set. #[inline(always)] -#[target_feature = "+sse4.2"] +#[target_feature = "+popcnt"] pub fn _popcnt64(x: u64) -> u64 { x.count_ones() as u64 } -#[cfg(all(test, target_feature = "sse4.2", any(target_arch = "x86", target_arch = "x86_64")))] +#[cfg(all(test, target_feature = "bmi", any(target_arch = "x86", target_arch = "x86_64")))] mod tests { use x86::abm; #[test] - #[target_feature = "+sse4.2"] + #[target_feature = "+lzcnt"] fn _lzcnt_u32() { assert_eq!(abm::_lzcnt_u32(0b0101_1010u32), 25u32); } #[test] - #[target_feature = "+sse4.2"] + #[target_feature = "+lzcnt"] fn _lzcnt_u64() { assert_eq!(abm::_lzcnt_u64(0b0101_1010u64), 57u64); } #[test] - #[target_feature = "+sse4.2"] + #[target_feature = "+popcnt"] fn _popcnt32() { assert_eq!(abm::_popcnt32(0b0101_1010u32), 4); } #[test] - #[target_feature = "+sse4.2"] + #[target_feature = "+popcnt"] fn _popcnt64() { assert_eq!(abm::_popcnt64(0b0101_1010u64), 4); }