[PATCH, GCC/ARM, 6/10] Clear GPRs inline when calling nscall function
[official-gcc.git] / gcc / testsuite / gcc.target / arm / cmse / cmse-1.c
blob9f36fa3b1d8b86b4e1827909fca4fee181ba1c61
1 /* { dg-do compile } */
2 /* { dg-options "-Os -mcmse -fdump-rtl-expand" } */
4 #include <arm_cmse.h>
6 extern int a;
7 extern int bar (void);
9 int foo (char * p)
11 cmse_address_info_t cait;
13 cait = cmse_TT (&a);
14 if (cait.flags.mpu_region)
15 a++;
17 cait = cmse_TT_fptr (&bar);
18 if (cait.flags.mpu_region)
19 a+= bar ();
21 cait = cmse_TTA (&a);
22 if (cait.flags.mpu_region)
23 a++;
25 cait = cmse_TTA_fptr (&bar);
26 if (cait.flags.mpu_region)
27 a+= bar ();
29 cait = cmse_TTT (&a);
30 if (cait.flags.mpu_region)
31 a++;
33 cait = cmse_TTT_fptr (&bar);
34 if (cait.flags.mpu_region)
35 a+= bar ();
37 cait = cmse_TTAT (&a);
38 if (cait.flags.mpu_region)
39 a++;
41 cait = cmse_TTAT_fptr (&bar);
42 if (cait.flags.mpu_region)
43 a+= bar ();
45 p = (char *) cmse_check_address_range ((void *) p, sizeof (char), 0);
46 p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
47 CMSE_MPU_UNPRIV);
48 p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
49 CMSE_MPU_READWRITE);
50 p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
51 CMSE_MPU_UNPRIV | CMSE_MPU_READ);
52 p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
53 CMSE_AU_NONSECURE
54 | CMSE_MPU_NONSECURE);
55 p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
56 CMSE_NONSECURE | CMSE_MPU_UNPRIV);
58 p = (char *) cmse_check_pointed_object (p, CMSE_NONSECURE | CMSE_MPU_UNPRIV);
60 return a;
62 /* { dg-final { scan-assembler-times "\ttt " 2 } } */
63 /* { dg-final { scan-assembler-times "ttt " 2 } } */
64 /* { dg-final { scan-assembler-times "tta " 2 } } */
65 /* { dg-final { scan-assembler-times "ttat " 2 } } */
66 /* { dg-final { scan-assembler-times "bl.cmse_check_address_range" 7 } } */
67 /* { dg-final { scan-assembler-not "cmse_check_pointed_object" } } */
69 int __attribute__ ((cmse_nonsecure_entry))
70 baz (void)
72 return cmse_nonsecure_caller ();
74 /* { dg-final { scan-assembler "baz:" } } */
75 /* { dg-final { scan-assembler "__acle_se_baz:" } } */
76 /* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */
77 /* Look for an andsi of 1 with a register in function baz, ie.
79 ;; Function baz<anything>
80 <any line without '('>
81 (insn <anything but '('> (set (reg<any register modifier>:SI <anything but ')'>)
82 (and:SI (reg<any register modifier>:SI <anything but ')'>)
83 (const_int 1 <anything but ')'>)<anything but '('>
84 <optional: (nil)<anything but '('>>
85 (insn
87 /* { dg-final { scan-rtl-dump "\n;; Function baz\[^\n\]*\[^(\]+\[^;\]*\n\\(insn \[^(\]+ \\(set \\(reg\[^:\]*:SI \[^)\]+\\)\[^(\]*\\(and:SI \\(reg\[^:\]*:SI \[^)\]+\\)\[^(\]*\\((const_int 1|reg\[^:\]*:SI) \[^)\]+\\)\[^(\]+(\\(nil\\)\[^(\]+)?\\(insn" expand } } */
89 typedef int __attribute__ ((cmse_nonsecure_call)) (int_nsfunc_t) (void);
91 int default_callback (void)
93 return 0;
96 int_nsfunc_t * fp = (int_nsfunc_t *) default_callback;
98 void __attribute__ ((cmse_nonsecure_entry))
99 qux (int_nsfunc_t * callback)
101 fp = cmse_nsfptr_create (callback);
103 /* { dg-final { scan-assembler "qux:" } } */
104 /* { dg-final { scan-assembler "__acle_se_qux:" } } */
105 /* { dg-final { scan-assembler "bic" } } */
106 /* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */
107 /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!" { target arm_cmse_clear_ok } } } */
108 /* { dg-final { scan-assembler "vscclrm\t\{s0-s15, VPR\}" { target arm_cmse_clear_ok } } } */
109 /* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, ip, APSR\}" { target arm_cmse_clear_ok } } } */
110 /* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" { target arm_cmse_clear_ok } } } */
111 /* { dg-final { scan-assembler "msr\tAPSR_nzcvq" { target { ! arm_cmse_clear_ok } } } } */
112 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
113 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" { target arm_cmse_clear_ok } } } */
114 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
116 int call_callback (void)
118 if (cmse_is_nsfptr (fp))
119 return fp ();
120 else
121 return default_callback ();
123 /* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 1 } } */