summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authoravieira <avieira@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-02 15:22:43 +0000
committeravieira <avieira@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-02 15:22:43 +0000
commit0120ae3031097eb092abd20bddac45f58762b1a9 (patch)
tree6811602f7f8aa090716356b734baf53b5076392b /gcc/config
parentb99ff0e778469b11eaab6563f68478c4486903ad (diff)
downloadgcc-0120ae3031097eb092abd20bddac45f58762b1a9.tar.gz
Add support for ARMv8-M's Secure Extensions flag and intrinsics
gcc/ChangeLog: 2016-12-02 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-flags.h: 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. * config/arm/arm_cmse.h: New file. * doc/invoke.texi (ARM Options): Add -mcmse. * doc/sourcebuild.texi (arm_cmse_ok): Add new effective target. * doc/extend.texi: Add ARMv8-M Security Extensions entry. gcc/testsuite/ChangeLog: 2016-12-02 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. libgcc/ChangeLog: 2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com> Thomas Preud'homme <thomas.preudhomme@arm.com> * config/arm/t-arm (HAVE_CMSE): New. * config/arm/cmse.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243187 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-arches.def6
-rw-r--r--gcc/config/arm/arm-c.c8
-rw-r--r--gcc/config/arm/arm-flags.h1
-rw-r--r--gcc/config/arm/arm.c7
-rw-r--r--gcc/config/arm/arm.h3
-rw-r--r--gcc/config/arm/arm.opt4
-rw-r--r--gcc/config/arm/arm_cmse.h192
7 files changed, 218 insertions, 3 deletions
diff --git a/gcc/config/arm/arm-arches.def b/gcc/config/arm/arm-arches.def
index cd79bc50585..71cabcc75e2 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", cortexm23, 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", cortexm33, 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 74417a6446d..b5921342f2e 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-flags.h b/gcc/config/arm/arm-flags.h
index 7ce059bcf87..fb498380938 100644
--- a/gcc/config/arm/arm-flags.h
+++ b/gcc/config/arm/arm-flags.h
@@ -70,6 +70,7 @@
#define FL2_ARCH8_2 (1U << 1) /* Architecture 8.2. */
#define FL2_FP16INST (1U << 2) /* FP16 Instructions for ARMv8.2 and
later. */
+#define FL2_CMSE (1U << 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.c b/gcc/config/arm/arm.c
index 74cb64ce789..0d7d38a73f1 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -909,6 +909,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;
@@ -3227,6 +3230,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 == TARGET_CPU_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)
@@ -3494,6 +3498,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.h b/gcc/config/arm/arm.h
index 464710b2a98..3d627436c57 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -523,6 +523,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.opt b/gcc/config/arm/arm.opt
index 8856976c6de..a37faccbb02 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -105,6 +105,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 00000000000..894343bb835
--- /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
+
+#define cmse_nsfptr_create(p) ((typeof ((p))) ((intptr_t) (p) & ~1))
+
+#define cmse_is_nsfptr(p) (!((intptr_t) (p) & 1))
+
+#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)))
+
+#endif /* __ARM_FEATURE_CMSE & 1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GCC_ARM_CMSE_H */