1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=thumbv8.1m.main-eabi -mattr=+8msecext,+mve.fp %s -o - | FileCheck %s --check-prefix=CHECK-SOFTFP 3; RUN: llc -mtriple=thumbebv8.1m.main-eabi -mattr=+8msecext,+mve.fp %s -o - | FileCheck %s --check-prefix=CHECK-SOFTFP 4; RUN: llc -mtriple=thumbv8.1m.main-eabi -mattr=+8msecext,+mve.fp --float-abi=hard %s -o - | FileCheck %s --check-prefix=CHECK-HARD 5; RUN: llc -mtriple=thumbebv8.1m.main-eabi -mattr=+8msecext,+mve.fp --float-abi=hard %s -o - | FileCheck %s --check-prefix=CHECK-HARD 6 7declare <8 x i16> @g0(...) #0 8declare <4 x float> @g1(...) #0 9 10;; 11;; Test clearing before return to nonsecure state 12;; 13 14define <8 x i16> @f0() #1 { 15; CHECK-SOFTFP-LABEL: f0: 16; CHECK-SOFTFP: @ %bb.0: @ %entry 17; CHECK-SOFTFP-NEXT: vstr fpcxtns, [sp, #-4]! 18; CHECK-SOFTFP-NEXT: .save {r7, lr} 19; CHECK-SOFTFP-NEXT: push {r7, lr} 20; CHECK-SOFTFP-NEXT: .pad #4 21; CHECK-SOFTFP-NEXT: sub sp, #4 22; CHECK-SOFTFP-NEXT: bl g0 23; CHECK-SOFTFP-NEXT: add sp, #4 24; CHECK-SOFTFP-NEXT: pop.w {r7, lr} 25; CHECK-SOFTFP-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr} 26; CHECK-SOFTFP-NEXT: vldr fpcxtns, [sp], #4 27; CHECK-SOFTFP-NEXT: clrm {r12, apsr} 28; CHECK-SOFTFP-NEXT: bxns lr 29; 30; CHECK-HARD-LABEL: f0: 31; CHECK-HARD: @ %bb.0: @ %entry 32; CHECK-HARD-NEXT: vstr fpcxtns, [sp, #-4]! 33; CHECK-HARD-NEXT: .save {r7, lr} 34; CHECK-HARD-NEXT: push {r7, lr} 35; CHECK-HARD-NEXT: .pad #4 36; CHECK-HARD-NEXT: sub sp, #4 37; CHECK-HARD-NEXT: bl g0 38; CHECK-HARD-NEXT: add sp, #4 39; CHECK-HARD-NEXT: pop.w {r7, lr} 40; CHECK-HARD-NEXT: vscclrm {s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr} 41; CHECK-HARD-NEXT: vldr fpcxtns, [sp], #4 42; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r12, apsr} 43; CHECK-HARD-NEXT: bxns lr 44entry: 45 %call = call <8 x i16> @g0() #0 46 ret <8 x i16> %call 47} 48 49define <4 x float> @f1() #1 { 50; CHECK-SOFTFP-LABEL: f1: 51; CHECK-SOFTFP: @ %bb.0: @ %entry 52; CHECK-SOFTFP-NEXT: vstr fpcxtns, [sp, #-4]! 53; CHECK-SOFTFP-NEXT: .save {r7, lr} 54; CHECK-SOFTFP-NEXT: push {r7, lr} 55; CHECK-SOFTFP-NEXT: .pad #4 56; CHECK-SOFTFP-NEXT: sub sp, #4 57; CHECK-SOFTFP-NEXT: bl g1 58; CHECK-SOFTFP-NEXT: add sp, #4 59; CHECK-SOFTFP-NEXT: pop.w {r7, lr} 60; CHECK-SOFTFP-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr} 61; CHECK-SOFTFP-NEXT: vldr fpcxtns, [sp], #4 62; CHECK-SOFTFP-NEXT: clrm {r12, apsr} 63; CHECK-SOFTFP-NEXT: bxns lr 64; 65; CHECK-HARD-LABEL: f1: 66; CHECK-HARD: @ %bb.0: @ %entry 67; CHECK-HARD-NEXT: vstr fpcxtns, [sp, #-4]! 68; CHECK-HARD-NEXT: .save {r7, lr} 69; CHECK-HARD-NEXT: push {r7, lr} 70; CHECK-HARD-NEXT: .pad #4 71; CHECK-HARD-NEXT: sub sp, #4 72; CHECK-HARD-NEXT: bl g1 73; CHECK-HARD-NEXT: add sp, #4 74; CHECK-HARD-NEXT: pop.w {r7, lr} 75; CHECK-HARD-NEXT: vscclrm {s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr} 76; CHECK-HARD-NEXT: vldr fpcxtns, [sp], #4 77; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r12, apsr} 78; CHECK-HARD-NEXT: bxns lr 79entry: 80 %call = call nnan ninf nsz <4 x float> @g1() #0 81 ret <4 x float> %call 82} 83 84;; 85;; Test clearing around nonsecure calls 86;; 87 88define void @f2(ptr nocapture %cb) #0 { 89; CHECK-SOFTFP-LABEL: f2: 90; CHECK-SOFTFP: @ %bb.0: @ %entry 91; CHECK-SOFTFP-NEXT: .save {r4, lr} 92; CHECK-SOFTFP-NEXT: push {r4, lr} 93; CHECK-SOFTFP-NEXT: mov r4, r0 94; CHECK-SOFTFP-NEXT: bl g0 95; CHECK-SOFTFP-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} 96; CHECK-SOFTFP-NEXT: bic r4, r4, #1 97; CHECK-SOFTFP-NEXT: sub sp, #136 98; CHECK-SOFTFP-NEXT: vlstm sp 99; CHECK-SOFTFP-NEXT: clrm {r5, r6, r7, r8, r9, r10, r11, r12, apsr} 100; CHECK-SOFTFP-NEXT: blxns r4 101; CHECK-SOFTFP-NEXT: vlldm sp 102; CHECK-SOFTFP-NEXT: add sp, #136 103; CHECK-SOFTFP-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} 104; CHECK-SOFTFP-NEXT: pop {r4, pc} 105; 106; CHECK-HARD-LABEL: f2: 107; CHECK-HARD: @ %bb.0: @ %entry 108; CHECK-HARD-NEXT: .save {r4, lr} 109; CHECK-HARD-NEXT: push {r4, lr} 110; CHECK-HARD-NEXT: mov r4, r0 111; CHECK-HARD-NEXT: bl g0 112; CHECK-HARD-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} 113; CHECK-HARD-NEXT: bic r4, r4, #1 114; CHECK-HARD-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} 115; 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} 116; CHECK-HARD-NEXT: vstr fpcxts, [sp, #-8]! 117; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11, r12, apsr} 118; CHECK-HARD-NEXT: blxns r4 119; CHECK-HARD-NEXT: vldr fpcxts, [sp], #8 120; CHECK-HARD-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} 121; CHECK-HARD-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} 122; CHECK-HARD-NEXT: pop {r4, pc} 123entry: 124 %call = tail call <8 x i16> @g0() #0 125 tail call void %cb(<8 x i16> %call) #2 126 ret void 127} 128 129define void @f3(ptr nocapture %cb) #0 { 130; CHECK-SOFTFP-LABEL: f3: 131; CHECK-SOFTFP: @ %bb.0: @ %entry 132; CHECK-SOFTFP-NEXT: .save {r4, lr} 133; CHECK-SOFTFP-NEXT: push {r4, lr} 134; CHECK-SOFTFP-NEXT: mov r4, r0 135; CHECK-SOFTFP-NEXT: bl g1 136; CHECK-SOFTFP-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} 137; CHECK-SOFTFP-NEXT: bic r4, r4, #1 138; CHECK-SOFTFP-NEXT: sub sp, #136 139; CHECK-SOFTFP-NEXT: vlstm sp 140; CHECK-SOFTFP-NEXT: clrm {r5, r6, r7, r8, r9, r10, r11, r12, apsr} 141; CHECK-SOFTFP-NEXT: blxns r4 142; CHECK-SOFTFP-NEXT: vlldm sp 143; CHECK-SOFTFP-NEXT: add sp, #136 144; CHECK-SOFTFP-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} 145; CHECK-SOFTFP-NEXT: pop {r4, pc} 146; 147; CHECK-HARD-LABEL: f3: 148; CHECK-HARD: @ %bb.0: @ %entry 149; CHECK-HARD-NEXT: .save {r4, lr} 150; CHECK-HARD-NEXT: push {r4, lr} 151; CHECK-HARD-NEXT: mov r4, r0 152; CHECK-HARD-NEXT: bl g1 153; CHECK-HARD-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} 154; CHECK-HARD-NEXT: bic r4, r4, #1 155; CHECK-HARD-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} 156; 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} 157; CHECK-HARD-NEXT: vstr fpcxts, [sp, #-8]! 158; CHECK-HARD-NEXT: clrm {r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11, r12, apsr} 159; CHECK-HARD-NEXT: blxns r4 160; CHECK-HARD-NEXT: vldr fpcxts, [sp], #8 161; CHECK-HARD-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} 162; CHECK-HARD-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} 163; CHECK-HARD-NEXT: pop {r4, pc} 164entry: 165 %call = tail call nnan ninf nsz <4 x float> @g1() #0 166 tail call void %cb(<4 x float> %call) #2 167 ret void 168} 169 170attributes #0 = { nounwind } 171attributes #1 = { nounwind "cmse_nonsecure_entry" } 172attributes #2 = { nounwind "cmse_nonsecure_call" } 173