[ARM][CMSE] Add commandline option and feature macro
authorJaved Absar <javed.absar@arm.com>
Tue, 21 May 2019 14:21:26 +0000 (14:21 +0000)
committerJaved Absar <javed.absar@arm.com>
Tue, 21 May 2019 14:21:26 +0000 (14:21 +0000)
Defines macro ARM_FEATURE_CMSE to 1 for v8-M targets and introduces
-mcmse option which for v8-M targets sets ARM_FEATURE_CMSE to 3.
A diagnostic is produced when the option is given on architectures
without support for Security Extensions.
Reviewed By: dmgreen, snidertm
Differential Revision: https://reviews.llvm.org/D59879

llvm-svn: 361261

clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/DiagnosticCommonKinds.td
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/Basic/Targets/ARM.cpp
clang/lib/Driver/ToolChains/Arch/ARM.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/Preprocessor/arm-target-features.c

index 67011ebdf80175a8a020e0ba0b6eef1a22774900..130899a2613a96786ae04cb820bbb20ba9291850 100644 (file)
@@ -299,6 +299,9 @@ def ObjC : LangOpt<"ObjC">;
 def BlocksSupported : LangOpt<"Blocks">;
 def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
 
+// Language option for CMSE extensions
+def Cmse : LangOpt<"Cmse">;
+
 // Defines targets for target-specific attributes. Empty lists are unchecked.
 class TargetSpec {
   // Specifies Architectures for which the target applies, based off the
index 07279807511a603ff95bf9d9cf9bac5a42695425..06ef3263c6f83f18569731212f4d05dd25d923a3 100644 (file)
@@ -252,6 +252,8 @@ def err_target_unsupported_unaligned : Error<
   "the %0 sub-architecture does not support unaligned accesses">;
 def err_target_unsupported_execute_only : Error<
   "execute only is not supported for the %0 sub-architecture">;
+def err_target_unsupported_mcmse : Error<
+  "-mcmse is not supported for %0">;
 def err_opt_not_valid_with_opt : Error<
   "option '%0' cannot be specified with '%1'">;
 def err_opt_not_valid_without_opt : Error<
index 74186a1a6b754cf768d0fb604b38a5a84b6b1393..359075717f5d7b1c2177b0872d94a2c55fc3d953 100644 (file)
@@ -300,6 +300,8 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
                                            "field padding (0: none, 1:least "
                                            "aggressive, 2: more aggressive)")
 
+LANGOPT(Cmse, 1, 0, "ARM Security extensions support")
+
 LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
 LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0,
         "controls whether to always emit intrinsic calls to "
index a931ae61c8f8dc7fc21ea3d5d0e778dbf1bb5152..26a06a6556a95cd1ab82dc8f30d0a317b1dc52a3 100644 (file)
@@ -2143,6 +2143,9 @@ def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
   HelpText<"Disallow use of CRC instructions (ARM only)">;
 def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group<m_arm_Features_Group>,
   HelpText<"Disallow converting instructions with negative immediates to their negation or inversion.">;
+def mcmse : Flag<["-"], "mcmse">, Group<m_arm_Features_Group>,
+  Flags<[DriverOption,CC1Option]>,
+  HelpText<"Allow use of CMSE (Armv8-M Security Extensions)">;
 
 def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
   HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
index b74514ea2c8c59436a4220228733513884254cdd..55c0d371598dc2980ebbbc959e1f6cdbe5230fca 100644 (file)
@@ -434,6 +434,11 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       DSP = 1;
     } else if (Feature == "+fp-only-sp") {
       HW_FP_remove |= HW_FP_DP;
+    } else if (Feature == "+8msecext") {
+      if (CPUProfile != "M" || ArchVersion != 8) {
+        Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
+        return false;
+      }
     } else if (Feature == "+strict-align") {
       Unaligned = 0;
     } else if (Feature == "+fp16") {
@@ -713,6 +718,10 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
 
   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
 
+  // CMSE
+  if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
+    Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
+
   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
index 9e0c48357167f69194969f94450dedb3647877c5..77fad7ed68f9125949e9c415d54e572816ab0262 100644 (file)
@@ -469,6 +469,10 @@ fp16_fml_fallthrough:
     }
   }
 
+  // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later.
+  if (Args.getLastArg(options::OPT_mcmse))
+    Features.push_back("+8msecext");
+
   // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
   // neither options are specified, see if we are compiling for kernel/kext and
   // decide whether to pass "+long-calls" based on the OS and its version.
index 5f8daa2b4a7a51c070e44673aaf84f9ebbce4725..556fe873f8f51630235979f8f6d6a7e6a68b8ca9 100644 (file)
@@ -1423,6 +1423,9 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
   if (!Args.hasFlag(options::OPT_mimplicit_float,
                     options::OPT_mno_implicit_float, true))
     CmdArgs.push_back("-no-implicit-float");
+
+  if (Args.getLastArg(options::OPT_mcmse))
+    CmdArgs.push_back("-mcmse");
 }
 
 void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
index 8a2dbcddfa9931312533ea31598c5b347a41b0d3..7cdc050e4673d0685f2f119ca2ed68c594fbb8ef 100644 (file)
@@ -2729,6 +2729,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
                             | Opts.NativeHalfArgsAndReturns;
   Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
+  Opts.Cmse = Args.hasArg(OPT_mcmse); // Armv8-M Security Extensions
 
   // __declspec is enabled by default for the PS4 by the driver, and also
   // enabled for Microsoft Extensions or Borland Extensions, here.
index 891093650e75a5e7bc822bf8c9c69f8ba2f0e6ed..57b0aa9c69e5c4a294203179a74a903f647c5dfc 100644 (file)
 // V8M_BASELINE: #define __ARM_ARCH_ISA_THUMB 1
 // V8M_BASELINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_BASELINE-NOT: __ARM_FEATURE_CRC32
+// V8M_BASELINE: #define __ARM_FEATURE_CMSE 1
 // V8M_BASELINE-NOT: __ARM_FEATURE_DSP
 // V8M_BASELINE-NOT: __ARM_FP 0x{{.*}}
 // V8M_BASELINE-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
 // V8M_MAINLINE: #define __ARM_ARCH_ISA_THUMB 2
 // V8M_MAINLINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_MAINLINE-NOT: __ARM_FEATURE_CRC32
+// V8M_MAINLINE: #define __ARM_FEATURE_CMSE 1
 // V8M_MAINLINE-NOT: __ARM_FEATURE_DSP
 // V8M_MAINLINE-NOT: #define __ARM_FP 0x
 // V8M_MAINLINE: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FP 0xe
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FPV5__ 1
 
+// Check that -mcmse (security extension) option works correctly for v8-M targets
+// RUN: %clang -target armv8m.base-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target armv8m.main-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm-none-linux-gnu -mcpu=cortex-m33 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm -mcpu=cortex-m23 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// V8M_CMSE-NOT: __ARM_FEATURE_CMSE 1
+// V8M_CMSE: #define __ARM_FEATURE_CMSE 3
+
+// Check that CMSE is not defined on architectures w/o support for security extension
+// RUN: %clang -target arm-arm-none-gnueabi -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// RUN: %clang -target armv8a-none-linux-gnu -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// NOTV8M_CMSE-NOT: __ARM_FEATURE_CMSE
+
+// Check that -mcmse option gives error on non v8-M targets
+// RUN: not %clang -target arm-arm-none-eabi -mthumb -mcmse -mcpu=cortex-m7 -x c -E -dM %s -o - 2>&1 | FileCheck -match-full-lines --check-prefix=NOTV8MCMSE_OPT %s
+// NOTV8MCMSE_OPT: error: -mcmse is not supported for cortex-m7
+
 // Test whether predefines are as expected when targeting v8m cores
 // RUN: %clang -target arm -mcpu=cortex-m23 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M23 %s
 // M23: #define __ARM_ARCH 8