Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve assembly test for CMSE ABIs #130752

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 81 additions & 5 deletions tests/assembly/cmse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//@ revisions: hard soft
//@ assembly-output: emit-asm
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
//@ needs-llvm-components: arm
//@ [hard] compile-flags: --target thumbv8m.main-none-eabihf --crate-type lib -Copt-level=1
//@ [soft] compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
tdittr marked this conversation as resolved.
Show resolved Hide resolved
//@ [hard] needs-llvm-components: arm
//@ [soft] needs-llvm-components: arm
jieyouxu marked this conversation as resolved.
Show resolved Hide resolved
#![crate_type = "lib"]
#![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)]
#![no_core]
Expand All @@ -9,15 +12,88 @@ pub trait Sized {}
#[lang = "copy"]
pub trait Copy {}

// CHECK-LABEL: __acle_se_entry_point
// CHECK: bxns
// CHECK-LABEL: __acle_se_entry_point:
// 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,
jieyouxu marked this conversation as resolved.
Show resolved Hide resolved
// 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,
jieyouxu marked this conversation as resolved.
Show resolved Hide resolved
//
// Branch back to non-secure side
// CHECK: bxns lr
#[no_mangle]
pub extern "C-cmse-nonsecure-entry" fn entry_point() -> i64 {
0
}

// NOTE for future codegen changes:
// The specific register assignment is not important, however:
jieyouxu marked this conversation as resolved.
Show resolved Hide resolved
// * 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: 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]
pub fn call_nonsecure(
f: unsafe extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u64,
Expand Down
Loading