Skip to content

Commit e81e77c

Browse files
committed
Move away from llvm_asm to new asm.
In my opinion, this makes the constraints a _lot_ easier to read, and gets us things like noreturn. (Plus, it moves us off a deprecated feature whose days are numbered.) asm has opinions about trying to use r11. These opinions are misguided: rust-lang/rust#73450 However, we respect them by manually moving values in and out of r11 in the asm sequences.
1 parent b3b29b5 commit e81e77c

File tree

11 files changed

+192
-160
lines changed

11 files changed

+192
-160
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![no_std]
22
#![no_main]
3-
#![feature(llvm_asm)]
43

54
#[cfg(not(any(feature = "panic-itm", feature = "panic-semihosting")))]
65
compile_error!(

kern/src/arch/arm_m.rs

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -567,19 +567,16 @@ pub fn start_first_task(task: &task::Task) -> ! {
567567
}
568568

569569
unsafe {
570-
llvm_asm! { "
571-
msr PSP, $0 @ set the user stack pointer
572-
ldm $1, {r4-r11} @ restore the callee-save registers
570+
asm!("
571+
msr PSP, {user_sp} @ set the user stack pointer
572+
ldm {task}, {{r4-r11}} @ restore the callee-save registers
573573
svc #0xFF @ branch into user mode (svc # ignored)
574574
udf #0xad @ should not return
575-
"
576-
:
577-
: "r"(task.save.psp),
578-
"r"(&task.save.r4)
579-
: "memory"
580-
: "volatile"
581-
}
582-
core::hint::unreachable_unchecked()
575+
",
576+
user_sp = in(reg) task.save.psp,
577+
task = in(reg) &task.save.r4,
578+
options(noreturn),
579+
)
583580
}
584581
}
585582

@@ -593,7 +590,7 @@ pub unsafe extern "C" fn SVCall() {
593590
// of instructions below, though the precise details depend on how complex
594591
// of an M-series processor you're targeting -- so I've punted on this for
595592
// the time being.
596-
llvm_asm! {"
593+
asm!("
597594
cmp lr, #0xFFFFFFF9 @ is it coming from inside the kernel?
598595
beq 1f @ if so, we're starting the first task;
599596
@ jump ahead.
@@ -608,7 +605,7 @@ pub unsafe extern "C" fn SVCall() {
608605
@ fetching into r12 means the order in the stm below is right.
609606
mrs r12, PSP
610607
@ now, store volatile registers, plus the PSP in r12, plus LR.
611-
stm r1, {r4-r12, lr}
608+
stm r1, {{r4-r12, lr}}
612609
613610
@ syscall number is passed in r11. Move it into r0 to pass it as an
614611
@ argument to the handler, then call the handler.
@@ -620,7 +617,7 @@ pub unsafe extern "C" fn SVCall() {
620617
movt r0, #:upper16:CURRENT_TASK_PTR
621618
ldr r0, [r0]
622619
@ restore volatile registers, plus load PSP into r12
623-
ldm r0, {r4-r12, lr}
620+
ldm r0, {{r4-r12, lr}}
624621
msr PSP, r12
625622
626623
@ resume
@@ -636,12 +633,9 @@ pub unsafe extern "C" fn SVCall() {
636633
@ return into thread mode, PSP, FP on
637634
638635
bx lr @ branch into user mode
639-
"
640-
:
641-
:
642-
:
643-
: "volatile"
644-
}
636+
",
637+
options(noreturn),
638+
)
645639
}
646640

647641
/// Manufacture a mutable/exclusive reference to the task table from thin air
@@ -745,7 +739,7 @@ fn pend_context_switch_from_isr() {
745739
#[naked]
746740
#[no_mangle]
747741
pub unsafe extern "C" fn PendSV() {
748-
llvm_asm! {"
742+
asm!("
749743
@ store volatile state.
750744
@ first, get a pointer to the current task.
751745
movw r0, #:lower16:CURRENT_TASK_PTR
@@ -755,7 +749,7 @@ pub unsafe extern "C" fn PendSV() {
755749
@ fetching into r12 means the order in the stm below is right.
756750
mrs r12, PSP
757751
@ now, store volatile registers, plus the PSP in r12, plus LR.
758-
stm r1, {r4-r12, lr}
752+
stm r1, {{r4-r12, lr}}
759753
760754
@ syscall number is passed in r11. Move it into r0 to pass it as an
761755
@ argument to the handler, then call the handler.
@@ -766,17 +760,14 @@ pub unsafe extern "C" fn PendSV() {
766760
movt r0, #:upper16:CURRENT_TASK_PTR
767761
ldr r0, [r0]
768762
@ restore volatile registers, plus load PSP into r12
769-
ldm r0, {r4-r12, lr}
763+
ldm r0, {{r4-r12, lr}}
770764
msr PSP, r12
771765
772766
@ resume
773767
bx lr
774-
"
775-
:
776-
:
777-
:
778-
: "volatile"
779-
}
768+
",
769+
options(noreturn),
770+
);
780771
}
781772

782773
/// The Rust side of the PendSV handler, after all volatile registers have been
@@ -803,10 +794,11 @@ pub unsafe extern "C" fn DefaultHandler() {
803794
// We can cheaply get the identity of the interrupt that called us from the
804795
// bottom 9 bits of IPSR.
805796
let mut ipsr: u32;
806-
llvm_asm! {
807-
"mrs $0, IPSR"
808-
: "=r"(ipsr)
809-
}
797+
asm!(
798+
"mrs {}, IPSR",
799+
out(reg) ipsr,
800+
options(pure, nomem, preserves_flags, nostack),
801+
);
810802
let exception_num = ipsr & 0x1FF;
811803

812804
// The first 16 exceptions are architecturally defined; vendor hardware
@@ -882,7 +874,7 @@ pub fn enable_irq(n: u32) {
882874
#[no_mangle]
883875
#[naked]
884876
pub unsafe extern "C" fn MemoryManagement() {
885-
llvm_asm! { "
877+
asm!("
886878
@ Get the exc_return value into an argument register, which is
887879
@ difficult to do from higher-level code.
888880
mov r0, lr
@@ -891,9 +883,9 @@ pub unsafe extern "C" fn MemoryManagement() {
891883
movt r1, #:upper16:CURRENT_TASK_PTR
892884
ldr r1, [r1]
893885
b mem_manage_fault
894-
"
895-
::::"volatile"
896-
}
886+
",
887+
options(noreturn),
888+
);
897889
}
898890

899891
bitflags::bitflags! {

kern/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
//! most clever algorithms used in kernels wind up requiring `unsafe`.)
2424
2525
#![cfg_attr(target_os = "none", no_std)]
26-
#![feature(llvm_asm)]
26+
#![feature(asm)]
2727
#![feature(naked_functions)]
2828

2929
#[macro_use]

lpc55/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![no_std]
22
#![no_main]
3-
#![feature(llvm_asm)]
43

54
#[cfg(not(any(feature = "panic-itm", feature = "panic-semihosting")))]
65
compile_error!(

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2020-05-01
1+
nightly-2020-06-10

task-idle/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2018"
88
# suppress default features to avoid including panic message collection, to
99
# ensure the idle task remains tiny.
1010
userlib = {path = "../userlib", default-features = false}
11+
cortex-m = {version = "0.6", features = ["inline-asm"]}
1112

1213
[features]
1314
default = ["standalone"]

task-idle/src/main.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![no_std]
22
#![no_main]
3-
#![feature(llvm_asm)]
43

54
// Make sure we actually link in userlib, despite not using any of it explicitly
65
// - we need it for our _start routine.
@@ -9,11 +8,8 @@ extern crate userlib;
98
#[export_name = "main"]
109
fn main() -> ! {
1110
loop {
12-
// Safety: asm in general is unsafe, but this instruction is fine.
13-
unsafe {
14-
// Wait For Interrupt to pause the processor until an ISR arrives,
15-
// which could wake some higher-priority task.
16-
llvm_asm!("wfi"::::"volatile");
17-
}
11+
// Wait For Interrupt to pause the processor until an ISR arrives,
12+
// which could wake some higher-priority task.
13+
cortex_m::asm::wfi();
1814
}
1915
}

task-ping/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![no_std]
22
#![no_main]
3-
#![feature(llvm_asm)]
43

54
use userlib::*;
65

task-spam2/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![no_std]
22
#![no_main]
3-
#![feature(llvm_asm)]
43

54
// Make sure we actually link in userlib, despite not using any of it explicitly
65
// - we need it for our _start routine.

0 commit comments

Comments
 (0)