Skip to content

Commit 51bcfbd

Browse files
committed
Convert all uses of llvm_asm! to asm!
1 parent 35d17a6 commit 51bcfbd

File tree

12 files changed

+198
-139
lines changed

12 files changed

+198
-139
lines changed

crates/core_arch/src/acle/barrier/cp15.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,29 @@ pub struct SY;
88
impl super::super::sealed::Dmb for SY {
99
#[inline(always)]
1010
unsafe fn __dmb(&self) {
11-
llvm_asm!("mcr p15, 0, r0, c7, c10, 5" : : : "memory" : "volatile")
11+
asm!(
12+
"mcr p15, 0, r0, c7, c10, 5",
13+
options(preserves_flags, nostack)
14+
)
1215
}
1316
}
1417

1518
impl super::super::sealed::Dsb for SY {
1619
#[inline(always)]
1720
unsafe fn __dsb(&self) {
18-
llvm_asm!("mcr p15, 0, r0, c7, c10, 4" : : : "memory" : "volatile")
21+
asm!(
22+
"mcr p15, 0, r0, c7, c10, 4",
23+
options(preserves_flags, nostack)
24+
)
1925
}
2026
}
2127

2228
impl super::super::sealed::Isb for SY {
2329
#[inline(always)]
2430
unsafe fn __isb(&self) {
25-
llvm_asm!("mcr p15, 0, r0, c7, c5, 4" : : : "memory" : "volatile")
31+
asm!(
32+
"mcr p15, 0, r0, c7, c5, 4",
33+
options(preserves_flags, nostack)
34+
)
2635
}
2736
}

crates/core_arch/src/acle/hints.rs

+10-27
Original file line numberDiff line numberDiff line change
@@ -80,33 +80,12 @@ pub unsafe fn __yield() {
8080
// and ARMv7-R edition (ARM DDI 0406C.c) sections D12.4.1 "ARM instruction set support" and D12.4.2
8181
// "Thumb instruction set support"
8282
#[cfg(target_feature = "v7")]
83+
#[cfg(target_arch = "arm")]
8384
#[inline(always)]
84-
#[rustc_args_required_const(0)]
85-
pub unsafe fn __dbg(imm4: u32) {
86-
macro_rules! call {
87-
($imm4:expr) => {
88-
llvm_asm!(concat!("DBG ", stringify!($imm4)) : : : : "volatile")
89-
}
90-
}
91-
92-
match imm4 & 0b1111 {
93-
0 => call!(0),
94-
1 => call!(1),
95-
2 => call!(2),
96-
3 => call!(3),
97-
4 => call!(4),
98-
5 => call!(5),
99-
6 => call!(6),
100-
7 => call!(7),
101-
8 => call!(8),
102-
9 => call!(9),
103-
10 => call!(10),
104-
11 => call!(11),
105-
12 => call!(12),
106-
13 => call!(13),
107-
14 => call!(14),
108-
_ => call!(15),
109-
}
85+
#[rustc_legacy_const_generics(0)]
86+
pub unsafe fn __dbg<const imm4: i32>() {
87+
static_assert_imm4!(imm4);
88+
dbg(imm4);
11089
}
11190

11291
/// Generates an unspecified no-op instruction.
@@ -117,13 +96,17 @@ pub unsafe fn __dbg(imm4: u32) {
11796
/// will increase execution time.
11897
#[inline(always)]
11998
pub unsafe fn __nop() {
120-
llvm_asm!("NOP" : : : : "volatile")
99+
asm!("nop", options(nomem, nostack, preserves_flags));
121100
}
122101

123102
extern "C" {
124103
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.hint")]
125104
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.hint")]
126105
fn hint(_: i32);
106+
107+
#[cfg(target_arch = "arm")]
108+
#[link_name = "llvm.arm.dbg"]
109+
fn dbg(_: i32);
127110
}
128111

129112
// from LLVM 7.0.1's lib/Target/ARM/{ARMInstrThumb,ARMInstrInfo,ARMInstrThumb2}.td

crates/core_arch/src/acle/registers/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ macro_rules! rsr {
44
impl super::super::sealed::Rsr for $R {
55
unsafe fn __rsr(&self) -> u32 {
66
let r: u32;
7-
llvm_asm!(concat!("mrs $0,", stringify!($R)) : "=r"(r) : : : "volatile");
7+
asm!(concat!("mrs {},", stringify!($R)), out(reg) r, options(nomem, nostack));
88
r
99
}
1010
}
@@ -17,7 +17,7 @@ macro_rules! rsrp {
1717
impl super::super::sealed::Rsrp for $R {
1818
unsafe fn __rsrp(&self) -> *const u8 {
1919
let r: *const u8;
20-
llvm_asm!(concat!("mrs $0,", stringify!($R)) : "=r"(r) : : : "volatile");
20+
asm!(concat!("mrs {},", stringify!($R)), out(reg) r, options(nomem, nostack));
2121
r
2222
}
2323
}
@@ -29,7 +29,7 @@ macro_rules! wsr {
2929
($R:ident) => {
3030
impl super::super::sealed::Wsr for $R {
3131
unsafe fn __wsr(&self, value: u32) {
32-
llvm_asm!(concat!("msr ", stringify!($R), ",$0") : : "r"(value) : : "volatile");
32+
asm!(concat!("msr ", stringify!($R), ", {}"), in(reg) value, options(nomem, nostack));
3333
}
3434
}
3535
};
@@ -40,7 +40,7 @@ macro_rules! wsrp {
4040
($R:ident) => {
4141
impl super::super::sealed::Wsrp for $R {
4242
unsafe fn __wsrp(&self, value: *const u8) {
43-
llvm_asm!(concat!("msr ", stringify!($R), ",$0") : : "r"(value) : : "volatile");
43+
asm!(concat!("msr ", stringify!($R), ", {}"), in(reg) value, options(nomem, nostack));
4444
}
4545
}
4646
};

crates/core_arch/src/arm/armclang.rs

+22-40
Original file line numberDiff line numberDiff line change
@@ -11,58 +11,40 @@ use stdarch_test::assert_instr;
1111

1212
/// Inserts a breakpoint instruction.
1313
///
14-
/// `val` is a compile-time constant integer in range `[0, 255]`.
15-
///
16-
/// The breakpoint instruction inserted is:
14+
/// `val` is a compile-time constant integer in range `[0, 65535]`.
1715
///
18-
/// * `BKPT` when compiling as T32,
19-
/// * `BRK` when compiling as A32 or A64.
16+
/// The breakpoint instruction inserted is `BRK` on A64.
17+
#[cfg(target_arch = "aarch64")]
18+
#[cfg_attr(test, assert_instr(brk, val = 0))]
19+
#[inline(always)]
20+
#[rustc_legacy_const_generics(0)]
21+
pub unsafe fn __breakpoint<const val: i32>() {
22+
static_assert_imm16!(val);
23+
asm!("brk {}", const val);
24+
}
25+
26+
/// Inserts a breakpoint instruction.
2027
///
21-
/// # Safety
28+
/// `val` is a compile-time constant integer in range `[0, 255]`.
2229
///
23-
/// If `val` is out-of-range the behavior is **undefined**.
30+
/// The breakpoint instruction inserted is `BKPT` on A32/T32.
2431
///
2532
/// # Note
2633
///
2734
/// [ARM's documentation][arm_docs] defines that `__breakpoint` accepts the
2835
/// following values for `val`:
2936
///
30-
/// - `0...65535` when compiling as A32 or A64,
37+
/// - `0...65535` when compiling as A32,
3138
/// - `0...255` when compiling as T32.
3239
///
33-
/// The current implementation only accepts values in range `[0, 255]` - if the
34-
/// value is out-of-range the behavior is **undefined**.
40+
/// The current implementation only accepts values in range `[0, 255]`.
3541
///
3642
/// [arm_docs]: https://developer.arm.com/docs/100067/latest/compiler-specific-intrinsics/__breakpoint-intrinsic
37-
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(bkpt, val = 0))]
38-
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(brk, val = 0))]
43+
#[cfg(target_arch = "arm")]
44+
#[cfg_attr(test, assert_instr(bkpt, val = 0))]
3945
#[inline(always)]
40-
#[rustc_args_required_const(0)]
41-
pub unsafe fn __breakpoint(val: i32) {
42-
// Ensure that this compiles correctly on non-arm architectures, so libstd
43-
// doc builds work. The proper macro will shadow this definition below.
44-
#[allow(unused_macros)]
45-
macro_rules! call {
46-
($e:expr) => {
47-
()
48-
};
49-
}
50-
51-
#[cfg(target_arch = "arm")]
52-
macro_rules! call {
53-
($imm8:expr) => {
54-
llvm_asm!(concat!("BKPT ", stringify!($imm8)) : : : : "volatile")
55-
}
56-
}
57-
58-
#[cfg(target_arch = "aarch64")]
59-
macro_rules! call {
60-
($imm8:expr) => {
61-
llvm_asm!(concat!("BRK ", stringify!($imm8)) : : : : "volatile")
62-
}
63-
}
64-
65-
// We can't `panic!` inside this intrinsic, so we can't really validate the
66-
// arguments here. If `val` is out-of-range this macro uses `val == 255`:
67-
constify_imm8!(val, call);
46+
#[rustc_legacy_const_generics(0)]
47+
pub unsafe fn __breakpoint<const val: i32>() {
48+
static_assert_imm8!(val);
49+
asm!("bkpt #{}", const val);
6850
}

crates/core_arch/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
platform_intrinsics,
1313
repr_simd,
1414
simd_ffi,
15-
llvm_asm,
1615
proc_macro_hygiene,
1716
stmt_expr_attributes,
1817
core_intrinsics,

crates/core_arch/src/macros.rs

+7
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ macro_rules! static_assert_imm8 {
5858
};
5959
}
6060

61+
#[allow(unused_macros)]
62+
macro_rules! static_assert_imm16 {
63+
($imm:ident) => {
64+
let _ = $crate::core_arch::macros::ValidateConstImm::<$imm, 0, { (1 << 16) - 1 }>::VALID;
65+
};
66+
}
67+
6168
#[allow(unused)]
6269
macro_rules! static_assert {
6370
($imm:ident : $ty:ty where $e:expr) => {

crates/core_arch/src/x86/bt.rs

+52-16
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,19 @@ use stdarch_test::assert_instr;
77
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
88
pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
99
let r: u8;
10-
llvm_asm!("btl $2, $1\n\tsetc ${0:b}"
11-
: "=r"(r)
12-
: "*m"(p), "r"(b)
13-
: "cc", "memory");
10+
#[cfg(not(doc))]
11+
asm!(
12+
"bt [{p}], {b:e}",
13+
"setc {r}",
14+
p = in(reg) p,
15+
b = in(reg) b,
16+
r = out(reg_byte) r,
17+
options(readonly, nostack, pure)
18+
);
19+
#[cfg(doc)]
20+
{
21+
r = 0;
22+
}
1423
r
1524
}
1625

@@ -20,10 +29,19 @@ pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
2029
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
2130
pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
2231
let r: u8;
23-
llvm_asm!("btsl $2, $1\n\tsetc ${0:b}"
24-
: "=r"(r), "+*m"(p)
25-
: "r"(b)
26-
: "cc", "memory");
32+
#[cfg(not(doc))]
33+
asm!(
34+
"bts [{p}], {b:e}",
35+
"setc {r}",
36+
p = in(reg) p,
37+
b = in(reg) b,
38+
r = out(reg_byte) r,
39+
options(nostack)
40+
);
41+
#[cfg(doc)]
42+
{
43+
r = 0;
44+
}
2745
r
2846
}
2947

@@ -33,10 +51,19 @@ pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
3351
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
3452
pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
3553
let r: u8;
36-
llvm_asm!("btrl $2, $1\n\tsetc ${0:b}"
37-
: "=r"(r), "+*m"(p)
38-
: "r"(b)
39-
: "cc", "memory");
54+
#[cfg(not(doc))]
55+
asm!(
56+
"btr [{p}], {b:e}",
57+
"setc {r}",
58+
p = in(reg) p,
59+
b = in(reg) b,
60+
r = out(reg_byte) r,
61+
options(nostack)
62+
);
63+
#[cfg(doc)]
64+
{
65+
r = 0;
66+
}
4067
r
4168
}
4269

@@ -46,10 +73,19 @@ pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
4673
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
4774
pub unsafe fn _bittestandcomplement(p: *mut i32, b: i32) -> u8 {
4875
let r: u8;
49-
llvm_asm!("btcl $2, $1\n\tsetc ${0:b}"
50-
: "=r"(r), "+*m"(p)
51-
: "r"(b)
52-
: "cc", "memory");
76+
#[cfg(not(doc))]
77+
asm!(
78+
"btc [{p}], {b:e}",
79+
"setc {r}",
80+
p = in(reg) p,
81+
b = in(reg) b,
82+
r = out(reg_byte) r,
83+
options(nostack)
84+
);
85+
#[cfg(doc)]
86+
{
87+
r = 0;
88+
}
5389
r
5490
}
5591

crates/core_arch/src/x86/cpuid.rs

+19-24
Original file line numberDiff line numberDiff line change
@@ -125,30 +125,25 @@ pub fn has_cpuid() -> bool {
125125
// the 21st bit of the EFLAGS register is modifiable or not.
126126
// If it is, then `cpuid` is available.
127127
let result: u32;
128-
let _temp: u32;
129-
llvm_asm!(r#"
130-
# Read eflags into $0 and copy it into $1:
131-
pushfd
132-
pop $0
133-
mov $1, $0
134-
# Flip 21st bit of $0.
135-
xor $0, 0x200000
136-
# Set eflags to the value of $0
137-
#
138-
# Bit 21st can only be modified if cpuid is available
139-
push $0
140-
popfd # A
141-
# Read eflags into $0:
142-
pushfd # B
143-
pop $0
144-
# xor with the original eflags sets the bits that
145-
# have been modified:
146-
xor $0, $1
147-
"#
148-
: "=r"(result), "=r"(_temp)
149-
:
150-
: "cc", "memory"
151-
: "intel");
128+
asm!(
129+
// Read eflags and save a copy of it
130+
"pushf",
131+
"pop {result}",
132+
"mov {saved_flags}, {result}",
133+
// Flip 21st bit of the flags
134+
"xor {result}, 0x200000",
135+
// Load the modified flags and read them back.
136+
// Bit 21 can only be modified if cpuid is available.
137+
"push {result}",
138+
"popf",
139+
"pushf",
140+
"pop {result}",
141+
// Use xor to find out whether bit 21 has changed
142+
"xor {result}, {saved_flags}",
143+
result = out(reg) result,
144+
saved_flags = out(reg) _,
145+
options(nomem),
146+
);
152147
// There is a race between popfd (A) and pushfd (B)
153148
// where other bits beyond 21st may have been modified due to
154149
// interrupts, a debugger stepping through the asm, etc.

0 commit comments

Comments
 (0)