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
"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<
"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 "
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)">;
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") {
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");
}
}
+ // 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.
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,
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.
// 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