Improve assembly test for CMSE ABIs
This ensures the code-gen for these ABIs does not change silently. Co-authored-by: Folkert <folkert@folkertdev.nl>
This commit is contained in:
parent
a772336fb3
commit
3d168c28f6
@ -1,6 +1,9 @@
|
|||||||
|
//@ revisions: hard soft
|
||||||
//@ assembly-output: emit-asm
|
//@ assembly-output: emit-asm
|
||||||
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
|
//@ [hard] compile-flags: --target thumbv8m.main-none-eabihf --crate-type lib -Copt-level=1
|
||||||
//@ needs-llvm-components: arm
|
//@ [soft] compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
|
||||||
|
//@ [hard] needs-llvm-components: arm
|
||||||
|
//@ [soft] needs-llvm-components: arm
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)]
|
#![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
@ -9,15 +12,88 @@ pub trait Sized {}
|
|||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
pub trait Copy {}
|
pub trait Copy {}
|
||||||
|
|
||||||
// CHECK-LABEL: __acle_se_entry_point
|
// CHECK-LABEL: __acle_se_entry_point:
|
||||||
// CHECK: bxns
|
// CHECK-NEXT: entry_point:
|
||||||
|
//
|
||||||
|
// Write return argument (two registers since 64bit integer)
|
||||||
|
// CHECK: movs r0, #0
|
||||||
|
// CHECK: movs r1, #0
|
||||||
|
//
|
||||||
|
// If we are using hard-float:
|
||||||
|
// * Check if the float registers were touched (bit 3 in CONTROL)
|
||||||
|
// hard: mrs [[REG:r[0-9]+]], control
|
||||||
|
// hard: tst.w [[REG]], #8
|
||||||
|
// hard: beq [[LABEL:[\.a-zA-Z0-9_]+]]
|
||||||
|
//
|
||||||
|
// * If touched clear all float registers (d0..=d7)
|
||||||
|
// hard: vmov d0,
|
||||||
|
// hard: vmov d1,
|
||||||
|
// hard: vmov d2,
|
||||||
|
// hard: vmov d3,
|
||||||
|
// hard: vmov d4,
|
||||||
|
// hard: vmov d5,
|
||||||
|
// hard: vmov d6,
|
||||||
|
// hard: vmov d7,
|
||||||
|
//
|
||||||
|
// * If touched clear FPU status register
|
||||||
|
// hard: vmrs [[REG:r[0-9]+]], fpscr
|
||||||
|
// hard: bic [[REG]], [[REG]], #159
|
||||||
|
// hard: bic [[REG]], [[REG]], #4026531840
|
||||||
|
// hard: vmsr fpscr, [[REG]]
|
||||||
|
// hard: [[LABEL]]:
|
||||||
|
//
|
||||||
|
// Clear all other registers that might have been used
|
||||||
|
// CHECK: mov r2,
|
||||||
|
// CHECK: mov r3,
|
||||||
|
// CHECK: mov r12,
|
||||||
|
//
|
||||||
|
// Clear the flags
|
||||||
|
// CHECK: msr apsr_nzcvq,
|
||||||
|
//
|
||||||
|
// Branch back to non-secure side
|
||||||
|
// CHECK: bxns lr
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C-cmse-nonsecure-entry" fn entry_point() -> i64 {
|
pub extern "C-cmse-nonsecure-entry" fn entry_point() -> i64 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE for future codegen changes:
|
||||||
|
// The specific register assignment is not important, however:
|
||||||
|
// * all registers must be cleared before `blxns` is executed
|
||||||
|
// (either by writing arguments or any other value)
|
||||||
|
// * the lowest bit on the address of the callee must be cleared
|
||||||
|
// * the flags need to be overwritten
|
||||||
|
// * `blxns` needs to be called with the callee address
|
||||||
|
// (with the lowest bit cleared)
|
||||||
|
//
|
||||||
// CHECK-LABEL: call_nonsecure
|
// CHECK-LABEL: call_nonsecure
|
||||||
// CHECK: blxns
|
// Save callee pointer
|
||||||
|
// CHECK: mov r12, r0
|
||||||
|
//
|
||||||
|
// All arguments are written to (writes r0..=r3)
|
||||||
|
// CHECK: movs r0, #0
|
||||||
|
// CHECK: movs r1, #1
|
||||||
|
// CHECK: movs r2, #2
|
||||||
|
// CHECK: movs r3, #3
|
||||||
|
//
|
||||||
|
// Lowest bit gets cleared on callee address
|
||||||
|
// CHECK: bic r12, r12, #1
|
||||||
|
//
|
||||||
|
// Ununsed registers get cleared (r4..=r11)
|
||||||
|
// CHECK: mov r4,
|
||||||
|
// CHECK: mov r5,
|
||||||
|
// CHECK: mov r6,
|
||||||
|
// CHECK: mov r7,
|
||||||
|
// CHECK: mov r8,
|
||||||
|
// CHECK: mov r9,
|
||||||
|
// CHECK: mov r10,
|
||||||
|
// CHECK: mov r11,
|
||||||
|
//
|
||||||
|
// Flags get cleared
|
||||||
|
// CHECK: msr apsr_nzcvq,
|
||||||
|
//
|
||||||
|
// Call to non-secure
|
||||||
|
// CHECK: blxns r12
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn call_nonsecure(
|
pub fn call_nonsecure(
|
||||||
f: unsafe extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u64,
|
f: unsafe extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u64,
|
||||||
|
Loading…
Reference in New Issue
Block a user