Skip to content

Commit 378f055

Browse files
mehcodegnzlbg
authored andcommitted
Add bittest instructions for x85
1 parent 9b6567b commit 378f055

File tree

5 files changed

+220
-0
lines changed

5 files changed

+220
-0
lines changed

crates/core_arch/src/x86/bt.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#[cfg(test)]
2+
use stdsimd_test::assert_instr;
3+
4+
/// Returns the bit in position `b` of the memory addressed by `p`.
5+
#[inline]
6+
#[cfg_attr(test, assert_instr(bt))]
7+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
8+
pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
9+
let r: u8;
10+
asm!("btl $2, $1\n\tsetc ${0:b}"
11+
: "=r"(r)
12+
: "*m"(p), "r"(b)
13+
: "cc", "memory");
14+
r
15+
}
16+
17+
/// Returns the bit in position `b` of the memory addressed by `p`, then sets the bit to `1`.
18+
#[inline]
19+
#[cfg_attr(test, assert_instr(bts))]
20+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
21+
pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
22+
let r: u8;
23+
asm!("btsl $2, $1\n\tsetc ${0:b}"
24+
: "=r"(r), "+*m"(p)
25+
: "r"(b)
26+
: "cc", "memory");
27+
r
28+
}
29+
30+
/// Returns the bit in position `b` of the memory addressed by `p`, then resets that bit to `0`.
31+
#[inline]
32+
#[cfg_attr(test, assert_instr(btr))]
33+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
34+
pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
35+
let r: u8;
36+
asm!("btrl $2, $1\n\tsetc ${0:b}"
37+
: "=r"(r), "+*m"(p)
38+
: "r"(b)
39+
: "cc", "memory");
40+
r
41+
}
42+
43+
/// Returns the bit in position `b` of the memory addressed by `p`, then inverts that bit.
44+
#[inline]
45+
#[cfg_attr(test, assert_instr(btc))]
46+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
47+
pub unsafe fn _bittestandcomplement(p: *mut i32, b: i32) -> u8 {
48+
let r: u8;
49+
asm!("btcl $2, $1\n\tsetc ${0:b}"
50+
: "=r"(r), "+*m"(p)
51+
: "r"(b)
52+
: "cc", "memory");
53+
r
54+
}
55+
56+
#[cfg(test)]
57+
mod tests {
58+
use crate::core_arch::x86::*;
59+
60+
#[test]
61+
fn test_bittest() {
62+
unsafe {
63+
let a = 0b0101_0000i32;
64+
assert_eq!(_bittest(&a as _, 4), 1);
65+
assert_eq!(_bittest(&a as _, 5), 0);
66+
}
67+
}
68+
69+
#[test]
70+
fn test_bittestandset() {
71+
unsafe {
72+
let mut a = 0b0101_0000i32;
73+
assert_eq!(_bittestandset(&mut a as _, 4), 1);
74+
assert_eq!(_bittestandset(&mut a as _, 4), 1);
75+
assert_eq!(_bittestandset(&mut a as _, 5), 0);
76+
assert_eq!(_bittestandset(&mut a as _, 5), 1);
77+
}
78+
}
79+
80+
#[test]
81+
fn test_bittestandreset() {
82+
unsafe {
83+
let mut a = 0b0101_0000i32;
84+
assert_eq!(_bittestandreset(&mut a as _, 4), 1);
85+
assert_eq!(_bittestandreset(&mut a as _, 4), 0);
86+
assert_eq!(_bittestandreset(&mut a as _, 5), 0);
87+
assert_eq!(_bittestandreset(&mut a as _, 5), 0);
88+
}
89+
}
90+
91+
#[test]
92+
fn test_bittestandcomplement() {
93+
unsafe {
94+
let mut a = 0b0101_0000i32;
95+
assert_eq!(_bittestandcomplement(&mut a as _, 4), 1);
96+
assert_eq!(_bittestandcomplement(&mut a as _, 4), 0);
97+
assert_eq!(_bittestandcomplement(&mut a as _, 4), 1);
98+
assert_eq!(_bittestandcomplement(&mut a as _, 5), 0);
99+
assert_eq!(_bittestandcomplement(&mut a as _, 5), 1);
100+
}
101+
}
102+
}

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: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#[cfg(test)]
2+
use stdsimd_test::assert_instr;
3+
4+
/// Returns the bit in position `b` of the memory addressed by `p`.
5+
#[inline]
6+
#[cfg_attr(test, assert_instr(bt))]
7+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
8+
pub unsafe fn _bittest64(p: *const i64, b: i64) -> u8 {
9+
let r: u8;
10+
asm!("btq $2, $1\n\tsetc ${0:b}"
11+
: "=r"(r)
12+
: "*m"(p), "r"(b)
13+
: "cc", "memory");
14+
r
15+
}
16+
17+
/// Returns the bit in position `b` of the memory addressed by `p`, then sets the bit to `1`.
18+
#[inline]
19+
#[cfg_attr(test, assert_instr(bts))]
20+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
21+
pub unsafe fn _bittestandset64(p: *mut i64, b: i64) -> u8 {
22+
let r: u8;
23+
asm!("btsq $2, $1\n\tsetc ${0:b}"
24+
: "=r"(r), "+*m"(p)
25+
: "r"(b)
26+
: "cc", "memory");
27+
r
28+
}
29+
30+
/// Returns the bit in position `b` of the memory addressed by `p`, then resets that bit to `0`.
31+
#[inline]
32+
#[cfg_attr(test, assert_instr(btr))]
33+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
34+
pub unsafe fn _bittestandreset64(p: *mut i64, b: i64) -> u8 {
35+
let r: u8;
36+
asm!("btrq $2, $1\n\tsetc ${0:b}"
37+
: "=r"(r), "+*m"(p)
38+
: "r"(b)
39+
: "cc", "memory");
40+
r
41+
}
42+
43+
/// Returns the bit in position `b` of the memory addressed by `p`, then inverts that bit.
44+
#[inline]
45+
#[cfg_attr(test, assert_instr(btc))]
46+
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
47+
pub unsafe fn _bittestandcomplement64(p: *mut i64, b: i64) -> u8 {
48+
let r: u8;
49+
asm!("btcq $2, $1\n\tsetc ${0:b}"
50+
: "=r"(r), "+*m"(p)
51+
: "r"(b)
52+
: "cc", "memory");
53+
r
54+
}
55+
56+
#[cfg(test)]
57+
mod tests {
58+
use crate::core_arch::x86_64::*;
59+
60+
#[test]
61+
fn test_bittest64() {
62+
unsafe {
63+
let a = 0b0101_0000i64;
64+
assert_eq!(_bittest64(&a as _, 4), 1);
65+
assert_eq!(_bittest64(&a as _, 5), 0);
66+
}
67+
}
68+
69+
#[test]
70+
fn test_bittestandset64() {
71+
unsafe {
72+
let mut a = 0b0101_0000i64;
73+
assert_eq!(_bittestandset64(&mut a as _, 4), 1);
74+
assert_eq!(_bittestandset64(&mut a as _, 4), 1);
75+
assert_eq!(_bittestandset64(&mut a as _, 5), 0);
76+
assert_eq!(_bittestandset64(&mut a as _, 5), 1);
77+
}
78+
}
79+
80+
#[test]
81+
fn test_bittestandreset64() {
82+
unsafe {
83+
let mut a = 0b0101_0000i64;
84+
assert_eq!(_bittestandreset64(&mut a as _, 4), 1);
85+
assert_eq!(_bittestandreset64(&mut a as _, 4), 0);
86+
assert_eq!(_bittestandreset64(&mut a as _, 5), 0);
87+
assert_eq!(_bittestandreset64(&mut a as _, 5), 0);
88+
}
89+
}
90+
91+
#[test]
92+
fn test_bittestandcomplement64() {
93+
unsafe {
94+
let mut a = 0b0101_0000i64;
95+
assert_eq!(_bittestandcomplement64(&mut a as _, 4), 1);
96+
assert_eq!(_bittestandcomplement64(&mut a as _, 4), 0);
97+
assert_eq!(_bittestandcomplement64(&mut a as _, 4), 1);
98+
assert_eq!(_bittestandcomplement64(&mut a as _, 5), 0);
99+
assert_eq!(_bittestandcomplement64(&mut a as _, 5), 1);
100+
}
101+
}
102+
}

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::*;

crates/stdsimd-verify/tests/x86-intel.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,15 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
246246
// the `x` inside the name which requires adx
247247
"_addcarry_u32" | "_addcarry_u64" | "_subborrow_u32" | "_subborrow_u64" => {}
248248

249+
"_bittest"
250+
| "_bittestandset"
251+
| "_bittestandreset"
252+
| "_bittestandcomplement"
253+
| "_bittest64"
254+
| "_bittestandset64"
255+
| "_bittestandreset64"
256+
| "_bittestandcomplement64" => {}
257+
249258
_ => {
250259
if intel.cpuid.is_empty() {
251260
bail!("missing cpuid for {}", rust.name);
@@ -423,6 +432,7 @@ fn equate(t: &Type, intel: &str, intrinsic: &str, is_const: bool) -> Result<(),
423432
(&Type::Ptr(&Type::PrimFloat(32)), "float*") => {}
424433
(&Type::Ptr(&Type::PrimFloat(64)), "double*") => {}
425434
(&Type::Ptr(&Type::PrimSigned(32)), "int*") => {}
435+
(&Type::Ptr(&Type::PrimSigned(32)), "__int32*") => {}
426436
(&Type::Ptr(&Type::PrimSigned(64)), "__int64*") => {}
427437
(&Type::Ptr(&Type::PrimSigned(8)), "char*") => {}
428438
(&Type::Ptr(&Type::PrimUnsigned(16)), "unsigned short*") => {}

0 commit comments

Comments
 (0)