Skip to content

Commit d58f9f0

Browse files
committed
Add bittest instructions for x86
1 parent f649570 commit d58f9f0

File tree

4 files changed

+216
-0
lines changed

4 files changed

+216
-0
lines changed

crates/core_arch/src/x86/bt.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#[cfg(test)]
2+
use stdsimd_test::assert_instr;
3+
4+
/// Return the bit at index `b` of 32-bit integer `a`.
5+
#[inline]
6+
#[cfg_attr(test, assert_instr(bt))]
7+
#[unstable(feature = "bittest", issue = "0")]
8+
pub unsafe fn _bittest_u32(a: &u32, b: u32) -> u8 {
9+
let r: u8;
10+
asm!("btl $2, $1\nsetc ${0:b}"
11+
: "=r"(r)
12+
: "m"(a), "lr"(b)
13+
: "cc", "flags", "fpsr");
14+
r
15+
}
16+
17+
/// Return the bit at index `b` of 32-bit integer `a`,
18+
/// and set that bit to one.
19+
#[inline]
20+
#[cfg_attr(test, assert_instr(bts))]
21+
#[unstable(feature = "bittest", issue = "0")]
22+
pub unsafe fn _bittestandset_u32(a: &mut u32, b: u32) -> u8 {
23+
let r: u8;
24+
asm!("btsl $2, $0\nsetc ${1:b}"
25+
: "=*m"(a), "=r"(r)
26+
: "lr"(b)
27+
: "cc", "flags", "fpsr");
28+
r
29+
}
30+
31+
/// Return the bit at index `b` of 32-bit integer `a`,
32+
/// and set that bit to zero.
33+
#[inline]
34+
#[cfg_attr(test, assert_instr(btr))]
35+
#[unstable(feature = "bittest", issue = "0")]
36+
pub unsafe fn _bittestandreset_u32(a: &mut u32, b: u32) -> u8 {
37+
let r: u8;
38+
asm!("btrl $2, $0\nsetc ${1:b}"
39+
: "=*m"(a), "=r"(r)
40+
: "lr"(b)
41+
: "cc", "flags", "fpsr");
42+
r
43+
}
44+
45+
/// Return the bit at index `b` of 32-bit integer `a`,
46+
/// and set that bit to its complement.
47+
#[inline]
48+
#[cfg_attr(test, assert_instr(btc))]
49+
#[unstable(feature = "bittest", issue = "0")]
50+
pub unsafe fn _bittestandcomplement_u32(a: &mut u32, b: u32) -> u8 {
51+
let r: u8;
52+
asm!("btcl $2, $0\nsetc ${1:b}"
53+
: "=*m"(a), "=r"(r)
54+
: "lr"(b)
55+
: "cc", "flags", "fpsr");
56+
r
57+
}
58+
59+
#[cfg(test)]
60+
mod tests {
61+
use crate::core_arch::x86::*;
62+
63+
#[test]
64+
fn test_bittest_u32() {
65+
unsafe {
66+
let a = 0b0101_0000u32;
67+
assert_eq!(_bittest_u32(&a, 4), 1);
68+
assert_eq!(_bittest_u32(&a, 5), 0);
69+
}
70+
}
71+
72+
#[test]
73+
fn test_bittestandset_u32() {
74+
unsafe {
75+
let mut a = 0b0101_0000u32;
76+
assert_eq!(_bittestandset_u32(&mut a, 4), 1);
77+
assert_eq!(_bittestandset_u32(&mut a, 4), 1);
78+
assert_eq!(_bittestandset_u32(&mut a, 5), 0);
79+
assert_eq!(_bittestandset_u32(&mut a, 5), 1);
80+
}
81+
}
82+
83+
#[test]
84+
fn test_bittestandreset_u32() {
85+
unsafe {
86+
let mut a = 0b0101_0000u32;
87+
assert_eq!(_bittestandreset_u32(&mut a, 4), 1);
88+
assert_eq!(_bittestandreset_u32(&mut a, 4), 0);
89+
assert_eq!(_bittestandreset_u32(&mut a, 5), 0);
90+
assert_eq!(_bittestandreset_u32(&mut a, 5), 0);
91+
}
92+
}
93+
94+
#[test]
95+
fn test_bittestandcomplement_u32() {
96+
unsafe {
97+
let mut a = 0b0101_0000u32;
98+
assert_eq!(_bittestandcomplement_u32(&mut a, 4), 1);
99+
assert_eq!(_bittestandcomplement_u32(&mut a, 4), 0);
100+
assert_eq!(_bittestandcomplement_u32(&mut a, 4), 1);
101+
assert_eq!(_bittestandcomplement_u32(&mut a, 5), 0);
102+
assert_eq!(_bittestandcomplement_u32(&mut a, 5), 1);
103+
}
104+
}
105+
}

crates/core_arch/src/x86/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,6 @@ pub use self::avx512f::*;
562562

563563
mod avx512ifma;
564564
pub use self::avx512ifma::*;
565+
566+
mod bt;
567+
pub use self::bt::*;

crates/core_arch/src/x86_64/bt.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#[cfg(test)]
2+
use stdsimd_test::assert_instr;
3+
4+
/// Return the bit at index `b` of 64-bit integer `a`.
5+
#[inline]
6+
#[cfg_attr(test, assert_instr(bt))]
7+
#[unstable(feature = "bittest", issue = "0")]
8+
pub unsafe fn _bittest_u64(a: &u64, b: u64) -> u8 {
9+
let r: u8;
10+
asm!("btq $2, $1\nsetc ${0:b}"
11+
: "=r"(r)
12+
: "m"(a), "lr"(b)
13+
: "cc", "flags", "fpsr");
14+
r
15+
}
16+
17+
/// Return the bit at index `b` of 64-bit integer `a`,
18+
/// and set that bit to one.
19+
#[inline]
20+
#[cfg_attr(test, assert_instr(bts))]
21+
#[unstable(feature = "bittest", issue = "0")]
22+
pub unsafe fn _bittestandset_u64(a: &mut u64, b: u64) -> u8 {
23+
let r: u8;
24+
asm!("btsq $2, $0\nsetc ${1:b}"
25+
: "=*m"(a), "=r"(r)
26+
: "lr"(b)
27+
: "cc", "flags", "fpsr");
28+
r
29+
}
30+
31+
/// Return the bit at index `b` of 64-bit integer `a`,
32+
/// and set that bit to zero.
33+
#[inline]
34+
#[cfg_attr(test, assert_instr(btr))]
35+
#[unstable(feature = "bittest", issue = "0")]
36+
pub unsafe fn _bittestandreset_u64(a: &mut u64, b: u64) -> u8 {
37+
let r: u8;
38+
asm!("btrq $2, $0\nsetc ${1:b}"
39+
: "=*m"(a), "=r"(r)
40+
: "lr"(b)
41+
: "cc", "flags", "fpsr");
42+
r
43+
}
44+
45+
/// Return the bit at index `b` of 64-bit integer `a`,
46+
/// and set that bit to its complement.
47+
#[inline]
48+
#[cfg_attr(test, assert_instr(btc))]
49+
#[unstable(feature = "bittest", issue = "0")]
50+
pub unsafe fn _bittestandcomplement_u64(a: &mut u64, b: u64) -> u8 {
51+
let r: u8;
52+
asm!("btcq $2, $0\nsetc ${1:b}"
53+
: "=*m"(a), "=r"(r)
54+
: "lr"(b)
55+
: "cc", "flags", "fpsr");
56+
r
57+
}
58+
59+
#[cfg(test)]
60+
mod tests {
61+
use crate::core_arch::x86_64::*;
62+
63+
#[test]
64+
fn test_bittest_u64() {
65+
unsafe {
66+
let a = 0b0101_0000u64;
67+
assert_eq!(_bittest_u64(&a, 4), 1);
68+
assert_eq!(_bittest_u64(&a, 5), 0);
69+
}
70+
}
71+
72+
#[test]
73+
fn test_bittestandset_u64() {
74+
unsafe {
75+
let mut a = 0b0101_0000u64;
76+
assert_eq!(_bittestandset_u64(&mut a, 4), 1);
77+
assert_eq!(_bittestandset_u64(&mut a, 4), 1);
78+
assert_eq!(_bittestandset_u64(&mut a, 5), 0);
79+
assert_eq!(_bittestandset_u64(&mut a, 5), 1);
80+
}
81+
}
82+
83+
#[test]
84+
fn test_bittestandreset_u64() {
85+
unsafe {
86+
let mut a = 0b0101_0000u64;
87+
assert_eq!(_bittestandreset_u64(&mut a, 4), 1);
88+
assert_eq!(_bittestandreset_u64(&mut a, 4), 0);
89+
assert_eq!(_bittestandreset_u64(&mut a, 5), 0);
90+
assert_eq!(_bittestandreset_u64(&mut a, 5), 0);
91+
}
92+
}
93+
94+
#[test]
95+
fn test_bittestandcomplement_u64() {
96+
unsafe {
97+
let mut a = 0b0101_0000u64;
98+
assert_eq!(_bittestandcomplement_u64(&mut a, 4), 1);
99+
assert_eq!(_bittestandcomplement_u64(&mut a, 4), 0);
100+
assert_eq!(_bittestandcomplement_u64(&mut a, 4), 1);
101+
assert_eq!(_bittestandcomplement_u64(&mut a, 5), 0);
102+
assert_eq!(_bittestandcomplement_u64(&mut a, 5), 1);
103+
}
104+
}
105+
}

crates/core_arch/src/x86_64/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,6 @@ pub use self::cmpxchg16b::*;
4444

4545
mod adx;
4646
pub use self::adx::*;
47+
48+
mod bt;
49+
pub use self::bt::*;

0 commit comments

Comments
 (0)