Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -4083,7 +4083,9 @@ } else if (CPU == "cortex-r5" || CPU == "cortex-r7" || // Enable the hwdiv extension for all v8a AArch32 cores by // default. - ArchName == "armv8a" || ArchName == "armv8" || + ArchName == "armv8a.1a" || ArchName == "thumbv8a.1a" || //v8.1a + ArchName == "armebv8.1a" || ArchName == "thumbebv8.1a" || + ArchName == "armv8a" || ArchName == "armv8" || //v8a ArchName == "armebv8a" || ArchName == "armebv8" || ArchName == "thumbv8a" || ArchName == "thumbv8" || ArchName == "thumbebv8a" || ArchName == "thumbebv8") { @@ -4168,7 +4170,17 @@ .Default(false); } // FIXME: Should we actually have some table instead of these switches? - static const char *getCPUDefineSuffix(StringRef Name) { + const char *getCPUDefineSuffix(StringRef Name) const { + if(Name == "generic") { + auto subarch = getTriple().getSubArch(); + switch (subarch) { + case llvm::Triple::SubArchType::ARMSubArch_v8_1a: + return "8_1A"; + default: + break; + } + } + return llvm::StringSwitch(Name) .Cases("arm8", "arm810", "4") .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", @@ -4198,7 +4210,17 @@ .Cases("cortex-a53", "cortex-a57", "cortex-a72", "8A") .Default(nullptr); } - static const char *getCPUProfile(StringRef Name) { + const char *getCPUProfile(StringRef Name) const { + if(Name == "generic") { + auto subarch = getTriple().getSubArch(); + switch (subarch) { + case llvm::Triple::SubArchType::ARMSubArch_v8_1a: + return "A"; + default: + break; + } + } + return llvm::StringSwitch(Name) .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A") .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", @@ -4234,6 +4256,7 @@ // We check both CPUArchVer and ArchName because when only triple is // specified, the default CPU is arm1136j-s. return ArchName.endswith("v6t2") || ArchName.endswith("v7") || + ArchName.endswith("v8.1a") || ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7; } void getTargetDefines(const LangOptions &Opts, Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -303,9 +303,12 @@ // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. - StringRef Suffix = Triple.isOSBinFormatMachO() - ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple)) - : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple)); + StringRef CPU = Triple.isOSBinFormatMachO() + ? tools::arm::getARMCPUForMArch(Args, Triple) + : tools::arm::getARMTargetCPU(Args, Triple); + StringRef Suffix = + tools::arm::getLLVMArchSuffixForARM(CPU, + tools::arm::getARMArch(Args, Triple)); bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") || Suffix.startswith("v7em") || (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO()); Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -226,9 +226,11 @@ namespace arm { StringRef getARMTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); + const StringRef getARMArch(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple); const char* getARMCPUForMArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); - const char* getLLVMArchSuffixForARM(StringRef CPU); + const char* getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch); void appendEBLinkFlags(const llvm::opt::ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple); } Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -645,7 +645,8 @@ // // FIXME: Factor out an ARM class so we can cache the arch somewhere. std::string ArchName = - arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple)); + arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple), + arm::getARMArch(Args, Triple)); if (StringRef(ArchName).startswith("v6") || StringRef(ArchName).startswith("v7")) FloatABI = "softfp"; @@ -688,7 +689,8 @@ break; case llvm::Triple::Android: { std::string ArchName = - arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple)); + arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple), + arm::getARMArch(Args, Triple)); if (StringRef(ArchName).startswith("v7")) FloatABI = "softfp"; else @@ -758,6 +760,10 @@ else Features.push_back("-crc"); } + + if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_1a) { + Features.insert(Features.begin(), "+v8.1a"); + } } void Clang::AddARMTargetArgs(const ArgList &Args, @@ -5548,9 +5554,8 @@ } // Hexagon tools end. -/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. -const char *arm::getARMCPUForMArch(const ArgList &Args, - const llvm::Triple &Triple) { +const StringRef arm::getARMArch(const ArgList &Args, + const llvm::Triple &Triple) { StringRef MArch; if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { // Otherwise, if we have -march= choose the base CPU for that arch. @@ -5559,6 +5564,12 @@ // Otherwise, use the Arch from the triple. MArch = Triple.getArchName(); } + return MArch; +} +/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. +const char *arm::getARMCPUForMArch(const ArgList &Args, + const llvm::Triple &Triple) { + StringRef MArch = getARMArch(Args, Triple); // Handle -march=native. if (MArch == "native") { @@ -5566,7 +5577,8 @@ if (CPU != "generic") { // Translate the native cpu into the architecture. The switch below will // then chose the minimum cpu for that arch. - MArch = std::string("arm") + arm::getLLVMArchSuffixForARM(CPU); + MArch = std::string("arm") + + arm::getLLVMArchSuffixForARM(CPU, arm::getARMArch(Args, Triple)); } } @@ -5591,11 +5603,18 @@ } /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular -/// CPU. +/// CPU (or Arch, if CPU is generic) // // FIXME: This is redundant with -mcpu, why does LLVM use this. // FIXME: tblgen this, or kill it! -const char *arm::getLLVMArchSuffixForARM(StringRef CPU) { +const char *arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch) { + if (CPU == "generic") { + if (Arch == "armv8.1a" || Arch == "armv8.1-a" || + Arch == "armebv8.1a" || Arch == "armebv8.1-a") { + return "v8.1a"; + } + } + return llvm::StringSwitch(CPU) .Case("strongarm", "v4") .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t") @@ -5622,11 +5641,13 @@ .Default(""); } -void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple) { +void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, + const llvm::Triple &Triple) { if (Args.hasArg(options::OPT_r)) return; - StringRef Suffix = getLLVMArchSuffixForARM(getARMCPUForMArch(Args, Triple)); + StringRef Suffix = getLLVMArchSuffixForARM(getARMCPUForMArch(Args, Triple), + getARMArch(Args, Triple)); const char *LinkFlag = llvm::StringSwitch(Suffix) .Cases("v4", "v4t", "v5", "v5e", nullptr) .Cases("v6", "v6k", "v6t2", nullptr) Index: test/Driver/arm-cortex-cpus.c =================================================================== --- test/Driver/arm-cortex-cpus.c +++ test/Driver/arm-cortex-cpus.c @@ -166,6 +166,39 @@ // RUN: %clang -target arm -march=armebv8a -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s // CHECK-BE-V8A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8-{{.*}}" "-target-cpu" "cortex-a53" +// RUN: %clang -target arm -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// RUN: %clang -target armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// RUN: %clang -target arm -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// RUN: %clang -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// RUN: %clang -target armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// RUN: %clang -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// RUN: %clang -target arm -mlittle-endian -march=armv8.1-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s +// CHECK-V81A: "-cc1"{{.*}} "-triple" "armv8.1a-{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.1a" + +// RUN: %clang -target armebv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s +// RUN: %clang -target armeb -march=armebv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s +// RUN: %clang -target armeb -march=armebv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s +// RUN: %clang -target armv8.1a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s +// RUN: %clang -target arm -march=armebv8.1a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s +// RUN: %clang -target arm -march=armebv8.1-a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s +// CHECK-BE-V81A: "-cc1"{{.*}} "-triple" "armebv8.1a-{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.1a" + +// RUN: %clang -target armv8.1a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-THUMB %s +// RUN: %clang -target arm -march=armv8.1a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-THUMB %s +// RUN: %clang -target arm -march=armv8.1-a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-THUMB %s +// RUN: %clang -target armv8.1a -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-THUMB %s +// RUN: %clang -target arm -march=armv8.1a -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-THUMB %s +// RUN: %clang -target arm -march=armv8.1-a -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A-THUMB %s +// CHECK-V81A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8.1a-{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.1a" + +// RUN: %clang -target armebv8.1a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A-THUMB %s +// RUN: %clang -target armeb -march=armebv8.1a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A-THUMB %s +// RUN: %clang -target armeb -march=armebv8.1-a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A-THUMB %s +// RUN: %clang -target armv8.1a -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A-THUMB %s +// RUN: %clang -target arm -march=armebv8.1a -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A-THUMB %s +// RUN: %clang -target arm -march=armebv8.1-a -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A-THUMB %s +// CHECK-BE-V81A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8.1a-{{.*}}" "-target-cpu" "generic" "-target-feature" "+v8.1a" + // ================== Check default CPU on bogus architecture // RUN: %clang -target arm -march=armbogusv6 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS %s // CHECK-BOGUS: "-cc1"{{.*}} "-triple" "armv4t-{{.*}} "-target-cpu" "arm7tdmi" Index: test/Preprocessor/arm-target-features.c =================================================================== --- test/Preprocessor/arm-target-features.c +++ test/Preprocessor/arm-target-features.c @@ -316,3 +316,8 @@ // KRAIT-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1 // KRAIT-THUMB:#define __ARM_FEATURE_DSP // KRAIT-THUMB:#define __ARM_VFPV4__ 1 + +// RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-V81A %s +// CHECK-V81A: __ARM_ARCH 8 +// CHECK-V81A: __ARM_ARCH_8_1A__ 1 +// CHECK-V81A: #define __ARM_ARCH_PROFILE 'A'