]>
Commit | Line | Data |
---|---|---|
0531ce1d XL |
1 | //! Advanced Bit Manipulation (ABM) instructions |
2 | //! | |
3 | //! The POPCNT and LZCNT have their own CPUID bits to indicate support. | |
4 | //! | |
5 | //! The references are: | |
6 | //! | |
7 | //! - [Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2: | |
8 | //! Instruction Set Reference, A-Z][intel64_ref]. | |
9 | //! - [AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and | |
10 | //! System Instructions][amd64_ref]. | |
11 | //! | |
12 | //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions | |
13 | //! available. | |
14 | //! | |
15 | //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf | |
16 | //! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf | |
17 | //! [wikipedia_bmi]: | |
18 | //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 | |
19 | ||
20 | #[cfg(test)] | |
416331ca | 21 | use stdarch_test::assert_instr; |
0531ce1d XL |
22 | |
23 | /// Counts the leading most significant zero bits. | |
24 | /// | |
25 | /// When the operand is zero, it returns its size in bits. | |
83c7162d XL |
26 | /// |
27 | /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_lzcnt_u32) | |
0531ce1d XL |
28 | #[inline] |
29 | #[target_feature(enable = "lzcnt")] | |
30 | #[cfg_attr(test, assert_instr(lzcnt))] | |
83c7162d | 31 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
32 | pub unsafe fn _lzcnt_u32(x: u32) -> u32 { |
33 | x.leading_zeros() | |
34 | } | |
35 | ||
36 | /// Counts the bits that are set. | |
83c7162d XL |
37 | /// |
38 | /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_popcnt32) | |
0531ce1d XL |
39 | #[inline] |
40 | #[target_feature(enable = "popcnt")] | |
41 | #[cfg_attr(test, assert_instr(popcnt))] | |
83c7162d | 42 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
43 | pub unsafe fn _popcnt32(x: i32) -> i32 { |
44 | x.count_ones() as i32 | |
45 | } | |
46 | ||
47 | #[cfg(test)] | |
48 | mod tests { | |
416331ca | 49 | use stdarch_test::simd_test; |
0531ce1d | 50 | |
532ac7d7 | 51 | use crate::core_arch::x86::*; |
0531ce1d | 52 | |
83c7162d | 53 | #[simd_test(enable = "lzcnt")] |
0531ce1d XL |
54 | unsafe fn test_lzcnt_u32() { |
55 | assert_eq!(_lzcnt_u32(0b0101_1010), 25); | |
56 | } | |
57 | ||
83c7162d | 58 | #[simd_test(enable = "popcnt")] |
0531ce1d XL |
59 | unsafe fn test_popcnt32() { |
60 | assert_eq!(_popcnt32(0b0101_1010), 4); | |
61 | } | |
62 | } |