; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=thumbv8.1m.main-eabi -mattr=+8msecext,+mve.fp %s -o - | FileCheck %s --check-prefix=CHECK-SOFTFP
; RUN: llc -mtriple=thumbebv8.1m.main-eabi -mattr=+8msecext,+mve.fp %s -o - | FileCheck %s --check-prefix=CHECK-SOFTFP
; RUN: llc -mtriple=thumbv8.1m.main-eabi -mattr=+8msecext,+mve.fp --float-abi=hard %s -o - | FileCheck %s --check-prefix=CHECK-HARD
; RUN: llc -mtriple=thumbebv8.1m.main-eabi -mattr=+8msecext,+mve.fp --float-abi=hard %s -o - | FileCheck %s --check-prefix=CHECK-HARD
declare <8 x i16> @g0(...) #0
declare <4 x float> @g1(...) #0
;;
;; Test clearing before return to nonsecure state
;;
define <8 x i16> @f0() #1 {
; CHECK-SOFTFP-LABEL: f0:
; CHECK-SOFTFP: @ %bb.0: @ %entry
; CHECK-SOFTFP-NEXT: vstr fpcxtns, [sp, #-4]!
; CHECK-SOFTFP-NEXT: .save {r7, lr}
; CHECK-SOFTFP-NEXT: push {r7, lr}
; CHECK-SOFTFP-NEXT: .pad #4
; CHECK-SOFTFP-NEXT: sub sp, #4
; CHECK-SOFTFP-NEXT: bl g0
; CHECK-SOFTFP-NEXT: add sp, #4
; CHECK-SOFTFP-NEXT: pop.w {r7, lr}
; CHECK-SOFTFP-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
; CHECK-SOFTFP-NEXT: vldr fpcxtns, [sp], #4
; CHECK-SOFTFP-NEXT: clrm {r12, apsr}
; CHECK-SOFTFP-NEXT: bxns lr
;
; CHECK-HARD-LABEL: f0:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: vstr fpcxtns, [sp, #-4]!
; CHECK-HARD-NEXT: .save {r7, lr}
; CHECK-HARD-NEXT: push {r7, lr}
; CHECK-HARD-NEXT: .pad #4
; CHECK-HARD-NEXT: sub sp, #4
; CHECK-HARD-NEXT: bl g0
; CHECK-HARD-NEXT: add sp, #4
; CHECK-HARD-NEXT: pop.w {r7, lr}
; CHECK-HARD-NEXT: vscclrm {s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
; CHECK-HARD-NEXT: vldr fpcxtns, [sp], #4
; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r12, apsr}
; CHECK-HARD-NEXT: bxns lr
entry:
%call = call <8 x i16> @g0() #0
ret <8 x i16> %call
}
define <4 x float> @f1() #1 {
; CHECK-SOFTFP-LABEL: f1:
; CHECK-SOFTFP: @ %bb.0: @ %entry
; CHECK-SOFTFP-NEXT: vstr fpcxtns, [sp, #-4]!
; CHECK-SOFTFP-NEXT: .save {r7, lr}
; CHECK-SOFTFP-NEXT: push {r7, lr}
; CHECK-SOFTFP-NEXT: .pad #4
; CHECK-SOFTFP-NEXT: sub sp, #4
; CHECK-SOFTFP-NEXT: bl g1
; CHECK-SOFTFP-NEXT: add sp, #4
; CHECK-SOFTFP-NEXT: pop.w {r7, lr}
; CHECK-SOFTFP-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
; CHECK-SOFTFP-NEXT: vldr fpcxtns, [sp], #4
; CHECK-SOFTFP-NEXT: clrm {r12, apsr}
; CHECK-SOFTFP-NEXT: bxns lr
;
; CHECK-HARD-LABEL: f1:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: vstr fpcxtns, [sp, #-4]!
; CHECK-HARD-NEXT: .save {r7, lr}
; CHECK-HARD-NEXT: push {r7, lr}
; CHECK-HARD-NEXT: .pad #4
; CHECK-HARD-NEXT: sub sp, #4
; CHECK-HARD-NEXT: bl g1
; CHECK-HARD-NEXT: add sp, #4
; CHECK-HARD-NEXT: pop.w {r7, lr}
; CHECK-HARD-NEXT: vscclrm {s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
; CHECK-HARD-NEXT: vldr fpcxtns, [sp], #4
; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r12, apsr}
; CHECK-HARD-NEXT: bxns lr
entry:
%call = call nnan ninf nsz <4 x float> @g1() #0
ret <4 x float> %call
}
;;
;; Test clearing around nonsecure calls
;;
define void @f2(ptr nocapture %cb) #0 {
; CHECK-SOFTFP-LABEL: f2:
; CHECK-SOFTFP: @ %bb.0: @ %entry
; CHECK-SOFTFP-NEXT: .save {r4, lr}
; CHECK-SOFTFP-NEXT: push {r4, lr}
; CHECK-SOFTFP-NEXT: mov r4, r0
; CHECK-SOFTFP-NEXT: bl g0
; CHECK-SOFTFP-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-SOFTFP-NEXT: bic r4, r4, #1
; CHECK-SOFTFP-NEXT: sub sp, #136
; CHECK-SOFTFP-NEXT: vlstm sp
; CHECK-SOFTFP-NEXT: clrm {r5, r6, r7, r8, r9, r10, r11, r12, apsr}
; CHECK-SOFTFP-NEXT: blxns r4
; CHECK-SOFTFP-NEXT: vlldm sp
; CHECK-SOFTFP-NEXT: add sp, #136
; CHECK-SOFTFP-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-SOFTFP-NEXT: pop {r4, pc}
;
; CHECK-HARD-LABEL: f2:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: .save {r4, lr}
; CHECK-HARD-NEXT: push {r4, lr}
; CHECK-HARD-NEXT: mov r4, r0
; CHECK-HARD-NEXT: bl g0
; CHECK-HARD-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-HARD-NEXT: bic r4, r4, #1
; CHECK-HARD-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31}
; CHECK-HARD-NEXT: vscclrm {s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, vpr}
; CHECK-HARD-NEXT: vstr fpcxts, [sp, #-8]!
; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
; CHECK-HARD-NEXT: blxns r4
; CHECK-HARD-NEXT: vldr fpcxts, [sp], #8
; CHECK-HARD-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31}
; CHECK-HARD-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-HARD-NEXT: pop {r4, pc}
entry:
%call = tail call <8 x i16> @g0() #0
tail call void %cb(<8 x i16> %call) #2
ret void
}
define void @f3(ptr nocapture %cb) #0 {
; CHECK-SOFTFP-LABEL: f3:
; CHECK-SOFTFP: @ %bb.0: @ %entry
; CHECK-SOFTFP-NEXT: .save {r4, lr}
; CHECK-SOFTFP-NEXT: push {r4, lr}
; CHECK-SOFTFP-NEXT: mov r4, r0
; CHECK-SOFTFP-NEXT: bl g1
; CHECK-SOFTFP-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-SOFTFP-NEXT: bic r4, r4, #1
; CHECK-SOFTFP-NEXT: sub sp, #136
; CHECK-SOFTFP-NEXT: vlstm sp
; CHECK-SOFTFP-NEXT: clrm {r5, r6, r7, r8, r9, r10, r11, r12, apsr}
; CHECK-SOFTFP-NEXT: blxns r4
; CHECK-SOFTFP-NEXT: vlldm sp
; CHECK-SOFTFP-NEXT: add sp, #136
; CHECK-SOFTFP-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-SOFTFP-NEXT: pop {r4, pc}
;
; CHECK-HARD-LABEL: f3:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: .save {r4, lr}
; CHECK-HARD-NEXT: push {r4, lr}
; CHECK-HARD-NEXT: mov r4, r0
; CHECK-HARD-NEXT: bl g1
; CHECK-HARD-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-HARD-NEXT: bic r4, r4, #1
; CHECK-HARD-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31}
; CHECK-HARD-NEXT: vscclrm {s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, vpr}
; CHECK-HARD-NEXT: vstr fpcxts, [sp, #-8]!
; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
; CHECK-HARD-NEXT: blxns r4
; CHECK-HARD-NEXT: vldr fpcxts, [sp], #8
; CHECK-HARD-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31}
; CHECK-HARD-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
; CHECK-HARD-NEXT: pop {r4, pc}
entry:
%call = tail call nnan ninf nsz <4 x float> @g1() #0
tail call void %cb(<4 x float> %call) #2
ret void
}
attributes #0 = { nounwind }
attributes #1 = { nounwind "cmse_nonsecure_entry" }
attributes #2 = { nounwind "cmse_nonsecure_call" }