diff mbox

[PATCHv2,1/7,ARM,V8M] Add support for ARMv8-M's Secure Extensions flag and intrinsics

Message ID 580F87B2.7090407@arm.com
State New
Headers show

Commit Message

Andre Vieira (lists) Oct. 25, 2016, 4:26 p.m. UTC
On 24/08/16 12:00, Andre Vieira (lists) wrote:
> On 25/07/16 14:19, Andre Vieira (lists) wrote:
>> This patch adds the support of the '-mcmse' option to enable ARMv8-M's
>> Security Extensions and supports the following intrinsics:
>> cmse_TT
>> cmse_TT_fptr
>> cmse_TTT
>> cmse_TTT_fptr
>> cmse_TTA
>> cmse_TTA_fptr
>> cmse_TTAT
>> cmse_TTAT_fptr
>> cmse_check_address_range
>> cmse_check_pointed_object
>> cmse_is_nsfptr
>> cmse_nsfptr_create
>>
>> It also defines the mandatory cmse_address_info struct and the
>> __ARM_FEATURE_CMSE macro.
>> See Chapter 4, Sections 5.2, 5.3 and 5.6 of ARM®v8-M Security
>> Extensions: Requirements on Development Tools
>> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
>>
>> *** gcc/ChangeLog ***
>> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>
>>         * config.gcc (extra_headers): Added arm_cmse.h.
>>         * config/arm/arm-arches.def (ARM_ARCH):
>>         (armv8-m): Add FL2_CMSE.
>>         (armv8-m.main): Likewise.
>>         (armv8-m.main+dsp): Likewise.
>>         * config/arm/arm-c.c
>>         (arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
>>         * config/arm/arm-protos.h
>>         (arm_is_constant_pool_ref): Define FL2_CMSE.
>>         * config/arm.c (arm_arch_cmse): New.
>>         (arm_option_override): New error for unsupported cmse target.
>>         * config/arm/arm.h (arm_arch_cmse): New.
>>         * config/arm/arm.opt (mcmse): New.
>>         * doc/invoke.texi (ARM Options): Add -mcmse.
>>         * config/arm/arm_cmse.h: New file.
>>
>> *** libgcc/ChangeLog ***
>> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>
>>         * config/arm/cmse.c: Likewise.
>>         * config/arm/t-arm (HAVE_CMSE): New.
>>
>> *** gcc/testsuite/ChangeLog ***
>> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>
>>         * gcc.target/arm/cmse/cmse.exp: New.
>>         * gcc.target/arm/cmse/cmse-1.c: New.
>>         * gcc.target/arm/cmse/cmse-12.c: New.
>>         * lib/target-supports.exp
>>         (check_effective_target_arm_cmse_ok): New.
>>
> 
> Added more documentation as requested.
> 
> This patch adds the support of the '-mcmse' option to enable ARMv8-M's
> Security Extensions and supports the following intrinsics:
> cmse_TT
> cmse_TT_fptr
> cmse_TTT
> cmse_TTT_fptr
> cmse_TTA
> cmse_TTA_fptr
> cmse_TTAT
> cmse_TTAT_fptr
> cmse_check_address_range
> cmse_check_pointed_object
> cmse_is_nsfptr
> cmse_nsfptr_create
> 
> It also defines the mandatory cmse_address_info struct and the
> __ARM_FEATURE_CMSE macro.
> See Chapter 4, Sections 5.2, 5.3 and 5.6 of ARM®v8-M Security
> Extensions: Requirements on Development Tools
> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
> 
> *** gcc/ChangeLog ***
> 2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
> 
>         * config.gcc (extra_headers): Added arm_cmse.h.
>         * config/arm/arm-arches.def (ARM_ARCH):
>         (armv8-m): Add FL2_CMSE.
>         (armv8-m.main): Likewise.
>         (armv8-m.main+dsp): Likewise.
>         * config/arm/arm-c.c
>         (arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
>         * config/arm/arm-protos.h
>         (arm_is_constant_pool_ref): Define FL2_CMSE.
>         * config/arm.c (arm_arch_cmse): New.
>         (arm_option_override): New error for unsupported cmse target.
>         * config/arm/arm.h (arm_arch_cmse): New.
>         * config/arm/arm.opt (mcmse): New.
>         * doc/invoke.texi (ARM Options): Add -mcmse.
>         * doc/extend.texi (ARM ARMv8-M Security Extensions): Add section.
>         * config/arm/arm_cmse.h: New file.
> 
> *** libgcc/ChangeLog ***
> 2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
>         * config/arm/cmse.c: Likewise.
>         * config/arm/t-arm (HAVE_CMSE): New.
> 
> 
> *** gcc/testsuite/ChangeLog ***
> 2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
> 
>         * gcc.target/arm/cmse/cmse.exp: New.
>         * gcc.target/arm/cmse/cmse-1.c: New.
>         * gcc.target/arm/cmse/cmse-12.c: New.
>         * lib/target-supports.exp
>         (check_effective_target_arm_cmse_ok): New.
> 
Hi,

Rebased previous patch on top of trunk as requested. No changes to
ChangeLog.

Cheers,
Andre

Comments

Kyrill Tkachov Oct. 26, 2016, 9:12 a.m. UTC | #1
Hi Andre, thanks for resending them.

On 25/10/16 17:26, Andre Vieira (lists) wrote:
> On 24/08/16 12:00, Andre Vieira (lists) wrote:
>> On 25/07/16 14:19, Andre Vieira (lists) wrote:
>>> This patch adds the support of the '-mcmse' option to enable ARMv8-M's
>>> Security Extensions and supports the following intrinsics:
>>> cmse_TT
>>> cmse_TT_fptr
>>> cmse_TTT
>>> cmse_TTT_fptr
>>> cmse_TTA
>>> cmse_TTA_fptr
>>> cmse_TTAT
>>> cmse_TTAT_fptr
>>> cmse_check_address_range
>>> cmse_check_pointed_object
>>> cmse_is_nsfptr
>>> cmse_nsfptr_create
>>>
>>> It also defines the mandatory cmse_address_info struct and the
>>> __ARM_FEATURE_CMSE macro.
>>> See Chapter 4, Sections 5.2, 5.3 and 5.6 of ARM®v8-M Security
>>> Extensions: Requirements on Development Tools
>>> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
>>>
>>> *** gcc/ChangeLog ***
>>> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>>
>>>          * config.gcc (extra_headers): Added arm_cmse.h.
>>>          * config/arm/arm-arches.def (ARM_ARCH):
>>>          (armv8-m): Add FL2_CMSE.
>>>          (armv8-m.main): Likewise.
>>>          (armv8-m.main+dsp): Likewise.
>>>          * config/arm/arm-c.c
>>>          (arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
>>>          * config/arm/arm-protos.h
>>>          (arm_is_constant_pool_ref): Define FL2_CMSE.
>>>          * config/arm.c (arm_arch_cmse): New.
>>>          (arm_option_override): New error for unsupported cmse target.
>>>          * config/arm/arm.h (arm_arch_cmse): New.
>>>          * config/arm/arm.opt (mcmse): New.
>>>          * doc/invoke.texi (ARM Options): Add -mcmse.
>>>          * config/arm/arm_cmse.h: New file.
>>>
>>> *** libgcc/ChangeLog ***
>>> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>>
>>>          * config/arm/cmse.c: Likewise.
>>>          * config/arm/t-arm (HAVE_CMSE): New.
>>>
>>> *** gcc/testsuite/ChangeLog ***
>>> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>>
>>>          * gcc.target/arm/cmse/cmse.exp: New.
>>>          * gcc.target/arm/cmse/cmse-1.c: New.
>>>          * gcc.target/arm/cmse/cmse-12.c: New.
>>>          * lib/target-supports.exp
>>>          (check_effective_target_arm_cmse_ok): New.
>>>
>> Added more documentation as requested.
>>
>> This patch adds the support of the '-mcmse' option to enable ARMv8-M's
>> Security Extensions and supports the following intrinsics:
>> cmse_TT
>> cmse_TT_fptr
>> cmse_TTT
>> cmse_TTT_fptr
>> cmse_TTA
>> cmse_TTA_fptr
>> cmse_TTAT
>> cmse_TTAT_fptr
>> cmse_check_address_range
>> cmse_check_pointed_object
>> cmse_is_nsfptr
>> cmse_nsfptr_create
>>
>> It also defines the mandatory cmse_address_info struct and the
>> __ARM_FEATURE_CMSE macro.
>> See Chapter 4, Sections 5.2, 5.3 and 5.6 of ARM®v8-M Security
>> Extensions: Requirements on Development Tools
>> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
>>
>> *** gcc/ChangeLog ***
>> 2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>
>>          * config.gcc (extra_headers): Added arm_cmse.h.
>>          * config/arm/arm-arches.def (ARM_ARCH):
>>          (armv8-m): Add FL2_CMSE.
>>          (armv8-m.main): Likewise.
>>          (armv8-m.main+dsp): Likewise.
>>          * config/arm/arm-c.c
>>          (arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
>>          * config/arm/arm-protos.h
>>          (arm_is_constant_pool_ref): Define FL2_CMSE.
>>          * config/arm.c (arm_arch_cmse): New.
>>          (arm_option_override): New error for unsupported cmse target.
>>          * config/arm/arm.h (arm_arch_cmse): New.
>>          * config/arm/arm.opt (mcmse): New.
>>          * doc/invoke.texi (ARM Options): Add -mcmse.
>>          * doc/extend.texi (ARM ARMv8-M Security Extensions): Add section.
>>          * config/arm/arm_cmse.h: New file.
>>
>> *** libgcc/ChangeLog ***
>> 2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>          * config/arm/cmse.c: Likewise.
>>          * config/arm/t-arm (HAVE_CMSE): New.
>>
>>
>> *** gcc/testsuite/ChangeLog ***
>> 2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>>
>>          * gcc.target/arm/cmse/cmse.exp: New.
>>          * gcc.target/arm/cmse/cmse-1.c: New.
>>          * gcc.target/arm/cmse/cmse-12.c: New.
>>          * lib/target-supports.exp
>>          (check_effective_target_arm_cmse_ok): New.
>>
> Hi,
>
> Rebased previous patch on top of trunk as requested. No changes to
> ChangeLog.
>
> Cheers,
> Andre

diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4232937c6ae04754a6bbc513b143672a4be5530
--- /dev/null
+++ b/gcc/config/arm/arm_cmse.h

<snip>

+
+#if __ARM_FEATURE_CMSE & 2
+
+#define cmse_TTA_fptr(p) (__cmse_TTA_fptr ((__cmse_fptr)(p)))
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+__cmse_TTA_fptr (__cmse_fptr __p)
+__CMSE_TT_ASM (a)
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+cmse_TTA (void *__p)
+__CMSE_TT_ASM (a)
+
+#define cmse_TTAT_fptr(p) (__cmse_TTAT_fptr ((__cmse_fptr)(p)))
+
+__extension__ static __inline cmse_address_info_t
+__attribute__ ((__always_inline__))
+__cmse_TTAT_fptr (__cmse_fptr __p)
+__CMSE_TT_ASM (at)
+
+__extension__ static __inline cmse_address_info_t
+__attribute__ ((__always_inline__))
+cmse_TTAT (void *__p)
+__CMSE_TT_ASM (at)
+
+#define CMSE_AU_NONSECURE	2
+#define CMSE_MPU_NONSECURE	16
+#define CMSE_NONSECURE		18
+
+#endif /* __ARM_FEATURE_CMSE & 2 */
+
+#define CMSE_MPU_UNPRIV		4
+#define CMSE_MPU_READWRITE	1
+#define CMSE_MPU_READ		8
+
+__extension__ void *
+cmse_check_address_range (void *, size_t, int);
+
+#define cmse_check_pointed_object(p, f) \
+  ((typeof ((p))) cmse_check_address_range ((p), sizeof (*(p)), (f)))
+
+#define cmse_nsfptr_create(p) ((typeof ((p))) ((intptr_t) (p) & ~1))
+
+#define cmse_is_nsfptr(p) (!((intptr_t) (p) & 1))
+
+#endif /* __ARM_FEATURE_CMSE & 1 */

 From my reading of the spec (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/ECM0359818_armv8m_security_extensions_reqs_on_dev_tools_1_0.pdf)
cmse_nsfptr_create and cmse_is_nsfptr should be defined if bit 1 of __ARM_FEATURE_CMSE is set.
But in your patch they fall under the "#if __ARM_FEATURE_CMSE & 1" check which checks bit 0.
They should be in the "__ARM_FEATURE_CMSE & 2" block. Please double check the other defines against the SPEC to make sure they
match the feature bit in __ARM_FEATURE_CMSE.

The patch is ok with that resolved if bootstrap and test on a normal arm-none-linux-gnueabihf configuration
shows no problems.
Thanks,
Kyrill
Kyrill Tkachov Oct. 26, 2016, 1 p.m. UTC | #2
On 26/10/16 10:12, Kyrill Tkachov wrote:
> Hi Andre, thanks for resending them.
>
> On 25/10/16 17:26, Andre Vieira (lists) wrote:
>> On 24/08/16 12:00, Andre Vieira (lists) wrote:
>>> On 25/07/16 14:19, Andre Vieira (lists) wrote:
>>>> This patch adds the support of the '-mcmse' option to enable ARMv8-M's
>>>> Security Extensions and supports the following intrinsics:
>>>> cmse_TT
>>>> cmse_TT_fptr
>>>> cmse_TTT
>>>> cmse_TTT_fptr
>>>> cmse_TTA
>>>> cmse_TTA_fptr
>>>> cmse_TTAT
>>>> cmse_TTAT_fptr
>>>> cmse_check_address_range
>>>> cmse_check_pointed_object
>>>> cmse_is_nsfptr
>>>> cmse_nsfptr_create
>>>>
>>>> It also defines the mandatory cmse_address_info struct and the
>>>> __ARM_FEATURE_CMSE macro.
>>>> See Chapter 4, Sections 5.2, 5.3 and 5.6 of ARM®v8-M Security
>>>> Extensions: Requirements on Development Tools
>>>> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
>>>>
>>>> *** gcc/ChangeLog ***
>>>> 2016-07-25  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>>              Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>>
>>>>          * config.gcc (extra_headers): Added arm_cmse.h.
>>>>          * config/arm/arm-arches.def (ARM_ARCH):
>>>>          (armv8-m): Add FL2_CMSE.
>>>>          (armv8-m.main): Likewise.
>>>>          (armv8-m.main+dsp): Likewise.
>>>>          * config/arm/arm-c.c
>>>>          (arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
>>>>          * config/arm/arm-protos.h
>>>>          (arm_is_constant_pool_ref): Define FL2_CMSE.
>>>>          * config/arm.c (arm_arch_cmse): New.
>>>>          (arm_option_override): New error for unsupported cmse target.
>>>>          * config/arm/arm.h (arm_arch_cmse): New.
>>>>          * config/arm/arm.opt (mcmse): New.
>>>>          * doc/invoke.texi (ARM Options): Add -mcmse.
>>>>          * config/arm/arm_cmse.h: New file.
>>>>
>>>> *** libgcc/ChangeLog ***
>>>> 2016-07-25  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>>              Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>>
>>>>          * config/arm/cmse.c: Likewise.
>>>>          * config/arm/t-arm (HAVE_CMSE): New.
>>>>
>>>> *** gcc/testsuite/ChangeLog ***
>>>> 2016-07-25  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>>              Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>>
>>>>          * gcc.target/arm/cmse/cmse.exp: New.
>>>>          * gcc.target/arm/cmse/cmse-1.c: New.
>>>>          * gcc.target/arm/cmse/cmse-12.c: New.
>>>>          * lib/target-supports.exp
>>>>          (check_effective_target_arm_cmse_ok): New.


Just remembered, new effective target checks should be documented in sourcebuild.texi
Kyrill

>>>>
>>> Added more documentation as requested.
>>>
>>> This patch adds the support of the '-mcmse' option to enable ARMv8-M's
>>> Security Extensions and supports the following intrinsics:
>>> cmse_TT
>>> cmse_TT_fptr
>>> cmse_TTT
>>> cmse_TTT_fptr
>>> cmse_TTA
>>> cmse_TTA_fptr
>>> cmse_TTAT
>>> cmse_TTAT_fptr
>>> cmse_check_address_range
>>> cmse_check_pointed_object
>>> cmse_is_nsfptr
>>> cmse_nsfptr_create
>>>
>>> It also defines the mandatory cmse_address_info struct and the
>>> __ARM_FEATURE_CMSE macro.
>>> See Chapter 4, Sections 5.2, 5.3 and 5.6 of ARM®v8-M Security
>>> Extensions: Requirements on Development Tools
>>> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
>>>
>>> *** gcc/ChangeLog ***
>>> 2016-07-xx  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>              Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>
>>>          * config.gcc (extra_headers): Added arm_cmse.h.
>>>          * config/arm/arm-arches.def (ARM_ARCH):
>>>          (armv8-m): Add FL2_CMSE.
>>>          (armv8-m.main): Likewise.
>>>          (armv8-m.main+dsp): Likewise.
>>>          * config/arm/arm-c.c
>>>          (arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
>>>          * config/arm/arm-protos.h
>>>          (arm_is_constant_pool_ref): Define FL2_CMSE.
>>>          * config/arm.c (arm_arch_cmse): New.
>>>          (arm_option_override): New error for unsupported cmse target.
>>>          * config/arm/arm.h (arm_arch_cmse): New.
>>>          * config/arm/arm.opt (mcmse): New.
>>>          * doc/invoke.texi (ARM Options): Add -mcmse.
>>>          * doc/extend.texi (ARM ARMv8-M Security Extensions): Add section.
>>>          * config/arm/arm_cmse.h: New file.
>>>
>>> *** libgcc/ChangeLog ***
>>> 2016-07-xx  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>              Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>          * config/arm/cmse.c: Likewise.
>>>          * config/arm/t-arm (HAVE_CMSE): New.
>>>
>>>
>>> *** gcc/testsuite/ChangeLog ***
>>> 2016-07-xx  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>              Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>
>>>          * gcc.target/arm/cmse/cmse.exp: New.
>>>          * gcc.target/arm/cmse/cmse-1.c: New.
>>>          * gcc.target/arm/cmse/cmse-12.c: New.
>>>          * lib/target-supports.exp
>>>          (check_effective_target_arm_cmse_ok): New.
>>>
>> Hi,
>>
>> Rebased previous patch on top of trunk as requested. No changes to
>> ChangeLog.
>>
>> Cheers,
>> Andre
>
> diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..b4232937c6ae04754a6bbc513b143672a4be5530
> --- /dev/null
> +++ b/gcc/config/arm/arm_cmse.h
>
> <snip>
>
> +
> +#if __ARM_FEATURE_CMSE & 2
> +
> +#define cmse_TTA_fptr(p) (__cmse_TTA_fptr ((__cmse_fptr)(p)))
> +
> +__extension__ static __inline __attribute__ ((__always_inline__))
> +cmse_address_info_t
> +__cmse_TTA_fptr (__cmse_fptr __p)
> +__CMSE_TT_ASM (a)
> +
> +__extension__ static __inline __attribute__ ((__always_inline__))
> +cmse_address_info_t
> +cmse_TTA (void *__p)
> +__CMSE_TT_ASM (a)
> +
> +#define cmse_TTAT_fptr(p) (__cmse_TTAT_fptr ((__cmse_fptr)(p)))
> +
> +__extension__ static __inline cmse_address_info_t
> +__attribute__ ((__always_inline__))
> +__cmse_TTAT_fptr (__cmse_fptr __p)
> +__CMSE_TT_ASM (at)
> +
> +__extension__ static __inline cmse_address_info_t
> +__attribute__ ((__always_inline__))
> +cmse_TTAT (void *__p)
> +__CMSE_TT_ASM (at)
> +
> +#define CMSE_AU_NONSECURE    2
> +#define CMSE_MPU_NONSECURE    16
> +#define CMSE_NONSECURE        18
> +
> +#endif /* __ARM_FEATURE_CMSE & 2 */
> +
> +#define CMSE_MPU_UNPRIV        4
> +#define CMSE_MPU_READWRITE    1
> +#define CMSE_MPU_READ        8
> +
> +__extension__ void *
> +cmse_check_address_range (void *, size_t, int);
> +
> +#define cmse_check_pointed_object(p, f) \
> +  ((typeof ((p))) cmse_check_address_range ((p), sizeof (*(p)), (f)))
> +
> +#define cmse_nsfptr_create(p) ((typeof ((p))) ((intptr_t) (p) & ~1))
> +
> +#define cmse_is_nsfptr(p) (!((intptr_t) (p) & 1))
> +
> +#endif /* __ARM_FEATURE_CMSE & 1 */
>
> From my reading of the spec (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/ECM0359818_armv8m_security_extensions_reqs_on_dev_tools_1_0.pdf)
> cmse_nsfptr_create and cmse_is_nsfptr should be defined if bit 1 of __ARM_FEATURE_CMSE is set.
> But in your patch they fall under the "#if __ARM_FEATURE_CMSE & 1" check which checks bit 0.
> They should be in the "__ARM_FEATURE_CMSE & 2" block. Please double check the other defines against the SPEC to make sure they
> match the feature bit in __ARM_FEATURE_CMSE.
>
> The patch is ok with that resolved if bootstrap and test on a normal arm-none-linux-gnueabihf configuration
> shows no problems.
> Thanks,
> Kyrill
>
diff mbox

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2143d632fd25892e3633abafe17eee9326b1efd8..63245ecec55c1712e8373b31bcf8c655b4ecfcea 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -322,7 +322,7 @@  arc*-*-*)
 arm*-*-*)
 	cpu_type=arm
 	extra_objs="arm-builtins.o aarch-common.o"
-	extra_headers="mmintrin.h arm_neon.h arm_acle.h arm_fp16.h"
+	extra_headers="mmintrin.h arm_neon.h arm_acle.h arm_fp16.h arm_cmse.h"
 	target_type_format_char='%'
 	c_target_objs="arm-c.o"
 	cxx_target_objs="arm-c.o"
diff --git a/gcc/config/arm/arm-arches.def b/gcc/config/arm/arm-arches.def
index 4b196a7d1188de5eca028e5c2597bbc20835201f..1bdcf5d9f92404d5d5abb2a53ff89ad3d3ff2794 100644
--- a/gcc/config/arm/arm-arches.def
+++ b/gcc/config/arm/arm-arches.def
@@ -70,10 +70,10 @@  ARM_ARCH ("armv8.2-a+fp16", cortexa53,  8A,
 	  ARM_FSET_MAKE (FL_CO_PROC | FL_CRC32 | FL_FOR_ARCH8A,
 			 FL2_FOR_ARCH8_2A | FL2_FP16INST))
 ARM_ARCH("armv8-m.base", cortexm0, 8M_BASE,
-	 ARM_FSET_MAKE_CPU1 (			      FL_FOR_ARCH8M_BASE))
+	 ARM_FSET_MAKE (			  FL_FOR_ARCH8M_BASE, FL2_CMSE))
 ARM_ARCH("armv8-m.main", cortexm7, 8M_MAIN,
-	 ARM_FSET_MAKE_CPU1(FL_CO_PROC |	      FL_FOR_ARCH8M_MAIN))
+	 ARM_FSET_MAKE (FL_CO_PROC |		  FL_FOR_ARCH8M_MAIN, FL2_CMSE))
 ARM_ARCH("armv8-m.main+dsp", cortexm7, 8M_MAIN,
-	 ARM_FSET_MAKE_CPU1(FL_CO_PROC | FL_ARCH7EM | FL_FOR_ARCH8M_MAIN))
+	 ARM_FSET_MAKE (FL_CO_PROC | FL_ARCH7EM | FL_FOR_ARCH8M_MAIN, FL2_CMSE))
 ARM_ARCH("iwmmxt",  iwmmxt,     5TE,	ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT))
 ARM_ARCH("iwmmxt2", iwmmxt2,    5TE,	ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2))
diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c
index df930f44801e9e5f481ee6eb990656dda4bf0cea..4031083893d8f9cbd44881e008b0cef40f3ad614 100644
--- a/gcc/config/arm/arm-c.c
+++ b/gcc/config/arm/arm-c.c
@@ -77,6 +77,14 @@  arm_cpu_builtins (struct cpp_reader* pfile)
 
   def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT);
 
+  if (arm_arch8 && !arm_arch_notm)
+    {
+      if (arm_arch_cmse && use_cmse)
+	builtin_define_with_int_value ("__ARM_FEATURE_CMSE", 3);
+      else
+	builtin_define ("__ARM_FEATURE_CMSE");
+    }
+
   if (TARGET_ARM_FEATURE_LDREX)
     builtin_define_with_int_value ("__ARM_FEATURE_LDREX",
 				   TARGET_ARM_FEATURE_LDREX);
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index fd8b6d106d13faebedf7a3539d30159c14f061c6..e7d9f824596a62f5c99000940f6190ab6aee9255 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -396,6 +396,7 @@  extern bool arm_is_constant_pool_ref (rtx);
 #define FL2_ARCH8_2   (1 << 1)	      /* Architecture 8.2.  */
 #define FL2_FP16INST  (1 << 2)	      /* FP16 Instructions for ARMv8.2 and
 					 later.  */
+#define FL2_CMSE      (1 << 3)	      /* ARMv8-M Security Extensions.  */
 
 /* Flags that only effect tuning, not available instructions.  */
 #define FL_TUNE		(FL_WBUF | FL_VFPV2 | FL_STRONG | FL_LDSCHED \
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 8a076ba3d8eb66e237790d23dd7c2ecb4b6fd264..a370dccdaa9fa4c980c1df11cb95a65cad16ac85 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -524,6 +524,9 @@  extern bool arm_disable_literal_pool;
 /* Nonzero if chip supports the ARMv8 CRC instructions.  */
 extern int arm_arch_crc;
 
+/* Nonzero if chip supports the ARMv8-M Security Extensions.  */
+extern int arm_arch_cmse;
+
 #ifndef TARGET_DEFAULT
 #define TARGET_DEFAULT  (MASK_APCS_FRAME)
 #endif
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 022c1d72a1272e56397dc7e2018483e77f18b90d..44677c1bccad42c5ad603ea0951d62abcbd6f05d 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -906,6 +906,9 @@  int arm_condexec_masklen = 0;
 /* Nonzero if chip supports the ARMv8 CRC instructions.  */
 int arm_arch_crc = 0;
 
+/* Nonzero if chip supports the ARMv8-M security extensions.  */
+int arm_arch_cmse = 0;
+
 /* Nonzero if the core has a very small, high-latency, multiply unit.  */
 int arm_m_profile_small_mul = 0;
 
@@ -3256,6 +3259,7 @@  arm_option_override (void)
   arm_arch_no_volatile_ce = ARM_FSET_HAS_CPU1 (insn_flags, FL_NO_VOLATILE_CE);
   arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
   arm_arch_crc = ARM_FSET_HAS_CPU1 (insn_flags, FL_CRC32);
+  arm_arch_cmse = ARM_FSET_HAS_CPU2 (insn_flags, FL2_CMSE);
   arm_m_profile_small_mul = ARM_FSET_HAS_CPU1 (insn_flags, FL_SMALLMUL);
   arm_fp16_inst = ARM_FSET_HAS_CPU2 (insn_flags, FL2_FP16INST);
   if (arm_fp16_inst)
@@ -3523,6 +3527,9 @@  arm_option_override (void)
   if (target_slow_flash_data || target_pure_code)
     arm_disable_literal_pool = true;
 
+  if (use_cmse && !arm_arch_cmse)
+    error ("target CPU does not support ARMv8-M Security Extensions");
+
   /* Disable scheduling fusion by default if it's not armv7 processor
      or doesn't prefer ldrd/strd.  */
   if (flag_schedule_fusion == 2
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 35f047e2de1659c2b426cf42dbbdae5be62cbfef..5fb645df71b93960e8cda38c4b5b1d9d37df125c 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -109,6 +109,10 @@  mfloat-abi=
 Target RejectNegative Joined Enum(float_abi_type) Var(arm_float_abi) Init(TARGET_DEFAULT_FLOAT_ABI)
 Specify if floating point hardware should be used.
 
+mcmse
+Target RejectNegative Var(use_cmse)
+Specify that the compiler should target secure code as per ARMv8-M Security Extensions.
+
 Enum
 Name(float_abi_type) Type(enum float_abi_type)
 Known floating-point ABIs (for use with the -mfloat-abi= option):
diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4232937c6ae04754a6bbc513b143672a4be5530
--- /dev/null
+++ b/gcc/config/arm/arm_cmse.h
@@ -0,0 +1,192 @@ 
+/* ARMv8-M Secure Extensions intrinsics include file.
+
+   Copyright (C) 2015-2016 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+#ifndef _GCC_ARM_CMSE_H
+#define _GCC_ARM_CMSE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __ARM_FEATURE_CMSE & 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __ARM_BIG_ENDIAN
+
+typedef union {
+  struct cmse_address_info {
+#if __ARM_FEATURE_CMSE & 2
+    unsigned idau_region:8;
+    unsigned idau_region_valid:1;
+    unsigned secure:1;
+    unsigned nonsecure_readwrite_ok:1;
+    unsigned nonsecure_read_ok:1;
+#else
+    unsigned :12;
+#endif
+    unsigned readwrite_ok:1;
+    unsigned read_ok:1;
+#if __ARM_FEATURE_CMSE & 2
+    unsigned sau_region_valid:1;
+#else
+    unsigned :1;
+#endif
+    unsigned mpu_region_valid:1;
+#if __ARM_FEATURE_CMSE & 2
+    unsigned sau_region:8;
+#else
+    unsigned :8;
+#endif
+    unsigned mpu_region:8;
+  } flags;
+  unsigned value;
+} cmse_address_info_t;
+
+#else
+
+typedef union {
+  struct cmse_address_info {
+    unsigned mpu_region:8;
+#if __ARM_FEATURE_CMSE & 2
+    unsigned sau_region:8;
+#else
+    unsigned :8;
+#endif
+    unsigned mpu_region_valid:1;
+#if __ARM_FEATURE_CMSE & 2
+    unsigned sau_region_valid:1;
+#else
+    unsigned :1;
+#endif
+    unsigned read_ok:1;
+    unsigned readwrite_ok:1;
+#if __ARM_FEATURE_CMSE & 2
+    unsigned nonsecure_read_ok:1;
+    unsigned nonsecure_readwrite_ok:1;
+    unsigned secure:1;
+    unsigned idau_region_valid:1;
+    unsigned idau_region:8;
+#else
+    unsigned :12;
+#endif
+  } flags;
+  unsigned value;
+} cmse_address_info_t;
+
+#endif /* __ARM_BIG_ENDIAN */
+
+#define cmse_TT_fptr(p) (__cmse_TT_fptr ((__cmse_fptr)(p)))
+
+typedef void (*__cmse_fptr)(void);
+
+#define __CMSE_TT_ASM(flags) \
+{ \
+  cmse_address_info_t __result; \
+   __asm__ ("tt" # flags " %0,%1" \
+	   : "=r"(__result) \
+	   : "r"(__p) \
+	   : "memory"); \
+  return __result; \
+}
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+__cmse_TT_fptr (__cmse_fptr __p)
+__CMSE_TT_ASM ()
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+cmse_TT (void *__p)
+__CMSE_TT_ASM ()
+
+#define cmse_TTT_fptr(p) (__cmse_TTT_fptr ((__cmse_fptr)(p)))
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+__cmse_TTT_fptr (__cmse_fptr __p)
+__CMSE_TT_ASM (t)
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+cmse_TTT (void *__p)
+__CMSE_TT_ASM (t)
+
+#if __ARM_FEATURE_CMSE & 2
+
+#define cmse_TTA_fptr(p) (__cmse_TTA_fptr ((__cmse_fptr)(p)))
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+__cmse_TTA_fptr (__cmse_fptr __p)
+__CMSE_TT_ASM (a)
+
+__extension__ static __inline __attribute__ ((__always_inline__))
+cmse_address_info_t
+cmse_TTA (void *__p)
+__CMSE_TT_ASM (a)
+
+#define cmse_TTAT_fptr(p) (__cmse_TTAT_fptr ((__cmse_fptr)(p)))
+
+__extension__ static __inline cmse_address_info_t
+__attribute__ ((__always_inline__))
+__cmse_TTAT_fptr (__cmse_fptr __p)
+__CMSE_TT_ASM (at)
+
+__extension__ static __inline cmse_address_info_t
+__attribute__ ((__always_inline__))
+cmse_TTAT (void *__p)
+__CMSE_TT_ASM (at)
+
+#define CMSE_AU_NONSECURE	2
+#define CMSE_MPU_NONSECURE	16
+#define CMSE_NONSECURE		18
+
+#endif /* __ARM_FEATURE_CMSE & 2 */
+
+#define CMSE_MPU_UNPRIV		4
+#define CMSE_MPU_READWRITE	1
+#define CMSE_MPU_READ		8
+
+__extension__ void *
+cmse_check_address_range (void *, size_t, int);
+
+#define cmse_check_pointed_object(p, f) \
+  ((typeof ((p))) cmse_check_address_range ((p), sizeof (*(p)), (f)))
+
+#define cmse_nsfptr_create(p) ((typeof ((p))) ((intptr_t) (p) & ~1))
+
+#define cmse_is_nsfptr(p) (!((intptr_t) (p) & 1))
+
+#endif /* __ARM_FEATURE_CMSE & 1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GCC_ARM_CMSE_H */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 0669f7999beb078822e471352036d8f13517812d..3f6fc27950fafa2e7649deb9dc5db44737cbb691 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -11753,6 +11753,7 @@  instructions, but allow the compiler to schedule those calls.
 * ARM iWMMXt Built-in Functions::
 * ARM C Language Extensions (ACLE)::
 * ARM Floating Point Status and Control Intrinsics::
+* ARM ARMv8-M Security Extensions::
 * AVR Built-in Functions::
 * Blackfin Built-in Functions::
 * FR-V Built-in Functions::
@@ -12598,6 +12599,31 @@  unsigned int __builtin_arm_get_fpscr ()
 void __builtin_arm_set_fpscr (unsigned int)
 @end smallexample
 
+@node ARM ARMv8-M Security Extensions
+@subsection ARM ARMv8-M Security Extensions
+
+GCC implements the ARMv8-M Security Extensions as described in the ARMv8-M
+Security Extensions: Requiremenets on Development Tools Engineering
+Specification, which can be found at
+@uref{http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/ECM0359818_armv8m_security_extensions_reqs_on_dev_tools_1_0.pdf}.
+
+As part of the Security Extensions GCC implements the intrinsics below.  FPTR
+is used here to mean any function pointer type.
+
+@smallexample
+cmse_address_info_t cmse_TT (void *)
+cmse_address_info_t cmse_TT_fptr (FPTR)
+cmse_address_info_t cmse_TTT (void *)
+cmse_address_info_t cmse_TTT_fptr (FPTR)
+cmse_address_info_t cmse_TTA (void *)
+cmse_address_info_t cmse_TTA_fptr (FPTR)
+cmse_address_info_t cmse_TTAT (void *)
+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)
+@end smallexample
+
 @node AVR Built-in Functions
 @subsection AVR Built-in Functions
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5ccd4244ef396696f1a7ca962a7a7fe9973fcf6e..13caf3c3bef2564d2c0152a95d520b6869ffda36 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -645,7 +645,8 @@  Objective-C and Objective-C++ Dialects}.
 -mslow-flash-data @gol
 -masm-syntax-unified @gol
 -mrestrict-it @gol
--mpure-code}
+-mpure-code @gol
+-mcmse}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -15170,6 +15171,11 @@  Additionally, when compiling for ELF object format give all text sections the
 ELF processor-specific section attribute @code{SHF_ARM_PURECODE}.  This option
 is only available when generating non-pic code for ARMv7-M targets.
 
+@item -mcmse
+@opindex mcmse
+Generate secure code as per the "ARMv8-M Security Extensions: Requirements on
+Development Tools Engineering Specification", which can be found on
+@url{http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/ECM0359818_armv8m_security_extensions_reqs_on_dev_tools_1_0.pdf}.
 @end table
 
 @node AVR Options
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..d5b9a2d9d59569de170da814ae660e9fb2b943e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
@@ -0,0 +1,67 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Os -mcmse -fdump-rtl-expand" }  */
+
+#include <arm_cmse.h>
+
+extern int a;
+extern int bar (void);
+
+int foo (char * p)
+{
+  cmse_address_info_t cait;
+
+  cait = cmse_TT (&a);
+  if (cait.flags.mpu_region)
+    a++;
+
+  cait = cmse_TT_fptr (&bar);
+  if (cait.flags.mpu_region)
+    a+= bar ();
+
+  cait = cmse_TTA (&a);
+  if (cait.flags.mpu_region)
+    a++;
+
+  cait = cmse_TTA_fptr (&bar);
+  if (cait.flags.mpu_region)
+    a+= bar ();
+
+  cait = cmse_TTT (&a);
+  if (cait.flags.mpu_region)
+    a++;
+
+  cait = cmse_TTT_fptr (&bar);
+  if (cait.flags.mpu_region)
+    a+= bar ();
+
+  cait = cmse_TTAT (&a);
+  if (cait.flags.mpu_region)
+    a++;
+
+  cait = cmse_TTAT_fptr (&bar);
+  if (cait.flags.mpu_region)
+    a+= bar ();
+
+  p = (char *) cmse_check_address_range ((void *) p, sizeof (char), 0);
+  p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
+					 CMSE_MPU_UNPRIV);
+  p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
+					 CMSE_MPU_READWRITE);
+  p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
+					 CMSE_MPU_UNPRIV | CMSE_MPU_READ);
+  p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
+					 CMSE_AU_NONSECURE
+					 | CMSE_MPU_NONSECURE);
+  p = (char *) cmse_check_address_range ((void *) p, sizeof (char),
+					 CMSE_NONSECURE | CMSE_MPU_UNPRIV);
+
+  p = (char *) cmse_check_pointed_object (p, CMSE_NONSECURE | CMSE_MPU_UNPRIV);
+
+  return a;
+}
+/* { dg-final { scan-assembler-times "\ttt " 2 } } */
+/* { dg-final { scan-assembler-times "ttt " 2 } } */
+/* { dg-final { scan-assembler-times "tta " 2 } } */
+/* { 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" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-12.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-12.c
new file mode 100644
index 0000000000000000000000000000000000000000..87a2f1363a4e4bd817503e79e504980210e722c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-12.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mcmse" }  */
+#include <arm_cmse.h>
+
+char *
+foo (char * p)
+{
+  if (!cmse_is_nsfptr (p))
+    return cmse_nsfptr_create (p);
+}
+
+/* Checks for saving and clearing prior to function call.  */
+/* { dg-final { scan-assembler-not "cmse_is_nsfptr" } } */
+/* { dg-final { scan-assembler-not "cmse_nsfptr_create" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
new file mode 100644
index 0000000000000000000000000000000000000000..f797dba1901720e04249d61078c1cbf2a3e436a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
@@ -0,0 +1,50 @@ 
+#   Copyright (C) 1997-2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for ARMv8-M Security Extensions using the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Exit immediately if the target does not support -mcmse.
+if ![check_effective_target_arm_cmse_ok] then {
+    return
+}
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+set saved-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default "assemble"
+
+set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
+set LTO_TORTURE_OPTIONS ""
+
+# These are for both baseline and mainline.
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
+	"" $DEFAULT_CFLAGS
+
+set LTO_TORTURE_OPTIONS ${saved-lto_torture_options}
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index b5a9faab5a47d01371c6402a5b07d34071dbc34b..eaeaf056c611889993b118d48a7aeb20e95be477 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3866,6 +3866,19 @@  proc check_effective_target_arm_thumb1_cbz_ok {} {
     }
 }
 
+# Return 1 if this is an ARM target where ARMv8-M Security Extensions is
+# available.
+
+proc check_effective_target_arm_cmse_ok {} {
+    return [check_no_compiler_messages arm_cmse object {
+	int
+	foo (void)
+	{
+	  asm ("bxns r0");
+	}
+    } "-mcmse"];
+}
+
 # Return 1 if this compilation turns on string_ops_prefer_neon on.
 
 proc check_effective_target_arm_tune_string_ops_prefer_neon { } {
diff --git a/libgcc/config/arm/cmse.c b/libgcc/config/arm/cmse.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe3a22967c8536f2a8c05b58627f964d3fb1d345
--- /dev/null
+++ b/libgcc/config/arm/cmse.c
@@ -0,0 +1,108 @@ 
+/* ARMv8-M Security Extensions routines.
+   Copyright (C) 2015-2016 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   This file is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This file is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+#if __ARM_FEATURE_CMSE & 1
+
+#include <arm_cmse.h>
+
+/* ARM intrinsic function to perform a permission check on a given
+   address range.  See ACLE changes for ARMv8-M.  */
+
+void *
+cmse_check_address_range (void *p, size_t size, int flags)
+{
+  cmse_address_info_t permb, perme;
+  char *pb = (char *) p, *pe;
+
+  /* Check if the range wraps around.  */
+  if (UINTPTR_MAX - (uintptr_t) p < size)
+    return NULL;
+
+  /* Check if an unknown flag is present.  */
+  int known = CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE | CMSE_MPU_READ;
+  int known_secure_level = CMSE_MPU_UNPRIV;
+#if __ARM_FEATURE_CMSE & 2
+  known |= CMSE_AU_NONSECURE | CMSE_MPU_NONSECURE;
+  known_secure_level |= CMSE_MPU_NONSECURE;
+#endif
+  if (flags & (~known))
+    return NULL;
+
+  /* Execute the right variant of the TT instructions.  */
+  pe = pb + size - 1;
+  const int singleCheck = (((uintptr_t) pb ^ (uintptr_t) pe) < 32);
+  switch (flags & known_secure_level)
+    {
+    case 0:
+      permb = cmse_TT (pb);
+      perme = singleCheck ? permb : cmse_TT (pe);
+      break;
+    case CMSE_MPU_UNPRIV:
+      permb = cmse_TTT (pb);
+      perme = singleCheck ? permb : cmse_TTT (pe);
+      break;
+#if __ARM_FEATURE_CMSE & 2
+    case CMSE_MPU_NONSECURE:
+      permb = cmse_TTA (pb);
+      perme = singleCheck ? permb : cmse_TTA (pe);
+      break;
+    case CMSE_MPU_UNPRIV | CMSE_MPU_NONSECURE:
+      permb = cmse_TTAT (pb);
+      perme = singleCheck ? permb : cmse_TTAT (pe);
+      break;
+#endif
+    default:
+      /* Invalid flag, eg.  CMSE_MPU_NONSECURE specified but
+	 __ARM_FEATURE_CMSE & 2 == 0.  */
+      return NULL;
+    }
+
+  /* Check that the range does not cross MPU, SAU, or IDAU boundaries.  */
+  if (permb.value != perme.value)
+    return NULL;
+
+  /* Check the permissions on the range.  */
+  switch (flags & (~known_secure_level))
+    {
+#if __ARM_FEATURE_CMSE & 2
+    case CMSE_MPU_READ | CMSE_MPU_READWRITE | CMSE_AU_NONSECURE:
+    case		 CMSE_MPU_READWRITE | CMSE_AU_NONSECURE:
+      return permb.flags.nonsecure_readwrite_ok	? p : NULL;
+    case CMSE_MPU_READ | CMSE_AU_NONSECURE:
+      return permb.flags.nonsecure_read_ok	? p : NULL;
+    case CMSE_AU_NONSECURE:
+      return permb.flags.secure			? NULL : p;
+#endif
+    case CMSE_MPU_READ | CMSE_MPU_READWRITE:
+    case		 CMSE_MPU_READWRITE:
+      return permb.flags.readwrite_ok		? p : NULL;
+    case CMSE_MPU_READ:
+      return permb.flags.read_ok		? p : NULL;
+    default:
+      return NULL;
+    }
+}
+
+
+#endif /* __ARM_FEATURE_CMSE & 1.  */
diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm
index 4e17e99b4a53bbafc0f1f8dddd02000f0e8f4f48..5618143bfd0f02b170db3f9e4c0a15cecb403cec 100644
--- a/libgcc/config/arm/t-arm
+++ b/libgcc/config/arm/t-arm
@@ -1,3 +1,15 @@ 
 LIB1ASMSRC = arm/lib1funcs.S
 LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \
 	_thumb1_case_uhi _thumb1_case_si
+
+HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
+ifneq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null 2>/dev/null),)
+CMSE_OPTS:=-mcmse
+endif
+
+ifdef HAVE_CMSE
+libgcc-objects += cmse.o cmse_nonsecure_call.o
+
+cmse.o: $(srcdir)/config/arm/cmse.c
+	$(gcc_compile) -c $(CMSE_OPTS) $<
+endif