diff options
| -rw-r--r-- | clang/lib/Driver/ToolChains/Arch/ARM.cpp | 72 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains/Arch/ARM.h | 3 | ||||
| -rw-r--r-- | clang/test/Driver/armv8.1m.main.c | 35 | ||||
| -rw-r--r-- | clang/test/Driver/armv8.1m.main.s | 24 |
4 files changed, 103 insertions, 31 deletions
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index e38ce4d583f..5ff1dd9c917 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -72,15 +72,13 @@ static void getARMFPUFeatures(const Driver &D, const Arg *A, // Decode ARM features from string like +[no]featureA+[no]featureB+... static bool DecodeARMFeatures(const Driver &D, StringRef text, + StringRef CPU, llvm::ARM::ArchKind ArchKind, std::vector<StringRef> &Features) { SmallVector<StringRef, 8> Split; text.split(Split, StringRef("+"), -1, false); for (StringRef Feature : Split) { - StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature); - if (!FeatureName.empty()) - Features.push_back(FeatureName); - else + if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features)) return false; } return true; @@ -100,14 +98,16 @@ static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, // getARMArch is used here instead of just checking the -march value in order // to handle -march=native correctly. static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, - llvm::StringRef ArchName, + llvm::StringRef ArchName, llvm::StringRef CPUName, std::vector<StringRef> &Features, const llvm::Triple &Triple) { std::pair<StringRef, StringRef> Split = ArchName.split("+"); std::string MArch = arm::getARMArch(ArchName, Triple); - if (llvm::ARM::parseArch(MArch) == llvm::ARM::ArchKind::INVALID || - (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features))) + llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch); + if (ArchKind == llvm::ARM::ArchKind::INVALID || + (Split.second.size() && !DecodeARMFeatures( + D, Split.second, CPUName, ArchKind, Features))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -119,8 +119,11 @@ static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args, std::pair<StringRef, StringRef> Split = CPUName.split("+"); std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); - if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() || - (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features))) + llvm::ARM::ArchKind ArchKind = + arm::getLLVMArchKindForARM(CPU, ArchName, Triple); + if (ArchKind == llvm::ARM::ArchKind::INVALID || + (Split.second.size() && !DecodeARMFeatures( + D, Split.second, CPU, ArchKind, Features))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -327,25 +330,12 @@ void arm::getARMTargetFeatures(const ToolChain &TC, if (ThreadPointer == arm::ReadTPMode::Cp15) Features.push_back("+read-tp-hard"); - // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); + const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); StringRef ArchName; - if (WaArch) { - if (ArchArg) - D.Diag(clang::diag::warn_drv_unused_argument) - << ArchArg->getAsString(Args); - ArchName = StringRef(WaArch->getValue()).substr(7); - checkARMArchName(D, WaArch, Args, ArchName, Features, Triple); - // FIXME: Set Arch. - D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args); - } else if (ArchArg) { - ArchName = ArchArg->getValue(); - checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple); - } + StringRef CPUName; // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=. - const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); - StringRef CPUName; if (WaCPU) { if (CPUArg) D.Diag(clang::diag::warn_drv_unused_argument) @@ -355,6 +345,20 @@ void arm::getARMTargetFeatures(const ToolChain &TC, } else if (CPUArg) CPUName = CPUArg->getValue(); + // Check -march. ClangAs gives preference to -Wa,-march=. + if (WaArch) { + if (ArchArg) + D.Diag(clang::diag::warn_drv_unused_argument) + << ArchArg->getAsString(Args); + ArchName = StringRef(WaArch->getValue()).substr(7); + checkARMArchName(D, WaArch, Args, ArchName, CPUName, Features, Triple); + // FIXME: Set Arch. + D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args); + } else if (ArchArg) { + ArchName = ArchArg->getValue(); + checkARMArchName(D, ArchArg, Args, ArchName, CPUName, Features, Triple); + } + // Add CPU features for generic CPUs if (CPUName == "native") { llvm::StringMap<bool> HostFeatures; @@ -625,11 +629,12 @@ std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch, return getARMCPUForMArch(Arch, Triple); } -/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular -/// CPU (or Arch, if CPU is generic). -// FIXME: This is redundant with -mcpu, why does LLVM use this. -StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, - const llvm::Triple &Triple) { +/// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a +/// particular CPU (or Arch, if CPU is generic). This is needed to +/// pass to functions like llvm::ARM::getDefaultFPU which need an +/// ArchKind as well as a CPU name. +llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch, + const llvm::Triple &Triple) { llvm::ARM::ArchKind ArchKind; if (CPU == "generic") { std::string ARMArch = tools::arm::getARMArch(Arch, Triple); @@ -645,6 +650,15 @@ StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, ? llvm::ARM::ArchKind::ARMV7K : llvm::ARM::parseCPUArch(CPU); } + return ArchKind; +} + +/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular +/// CPU (or Arch, if CPU is generic). +// FIXME: This is redundant with -mcpu, why does LLVM use this. +StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, + const llvm::Triple &Triple) { + llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple); if (ArchKind == llvm::ARM::ArchKind::INVALID) return ""; return llvm::ARM::getSubArch(ArchKind); diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.h b/clang/lib/Driver/ToolChains/Arch/ARM.h index 0b3ad4d413e..5640f837126 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -13,6 +13,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Option/Option.h" +#include "llvm/Support/TargetParser.h" #include <string> #include <vector> @@ -25,6 +26,8 @@ std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple); const std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple); StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple); +llvm::ARM::ArchKind getLLVMArchKindForARM(StringRef CPU, StringRef Arch, + const llvm::Triple &Triple); StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple); diff --git a/clang/test/Driver/armv8.1m.main.c b/clang/test/Driver/armv8.1m.main.c index 675d98c8fd1..9a745b1b809 100644 --- a/clang/test/Driver/armv8.1m.main.c +++ b/clang/test/Driver/armv8.1m.main.c @@ -2,13 +2,48 @@ // RUN: FileCheck --check-prefix=CHECK-DSP < %t %s // CHECK-DSP: "-target-feature" "+dsp" +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+fp -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-FP < %t %s +// CHECK-FP: "-target-feature" "+fp-armv8" +// CHECK-FP-NOT: "-target-feature" "+fp64" +// CHECK-FP-NOT: "-target-feature" "+d32" +// CHECK-FP: "-target-feature" "+fullfp16" + +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nofp -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NOFP < %t %s +// CHECK-NOFP: "-target-feature" "-vfp2" "-target-feature" "-vfp3" "-target-feature" "-fp16" "-target-feature" "-vfp4" "-target-feature" "-fp-armv8" "-target-feature" "-fp64" "-target-feature" "-d32" "-target-feature" "-neon" "-target-feature" "-crypto" + +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+fp.dp -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-FPDP < %t %s +// CHECK-FPDP: "-target-feature" "+fp-armv8" +// CHECK-FPDP: "-target-feature" "+fullfp16" +// CHECK-FPDP: "-target-feature" "+fp64" +// CHECK-FPDP-NOT: "-target-feature" "+d32" + +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nofp.dp -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NOFPDP < %t %s +// CHECK-NOFPDP: "-target-feature" "-fp64" + // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-MVE < %t %s // CHECK-MVE: "-target-feature" "+mve" +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nomve -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s +// CHECK-NOMVE: "-target-feature" "-mve" + // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-MVEFP < %t %s // CHECK-MVEFP: "-target-feature" "+mve.fp" // CHECK-MVEFP-NOT: "-target-feature" "+fp64" +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nomve.fp -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NOMVEFP < %t %s +// CHECK-NOMVEFP: "-target-feature" "-mve.fp" + +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+fp.dp -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-MVEFP_DP < %t %s +// CHECK-MVEFP_DP: "-target-feature" "+mve.fp" +// CHECK-MVEFP_DP: "-target-feature" "+fp64" + double foo (double a) { return a; } diff --git a/clang/test/Driver/armv8.1m.main.s b/clang/test/Driver/armv8.1m.main.s index 546ddca4ef1..8fc94cf772f 100644 --- a/clang/test/Driver/armv8.1m.main.s +++ b/clang/test/Driver/armv8.1m.main.s @@ -5,10 +5,24 @@ # RUN: FileCheck --check-prefix=ERROR-V81M < %t %s # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+dsp -o /dev/null %s 2>%t # RUN: FileCheck --check-prefix=ERROR-V81M_DSP < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_FP < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_FP < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp.dp -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp.dp -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve -o /dev/null %s 2>%t # RUN: FileCheck --check-prefix=ERROR-V81M_MVE < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_MVE < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve+fp -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_MVE_FP < %t %s # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve.fp -o /dev/null %s 2>%t # RUN: FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s +# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve.fp -o /dev/null %s 2>%t +# RUN: FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s .syntax unified .thumb @@ -39,15 +53,21 @@ vcmp.f64 d0,d1 # ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V81M: :[[@LINE-2]]:1: error # ERROR-V81M_DSP: :[[@LINE-3]]:1: error -# ERROR-V81M_MVE: :[[@LINE-4]]:1: error -# ERROR-V81M_MVEFP: :[[@LINE-5]]:1: error +# ERROR-V81M_FP: :[[@LINE-4]]:1: error +# ERROR-V81M_MVE: :[[@LINE-5]]:1: error +# ERROR-V81M_MVE_FP: :[[@LINE-6]]:1: error +# ERROR-V81M_MVEFP: :[[@LINE-7]]:1: error asrl r0, r1, r2 # ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V81M: :[[@LINE-2]]:1: error # ERROR-V81M_DSP: :[[@LINE-3]]:1: error +# ERROR-V81M_FP: :[[@LINE-4]]:1: error +# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error vcadd.i8 q0, q1, q2, #90 # ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V81M: :[[@LINE-2]]:1: error # ERROR-V81M_DSP: :[[@LINE-3]]:1: error +# ERROR-V81M_FP: :[[@LINE-4]]:1: error +# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error |

