Skip to content

Commit 068f60e

Browse files
tdittrfolkertdev
andcommitted
Improve assembly test for CMSE ABIs
This ensures the code-gen for these ABIs does not change silently. Co-authored-by: Folkert <[email protected]>
1 parent a772336 commit 068f60e

File tree

1 file changed

+78
-4
lines changed

1 file changed

+78
-4
lines changed

tests/assembly/cmse.rs

+78-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
//@ revisions: hard soft
12
//@ assembly-output: emit-asm
2-
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
3-
//@ needs-llvm-components: arm
3+
//@ [hard] compile-flags: --target thumbv8m.main-none-eabihf --crate-type lib -Copt-level=1
4+
//@ [soft] compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
5+
//@ [hard] needs-llvm-components: arm
6+
//@ [soft] needs-llvm-components: arm
47
#![crate_type = "lib"]
58
#![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)]
69
#![no_core]
@@ -10,14 +13,85 @@ pub trait Sized {}
1013
pub trait Copy {}
1114

1215
// CHECK-LABEL: __acle_se_entry_point
13-
// CHECK: bxns
16+
// CHECK: entry_point:
17+
//
18+
// Write return argument (two registers since 64bit integer)
19+
// CHECK: movs r0, #0
20+
// CHECK: movs r1, #0
21+
//
22+
// If we are using hard-float:
23+
// * Check if the float registers were touched (bit 3 in CONTROL)
24+
// hard: mrs r12, control
25+
// hard: tst.w r12, #8
26+
// hard: beq .LBB0_2
27+
//
28+
// * If touched clear all float registers (d0..=d7)
29+
// hard: vmov d0, lr, lr
30+
// hard: vmov d1, lr, lr
31+
// hard: vmov d2, lr, lr
32+
// hard: vmov d3, lr, lr
33+
// hard: vmov d4, lr, lr
34+
// hard: vmov d5, lr, lr
35+
// hard: vmov d6, lr, lr
36+
// hard: vmov d7, lr, lr
37+
//
38+
// * If touched clear FPU status register
39+
// hard: vmrs r12, fpscr
40+
// hard: bic r12, r12, #159
41+
// hard: bic r12, r12, #4026531840
42+
// hard: vmsr fpscr, r12
43+
// hard: .LBB0_2:
44+
//
45+
// Clear all other registers that might have been used
46+
// CHECK: mov r2, lr
47+
// CHECK: mov r3, lr
48+
// CHECK: mov r12, lr
49+
//
50+
// Clear the flags
51+
// CHECK: msr apsr_nzcvq, lr
52+
//
53+
// Branch back to non-secure side
54+
// CHECK: bxns lr
1455
#[no_mangle]
1556
pub extern "C-cmse-nonsecure-entry" fn entry_point() -> i64 {
1657
0
1758
}
1859

60+
// NOTE for future codegen changes:
61+
// The specific register assignment is not important, however:
62+
// * all registers must be cleared before `blxns` is executed
63+
// (either by writing arguments or any other value)
64+
// * the lowest bit on the address of the callee must be cleared
65+
// * the flags need to be overwritten
66+
// * `blxns` needs to be called with the callee address
67+
// (with the lowest bit cleared)
68+
//
1969
// CHECK-LABEL: call_nonsecure
20-
// CHECK: blxns
70+
// All arguments are written to (writes r0..=r3 and r12)
71+
// CHECK: mov r12, r0
72+
// CHECK: movs r0, #0
73+
// CHECK: movs r1, #1
74+
// CHECK: movs r2, #2
75+
// CHECK: movs r3, #3
76+
//
77+
// Lowest bit gets cleared on callee address
78+
// CHECK: bic r12, r12, #1
79+
//
80+
// Ununsed registers get cleared (r4..=r11)
81+
// CHECK: mov r4, r12
82+
// CHECK: mov r5, r12
83+
// CHECK: mov r6, r12
84+
// CHECK: mov r7, r12
85+
// CHECK: mov r8, r12
86+
// CHECK: mov r9, r12
87+
// CHECK: mov r10, r12
88+
// CHECK: mov r11, r12
89+
//
90+
// Flags get cleared
91+
// CHECK: msr apsr_nzcvq, r12
92+
//
93+
// Call to non-secure
94+
// CHECK: blxns r12
2195
#[no_mangle]
2296
pub fn call_nonsecure(
2397
f: unsafe extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u64,

0 commit comments

Comments
 (0)