From: Javed Absar Date: Tue, 21 May 2019 14:21:26 +0000 (+0000) Subject: [ARM][CMSE] Add commandline option and feature macro X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=470239452088f568ae6edfb619f95756a7114fd7;p=clang [ARM][CMSE] Add commandline option and feature macro 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361261 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 67011ebdf8..130899a261 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -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 diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 0727980751..06ef3263c6 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -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< diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index 74186a1a6b..359075717f 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -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 " diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index a931ae61c8..26a06a6556 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2143,6 +2143,9 @@ def mnocrc : Flag<["-"], "mnocrc">, Group, HelpText<"Disallow use of CRC instructions (ARM only)">; def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group, HelpText<"Disallow converting instructions with negative immediates to their negation or inversion.">; +def mcmse : Flag<["-"], "mcmse">, Group, + Flags<[DriverOption,CC1Option]>, + HelpText<"Allow use of CMSE (Armv8-M Security Extensions)">; def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group, HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">; diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp index b74514ea2c..55c0d37159 100644 --- a/lib/Basic/Targets/ARM.cpp +++ b/lib/Basic/Targets/ARM.cpp @@ -434,6 +434,11 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector &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"); diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp index 9e0c483571..77fad7ed68 100644 --- a/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/lib/Driver/ToolChains/Arch/ARM.cpp @@ -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. diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 5f8daa2b4a..556fe873f8 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -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, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8a2dbcddfa..7cdc050e46 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -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. diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c index 891093650e..57b0aa9c69 100644 --- a/test/Preprocessor/arm-target-features.c +++ b/test/Preprocessor/arm-target-features.c @@ -198,6 +198,7 @@ // 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 @@ -210,6 +211,7 @@ // 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 @@ -675,6 +677,24 @@ // 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