core/stdarch/crates/core_arch/src/x86/
bmi1.rs1#[cfg(test)]
13use stdarch_test::assert_instr;
14
15#[inline]
20#[target_feature(enable = "bmi1")]
21#[cfg_attr(test, assert_instr(bextr))]
22#[stable(feature = "simd_x86", since = "1.27.0")]
23pub fn _bextr_u32(a: u32, start: u32, len: u32) -> u32 {
24 _bextr2_u32(a, (start & 0xff_u32) | ((len & 0xff_u32) << 8_u32))
25}
26
27#[inline]
35#[target_feature(enable = "bmi1")]
36#[cfg_attr(test, assert_instr(bextr))]
37#[stable(feature = "simd_x86", since = "1.27.0")]
38pub fn _bextr2_u32(a: u32, control: u32) -> u32 {
39 unsafe { x86_bmi_bextr_32(a, control) }
40}
41
42#[inline]
46#[target_feature(enable = "bmi1")]
47#[cfg_attr(test, assert_instr(andn))]
48#[stable(feature = "simd_x86", since = "1.27.0")]
49pub fn _andn_u32(a: u32, b: u32) -> u32 {
50 !a & b
51}
52
53#[inline]
57#[target_feature(enable = "bmi1")]
58#[cfg_attr(test, assert_instr(blsi))]
59#[stable(feature = "simd_x86", since = "1.27.0")]
60pub fn _blsi_u32(x: u32) -> u32 {
61 x & x.wrapping_neg()
62}
63
64#[inline]
68#[target_feature(enable = "bmi1")]
69#[cfg_attr(test, assert_instr(blsmsk))]
70#[stable(feature = "simd_x86", since = "1.27.0")]
71pub fn _blsmsk_u32(x: u32) -> u32 {
72 x ^ (x.wrapping_sub(1_u32))
73}
74
75#[inline]
81#[target_feature(enable = "bmi1")]
82#[cfg_attr(test, assert_instr(blsr))]
83#[stable(feature = "simd_x86", since = "1.27.0")]
84pub fn _blsr_u32(x: u32) -> u32 {
85 x & (x.wrapping_sub(1))
86}
87
88#[inline]
94#[target_feature(enable = "bmi1")]
95#[cfg_attr(test, assert_instr(tzcnt))]
96#[stable(feature = "simd_x86_updates", since = "1.82.0")]
97pub fn _tzcnt_u16(x: u16) -> u16 {
98 x.trailing_zeros() as u16
99}
100
101#[inline]
107#[target_feature(enable = "bmi1")]
108#[cfg_attr(test, assert_instr(tzcnt))]
109#[stable(feature = "simd_x86", since = "1.27.0")]
110pub fn _tzcnt_u32(x: u32) -> u32 {
111 x.trailing_zeros()
112}
113
114#[inline]
120#[target_feature(enable = "bmi1")]
121#[cfg_attr(test, assert_instr(tzcnt))]
122#[stable(feature = "simd_x86", since = "1.27.0")]
123pub fn _mm_tzcnt_32(x: u32) -> i32 {
124 x.trailing_zeros() as i32
125}
126
127unsafe extern "C" {
128 #[link_name = "llvm.x86.bmi.bextr.32"]
129 fn x86_bmi_bextr_32(x: u32, y: u32) -> u32;
130}
131
132#[cfg(test)]
133mod tests {
134 use stdarch_test::simd_test;
135
136 use crate::core_arch::x86::*;
137
138 #[simd_test(enable = "bmi1")]
139 unsafe fn test_bextr_u32() {
140 let r = _bextr_u32(0b0101_0000u32, 4, 4);
141 assert_eq!(r, 0b0000_0101u32);
142 }
143
144 #[simd_test(enable = "bmi1")]
145 unsafe fn test_andn_u32() {
146 assert_eq!(_andn_u32(0, 0), 0);
147 assert_eq!(_andn_u32(0, 1), 1);
148 assert_eq!(_andn_u32(1, 0), 0);
149 assert_eq!(_andn_u32(1, 1), 0);
150
151 let r = _andn_u32(0b0000_0000u32, 0b0000_0000u32);
152 assert_eq!(r, 0b0000_0000u32);
153
154 let r = _andn_u32(0b0000_0000u32, 0b1111_1111u32);
155 assert_eq!(r, 0b1111_1111u32);
156
157 let r = _andn_u32(0b1111_1111u32, 0b0000_0000u32);
158 assert_eq!(r, 0b0000_0000u32);
159
160 let r = _andn_u32(0b1111_1111u32, 0b1111_1111u32);
161 assert_eq!(r, 0b0000_0000u32);
162
163 let r = _andn_u32(0b0100_0000u32, 0b0101_1101u32);
164 assert_eq!(r, 0b0001_1101u32);
165 }
166
167 #[simd_test(enable = "bmi1")]
168 unsafe fn test_blsi_u32() {
169 assert_eq!(_blsi_u32(0b1101_0000u32), 0b0001_0000u32);
170 }
171
172 #[simd_test(enable = "bmi1")]
173 unsafe fn test_blsmsk_u32() {
174 let r = _blsmsk_u32(0b0011_0000u32);
175 assert_eq!(r, 0b0001_1111u32);
176 }
177
178 #[simd_test(enable = "bmi1")]
179 unsafe fn test_blsr_u32() {
180 let r = _blsr_u32(0b0011_0000u32);
182 assert_eq!(r, 0b0010_0000u32);
183 }
184
185 #[simd_test(enable = "bmi1")]
186 unsafe fn test_tzcnt_u16() {
187 assert_eq!(_tzcnt_u16(0b0000_0001u16), 0u16);
188 assert_eq!(_tzcnt_u16(0b0000_0000u16), 16u16);
189 assert_eq!(_tzcnt_u16(0b1001_0000u16), 4u16);
190 }
191
192 #[simd_test(enable = "bmi1")]
193 unsafe fn test_tzcnt_u32() {
194 assert_eq!(_tzcnt_u32(0b0000_0001u32), 0u32);
195 assert_eq!(_tzcnt_u32(0b0000_0000u32), 32u32);
196 assert_eq!(_tzcnt_u32(0b1001_0000u32), 4u32);
197 }
198}