core/stdarch/crates/core_arch/src/x86/
bt.rs1use crate::arch::asm;
2#[cfg(test)]
3use stdarch_test::assert_instr;
4
5#[cfg(target_pointer_width = "32")]
9macro_rules! bt {
10    ($inst:expr) => {
11        concat!($inst, " {b:e}, ({p:e})")
12    };
13}
14#[cfg(target_pointer_width = "64")]
15macro_rules! bt {
16    ($inst:expr) => {
17        concat!($inst, " {b:e}, ({p})")
18    };
19}
20
21#[inline]
25#[cfg_attr(test, assert_instr(bt))]
26#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
27pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
28    let r: u8;
29    asm!(
30        bt!("btl"),
31        "setc {r}",
32        p = in(reg) p,
33        b = in(reg) b,
34        r = out(reg_byte) r,
35        options(readonly, nostack, pure, att_syntax)
36    );
37    r
38}
39
40#[inline]
44#[cfg_attr(test, assert_instr(bts))]
45#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
46pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
47    let r: u8;
48    asm!(
49        bt!("btsl"),
50        "setc {r}",
51        p = in(reg) p,
52        b = in(reg) b,
53        r = out(reg_byte) r,
54        options(nostack, att_syntax)
55    );
56    r
57}
58
59#[inline]
63#[cfg_attr(test, assert_instr(btr))]
64#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
65pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
66    let r: u8;
67    asm!(
68        bt!("btrl"),
69        "setc {r}",
70        p = in(reg) p,
71        b = in(reg) b,
72        r = out(reg_byte) r,
73        options(nostack, att_syntax)
74    );
75    r
76}
77
78#[inline]
82#[cfg_attr(test, assert_instr(btc))]
83#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
84pub unsafe fn _bittestandcomplement(p: *mut i32, b: i32) -> u8 {
85    let r: u8;
86    asm!(
87        bt!("btcl"),
88        "setc {r}",
89        p = in(reg) p,
90        b = in(reg) b,
91        r = out(reg_byte) r,
92        options(nostack, att_syntax)
93    );
94    r
95}
96
97#[cfg(test)]
98mod tests {
99    use crate::core_arch::x86::*;
100
101    #[test]
102    #[cfg_attr(miri, ignore)] fn test_bittest() {
104        unsafe {
105            let a = 0b0101_0000i32;
106            assert_eq!(_bittest(&a as _, 4), 1);
107            assert_eq!(_bittest(&a as _, 5), 0);
108        }
109    }
110
111    #[test]
112    #[cfg_attr(miri, ignore)] fn test_bittestandset() {
114        unsafe {
115            let mut a = 0b0101_0000i32;
116            assert_eq!(_bittestandset(&mut a as _, 4), 1);
117            assert_eq!(_bittestandset(&mut a as _, 4), 1);
118            assert_eq!(_bittestandset(&mut a as _, 5), 0);
119            assert_eq!(_bittestandset(&mut a as _, 5), 1);
120        }
121    }
122
123    #[test]
124    #[cfg_attr(miri, ignore)] fn test_bittestandreset() {
126        unsafe {
127            let mut a = 0b0101_0000i32;
128            assert_eq!(_bittestandreset(&mut a as _, 4), 1);
129            assert_eq!(_bittestandreset(&mut a as _, 4), 0);
130            assert_eq!(_bittestandreset(&mut a as _, 5), 0);
131            assert_eq!(_bittestandreset(&mut a as _, 5), 0);
132        }
133    }
134
135    #[test]
136    #[cfg_attr(miri, ignore)] fn test_bittestandcomplement() {
138        unsafe {
139            let mut a = 0b0101_0000i32;
140            assert_eq!(_bittestandcomplement(&mut a as _, 4), 1);
141            assert_eq!(_bittestandcomplement(&mut a as _, 4), 0);
142            assert_eq!(_bittestandcomplement(&mut a as _, 4), 1);
143            assert_eq!(_bittestandcomplement(&mut a as _, 5), 0);
144            assert_eq!(_bittestandcomplement(&mut a as _, 5), 1);
145        }
146    }
147}