Skip to content

Commit cd07522

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

File tree

12 files changed

+161
-140
lines changed

12 files changed

+161
-140
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

+11-27
Original file line numberDiff line numberDiff line change
@@ -80,33 +80,13 @@ 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(any(target_arch = "arm", doc))]
84+
#[doc(cfg(target_arch = "arm"))]
8385
#[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-
}
86+
#[rustc_legacy_const_generics(0)]
87+
pub unsafe fn __dbg<const IMM4: i32>() {
88+
static_assert_imm4!(IMM4);
89+
dbg(IMM4);
11090
}
11191

11292
/// Generates an unspecified no-op instruction.
@@ -117,13 +97,17 @@ pub unsafe fn __dbg(imm4: u32) {
11797
/// will increase execution time.
11898
#[inline(always)]
11999
pub unsafe fn __nop() {
120-
llvm_asm!("NOP" : : : : "volatile")
100+
asm!("nop", options(nomem, nostack, preserves_flags));
121101
}
122102

123103
extern "C" {
124104
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.hint")]
125105
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.hint")]
126106
fn hint(_: i32);
107+
108+
#[cfg(target_arch = "arm")]
109+
#[link_name = "llvm.arm.dbg"]
110+
fn dbg(_: i32);
127111
}
128112

129113
// 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

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

1212
/// Inserts a breakpoint instruction.
1313
///
14-
/// `val` is a compile-time constant integer in range `[0, 255]`.
14+
/// `VAL` is a compile-time constant integer in range `[0, 65535]`.
1515
///
16-
/// The breakpoint instruction inserted is:
17-
///
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(all(target_arch = "aarch64", not(doc)))]
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
28-
/// following values for `val`:
35+
/// 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(any(target_arch = "arm", doc))]
44+
#[doc(cfg(target_arch = "arm"))]
45+
#[cfg_attr(test, assert_instr(bkpt, VAL = 0))]
3946
#[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);
47+
#[rustc_legacy_const_generics(0)]
48+
pub unsafe fn __breakpoint<const VAL: i32>() {
49+
static_assert_imm8!(VAL);
50+
asm!("bkpt #{}", const VAL);
6851
}

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

+32-16
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ 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+
asm!(
11+
"bt [{p}], {b:e}",
12+
"setc {r}",
13+
p = in(reg) p,
14+
b = in(reg) b,
15+
r = out(reg_byte) r,
16+
options(readonly, nostack, pure)
17+
);
1418
r
1519
}
1620

@@ -20,10 +24,14 @@ pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 {
2024
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
2125
pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
2226
let r: u8;
23-
llvm_asm!("btsl $2, $1\n\tsetc ${0:b}"
24-
: "=r"(r), "+*m"(p)
25-
: "r"(b)
26-
: "cc", "memory");
27+
asm!(
28+
"bts [{p}], {b:e}",
29+
"setc {r}",
30+
p = in(reg) p,
31+
b = in(reg) b,
32+
r = out(reg_byte) r,
33+
options(nostack)
34+
);
2735
r
2836
}
2937

@@ -33,10 +41,14 @@ pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 {
3341
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
3442
pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
3543
let r: u8;
36-
llvm_asm!("btrl $2, $1\n\tsetc ${0:b}"
37-
: "=r"(r), "+*m"(p)
38-
: "r"(b)
39-
: "cc", "memory");
44+
asm!(
45+
"btr [{p}], {b:e}",
46+
"setc {r}",
47+
p = in(reg) p,
48+
b = in(reg) b,
49+
r = out(reg_byte) r,
50+
options(nostack)
51+
);
4052
r
4153
}
4254

@@ -46,10 +58,14 @@ pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 {
4658
#[unstable(feature = "simd_x86_bittest", issue = "59414")]
4759
pub unsafe fn _bittestandcomplement(p: *mut i32, b: i32) -> u8 {
4860
let r: u8;
49-
llvm_asm!("btcl $2, $1\n\tsetc ${0:b}"
50-
: "=r"(r), "+*m"(p)
51-
: "r"(b)
52-
: "cc", "memory");
61+
asm!(
62+
"btc [{p}], {b:e}",
63+
"setc {r}",
64+
p = in(reg) p,
65+
b = in(reg) b,
66+
r = out(reg_byte) r,
67+
options(nostack)
68+
);
5369
r
5470
}
5571

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+
"pushfd",
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+
"popfd",
139+
"pushfd",
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.

crates/core_arch/src/x86/eflags.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#[doc(hidden)]
1414
pub unsafe fn __readeflags() -> u32 {
1515
let eflags: u32;
16-
llvm_asm!("pushfd; popl $0" : "=r"(eflags) : : : "volatile");
16+
asm!("pushfd", "pop {}", out(reg) eflags, options(nomem));
1717
eflags
1818
}
1919

@@ -30,7 +30,7 @@ pub unsafe fn __readeflags() -> u32 {
3030
#[doc(hidden)]
3131
pub unsafe fn __readeflags() -> u64 {
3232
let eflags: u64;
33-
llvm_asm!("pushfq; popq $0" : "=r"(eflags) : : : "volatile");
33+
asm!("pushfq", "pop {}", out(reg) eflags, options(nomem));
3434
eflags
3535
}
3636

@@ -46,7 +46,7 @@ pub unsafe fn __readeflags() -> u64 {
4646
)]
4747
#[doc(hidden)]
4848
pub unsafe fn __writeeflags(eflags: u32) {
49-
llvm_asm!("pushl $0; popfd" : : "r"(eflags) : "cc", "flags" : "volatile");
49+
asm!("push {}", "popfd", in(reg) eflags, options(nomem));
5050
}
5151

5252
/// Write EFLAGS.
@@ -61,7 +61,7 @@ pub unsafe fn __writeeflags(eflags: u32) {
6161
)]
6262
#[doc(hidden)]
6363
pub unsafe fn __writeeflags(eflags: u64) {
64-
llvm_asm!("pushq $0; popfq" : : "r"(eflags) : "cc", "flags" : "volatile");
64+
asm!("push {}", "popfq", in(reg) eflags, options(nomem));
6565
}
6666

6767
#[cfg(test)]

0 commit comments

Comments
 (0)