Fix asm! in bit-test intrinsics on x32

This commit is contained in:
Amanieu d'Antras 2021-05-08 19:28:32 +01:00
parent 994a4250a9
commit e9f73d0dc8
2 changed files with 40 additions and 8 deletions

View file

@ -1,6 +1,22 @@
#[cfg(test)]
use stdarch_test::assert_instr;
// x32 wants to use a 32-bit address size, but asm! defaults to using the full
// register name (e.g. rax). We have to explicitly override the placeholder to
// use the 32-bit register name in that case.
#[cfg(target_pointer_width = "32")]
macro_rules! bt {
($inst:expr) => {
concat!($inst, " {b:e}, ({p:e})")
};
}
#[cfg(target_pointer_width = "64")]
macro_rules! bt {
($inst:expr) => {
concat!($inst, " {b:e}, ({p})")
};
}
/// Returns the bit in position `b` of the memory addressed by `p`.
#[inline]
#[cfg_attr(test, assert_instr(bt))]
@ -8,7 +24,7 @@ use stdarch_test::assert_instr;
pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
let r: u8;
asm!(
"btl {b:e}, ({p})",
bt!("btl"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,
@ -25,7 +41,7 @@ pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
let r: u8;
asm!(
"btsl {b:e}, ({p})",
bt!("btsl"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,
@ -42,7 +58,7 @@ pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
let r: u8;
asm!(
"btrl {b:e}, ({p})",
bt!("btrl"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,
@ -59,7 +75,7 @@ pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
pub unsafe fn _bittestandcomplement(p: *mut i32, b: i32) -> u8 {
let r: u8;
asm!(
"btcl {b:e}, ({p})",
bt!("btcl"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,

View file

@ -1,6 +1,22 @@
#[cfg(test)]
use stdarch_test::assert_instr;
// x32 wants to use a 32-bit address size, but asm! defaults to using the full
// register name (e.g. rax). We have to explicitly override the placeholder to
// use the 32-bit register name in that case.
#[cfg(target_pointer_width = "32")]
macro_rules! bt {
($inst:expr) => {
concat!($inst, " {b}, ({p:e})")
};
}
#[cfg(target_pointer_width = "64")]
macro_rules! bt {
($inst:expr) => {
concat!($inst, " {b}, ({p})")
};
}
/// Returns the bit in position `b` of the memory addressed by `p`.
#[inline]
#[cfg_attr(test, assert_instr(bt))]
@ -8,7 +24,7 @@ use stdarch_test::assert_instr;
pub unsafe fn _bittest64(p: *const i64, b: i64) -> u8 {
let r: u8;
asm!(
"btq {b}, ({p})",
bt!("btq"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,
@ -25,7 +41,7 @@ pub unsafe fn _bittest64(p: *const i64, b: i64) -> u8 {
pub unsafe fn _bittestandset64(p: *mut i64, b: i64) -> u8 {
let r: u8;
asm!(
"btsq {b}, ({p})",
bt!("btsq"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,
@ -42,7 +58,7 @@ pub unsafe fn _bittestandset64(p: *mut i64, b: i64) -> u8 {
pub unsafe fn _bittestandreset64(p: *mut i64, b: i64) -> u8 {
let r: u8;
asm!(
"btrq {b}, ({p})",
bt!("btrq"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,
@ -59,7 +75,7 @@ pub unsafe fn _bittestandreset64(p: *mut i64, b: i64) -> u8 {
pub unsafe fn _bittestandcomplement64(p: *mut i64, b: i64) -> u8 {
let r: u8;
asm!(
"btcq {b}, ({p})",
bt!("btcq"),
"setc {r}",
p = in(reg) p,
b = in(reg) b,