Hi, I changed the testcase with this patch since the old testcase was casting a function pointer to another function pointer and using that pointer to call the function. This is undefined behavior. The new test reflects a more sane use of the intrinsics.
Cheers, Andre
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c index 5ed38d1608cfbfbd1248d76705fcf675bc36c2b2..14444206814fb95268ba5ba008245513b0dc94f1 100644 --- a/gcc/config/arm/arm-builtins.c +++ b/gcc/config/arm/arm-builtins.c @@ -528,6 +528,8 @@ enum arm_builtins ARM_BUILTIN_GET_FPSCR, ARM_BUILTIN_SET_FPSCR, + ARM_BUILTIN_CMSE_NONSECURE_CALLER, + #undef CRYPTO1 #undef CRYPTO2 #undef CRYPTO3 @@ -1833,6 +1835,17 @@ arm_init_builtins (void) = add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr, ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE); } + + if (use_cmse) + { + tree ftype_cmse_nonsecure_caller + = build_function_type_list (unsigned_type_node, NULL); + arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER] + = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller", + ftype_cmse_nonsecure_caller, + ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD, + NULL, NULL_TREE); + } } /* Return the ARM builtin for CODE. */ @@ -2453,6 +2466,12 @@ arm_expand_builtin (tree exp, emit_insn (pat); return target; + case ARM_BUILTIN_CMSE_NONSECURE_CALLER: + target = gen_reg_rtx (SImode); + op0 = arm_return_addr (0, NULL_RTX); + emit_insn (gen_addsi3 (target, op0, const1_rtx)); + return target; + case ARM_BUILTIN_TEXTRMSB: case ARM_BUILTIN_TEXTRMUB: case ARM_BUILTIN_TEXTRMSH: diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h index 894343bb835b61e09c14668d45aa43a8693fd011..82b58b1c4f4a12ba6062e2cc2632653788d0eeb7 100644 --- a/gcc/config/arm/arm_cmse.h +++ b/gcc/config/arm/arm_cmse.h @@ -163,6 +163,13 @@ __attribute__ ((__always_inline__)) cmse_TTAT (void *__p) __CMSE_TT_ASM (at) +/* FIXME: diagnose use outside cmse_nonsecure_entry functions. */ +__extension__ static __inline int __attribute__ ((__always_inline__)) +cmse_nonsecure_caller (void) +{ + return __builtin_arm_cmse_nonsecure_caller (); +} + #define CMSE_AU_NONSECURE 2 #define CMSE_MPU_NONSECURE 16 #define CMSE_NONSECURE 18 diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e8d8deefca87eacbdde6042fc1885c0d0a85a5b8..587a30d7efc6b1f2653efe96ed233828ebeb570a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -12640,6 +12640,7 @@ cmse_address_info_t cmse_TTAT_fptr (FPTR) void * cmse_check_address_range (void *, size_t, int) typeof(p) cmse_nsfptr_create (FPTR p) intptr_t cmse_is_nsfptr (FPTR) +int cmse_nonsecure_caller (void) @end smallexample @node AVR Built-in Functions diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c index d5b9a2d9d59569de170da814ae660e9fb2b943e7..c13272eed683aa06db027cd4646e5fe67817212b 100644 --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c @@ -65,3 +65,42 @@ int foo (char * p) /* { dg-final { scan-assembler-times "ttat " 2 } } */ /* { dg-final { scan-assembler-times "bl.cmse_check_address_range" 7 } } */ /* { dg-final { scan-assembler-not "cmse_check_pointed_object" } } */ + +int __attribute__ ((cmse_nonsecure_entry)) +baz (void) +{ + return cmse_nonsecure_caller (); +} + +typedef int __attribute__ ((cmse_nonsecure_call)) (int_nsfunc_t) (void); + +int default_callback (void) +{ + return 0; +} + +int_nsfunc_t * fp = (int_nsfunc_t *) default_callback; + +void __attribute__ ((cmse_nonsecure_entry)) +qux (int_nsfunc_t * callback) +{ + fp = cmse_nsfptr_create (callback); +} + +int call_callback (void) +{ + if (cmse_is_nsfptr (fp)) + return fp (); + else + return default_callback (); +} +/* { dg-final { scan-assembler "baz:" } } */ +/* { dg-final { scan-assembler "__acle_se_baz:" } } */ +/* { dg-final { scan-assembler "qux:" } } */ +/* { dg-final { scan-assembler "__acle_se_qux:" } } */ +/* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */ +/* { dg-final { scan-rtl-dump "and.*reg.*const_int 1" expand } } */ +/* { dg-final { scan-assembler "bic" } } */ +/* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */ +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" } } */ +/* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 1 } } */