From 0600e1ebe940258c6edee6c849e371be2475f909 Mon Sep 17 00:00:00 2001 From: Renato Golin Date: Fri, 8 May 2015 21:04:50 +0000 Subject: [PATCH] Using ARMTargetParser in Clang This is a starting point for using the TargetParser in Clang, in a simple enough part of the code that can be used without disrupting the crazy platform support that we need to be compatible with other toolchains. Also adding a few FIXME on obvious places that need replacing, but those cases will indeed break a few of the platform assumptions, as arch/cpu names change multiple times in the driver. Finally, I'm changing the "neon-vfpv3" behaviour to match standard NEON, since -mfpu=neon implies vfpv3 by default in both Clang and LLVM. That option string is still supported as an alias to "neon". llvm-svn: 236901 --- clang/lib/Driver/ToolChains.cpp | 2 + clang/lib/Driver/Tools.cpp | 128 ++++++++++++++++---------------- clang/test/Driver/arm-mfpu.c | 13 ++-- 3 files changed, 74 insertions(+), 69 deletions(-) diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 20a308dedf39..ab129a139f57 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -108,6 +108,7 @@ bool Darwin::hasBlocksRuntime() const { } } +// FIXME: Use ARMTargetParser. static const char *GetArmArchForMArch(StringRef Value) { return llvm::StringSwitch(Value) .Case("armv6k", "armv6") @@ -125,6 +126,7 @@ static const char *GetArmArchForMArch(StringRef Value) { .Default(nullptr); } +// FIXME: Use ARMTargetParser. static const char *GetArmArchForMCpu(StringRef Value) { return llvm::StringSwitch(Value) .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5") diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 88e422171021..186f08e21165 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -32,6 +32,7 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" +#include "llvm/Support/TargetParser.h" #include "llvm/Support/Compression.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -543,75 +544,77 @@ static void getARMFPUFeatures(const Driver &D, const Arg *A, std::vector &Features) { StringRef FPU = A->getValue(); - // Set the target features based on the FPU. - if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") { - // Disable any default FPU support. - Features.push_back("-vfp2"); - Features.push_back("-vfp3"); - Features.push_back("-neon"); - } else if (FPU == "vfp") { - Features.push_back("+vfp2"); - Features.push_back("-neon"); - } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") { - Features.push_back("+vfp3"); - Features.push_back("+d16"); - Features.push_back("-neon"); - } else if (FPU == "vfp3" || FPU == "vfpv3") { - Features.push_back("+vfp3"); - Features.push_back("-neon"); - } else if (FPU == "vfp4-d16" || FPU == "vfpv4-d16") { - Features.push_back("+vfp4"); - Features.push_back("+d16"); - Features.push_back("-neon"); - } else if (FPU == "vfp4" || FPU == "vfpv4") { - Features.push_back("+vfp4"); - Features.push_back("-neon"); - } else if (FPU == "fp4-sp-d16" || FPU == "fpv4-sp-d16") { - Features.push_back("+vfp4"); - Features.push_back("+d16"); - Features.push_back("+fp-only-sp"); - Features.push_back("-neon"); - } else if (FPU == "fp5-sp-d16" || FPU == "fpv5-sp-d16") { - Features.push_back("+fp-armv8"); - Features.push_back("+fp-only-sp"); - Features.push_back("+d16"); - Features.push_back("-neon"); - Features.push_back("-crypto"); - } else if (FPU == "fp5-dp-d16" || FPU == "fpv5-dp-d16" || - FPU == "fp5-d16" || FPU == "fpv5-d16") { - Features.push_back("+fp-armv8"); - Features.push_back("+d16"); - Features.push_back("-neon"); - Features.push_back("-crypto"); - } else if (FPU == "fp-armv8") { - Features.push_back("+fp-armv8"); - Features.push_back("-neon"); - Features.push_back("-crypto"); - } else if (FPU == "neon-fp-armv8") { - Features.push_back("+fp-armv8"); - Features.push_back("+neon"); - Features.push_back("-crypto"); - } else if (FPU == "crypto-neon-fp-armv8") { - Features.push_back("+fp-armv8"); - Features.push_back("+neon"); - Features.push_back("+crypto"); - } else if (FPU == "neon") { - Features.push_back("+neon"); - } else if (FPU == "neon-vfpv3") { - Features.push_back("+vfp3"); - Features.push_back("+neon"); - } else if (FPU == "neon-vfpv4") { - Features.push_back("+neon"); - Features.push_back("+vfp4"); - } else if (FPU == "none") { + // FIXME: Why does "none" disable more than "invalid"? + if (FPU == "none") { Features.push_back("-vfp2"); Features.push_back("-vfp3"); Features.push_back("-vfp4"); Features.push_back("-fp-armv8"); Features.push_back("-crypto"); Features.push_back("-neon"); - } else + return; + } + + // FIXME: Make sure we differentiate sp-only. + if (FPU.find("-sp-") != StringRef::npos) { + Features.push_back("+fp-only-sp"); + } + + // All other FPU types, valid or invalid. + switch(llvm::ARMTargetParser::parseFPU(FPU)) { + case llvm::ARM::INVALID_FPU: + case llvm::ARM::SOFTVFP: + Features.push_back("-vfp2"); + Features.push_back("-vfp3"); + Features.push_back("-neon"); + break; + case llvm::ARM::VFP: + case llvm::ARM::VFPV2: + Features.push_back("+vfp2"); + Features.push_back("-neon"); + break; + case llvm::ARM::VFPV3_D16: + Features.push_back("+d16"); + // fall-through + case llvm::ARM::VFPV3: + Features.push_back("+vfp3"); + Features.push_back("-neon"); + break; + case llvm::ARM::VFPV4_D16: + Features.push_back("+d16"); + // fall-through + case llvm::ARM::VFPV4: + Features.push_back("+vfp4"); + Features.push_back("-neon"); + break; + case llvm::ARM::FPV5_D16: + Features.push_back("+d16"); + // fall-through + case llvm::ARM::FP_ARMV8: + Features.push_back("+fp-armv8"); + Features.push_back("-neon"); + Features.push_back("-crypto"); + break; + case llvm::ARM::NEON_FP_ARMV8: + Features.push_back("+fp-armv8"); + Features.push_back("+neon"); + Features.push_back("-crypto"); + break; + case llvm::ARM::CRYPTO_NEON_FP_ARMV8: + Features.push_back("+fp-armv8"); + Features.push_back("+neon"); + Features.push_back("+crypto"); + break; + case llvm::ARM::NEON: + Features.push_back("+neon"); + break; + case llvm::ARM::NEON_VFPV4: + Features.push_back("+neon"); + Features.push_back("+vfp4"); + break; + default: D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); + } } // Select the float ABI as determined by -msoft-float, -mhard-float, and @@ -5657,6 +5660,7 @@ StringRef arm::getARMTargetCPU(const ArgList &Args, // // FIXME: This is redundant with -mcpu, why does LLVM use this. // FIXME: tblgen this, or kill it! +// FIXME: Use ARMTargetParser. const char *arm::getLLVMArchSuffixForARM(StringRef CPU) { return llvm::StringSwitch(CPU) .Case("strongarm", "v4") diff --git a/clang/test/Driver/arm-mfpu.c b/clang/test/Driver/arm-mfpu.c index 0f062a1615a7..d941a3c9af06 100644 --- a/clang/test/Driver/arm-mfpu.c +++ b/clang/test/Driver/arm-mfpu.c @@ -35,8 +35,8 @@ // RUN: | FileCheck --check-prefix=CHECK-VFP3-D16 %s // RUN: %clang -target arm-linux-eabi -mfpu=vfpv3-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-VFP3-D16 %s -// CHECK-VFP3-D16: "-target-feature" "+vfp3" // CHECK-VFP3-D16: "-target-feature" "+d16" +// CHECK-VFP3-D16: "-target-feature" "+vfp3" // CHECK-VFP3-D16: "-target-feature" "-neon" // RUN: %clang -target arm-linux-eabi -mfpu=vfp4 %s -### -o %t.o 2>&1 \ @@ -50,26 +50,26 @@ // RUN: | FileCheck --check-prefix=CHECK-VFP4-D16 %s // RUN: %clang -target arm-linux-eabi -mfpu=vfpv4-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-VFP4-D16 %s -// CHECK-VFP4-D16: "-target-feature" "+vfp4" // CHECK-VFP4-D16: "-target-feature" "+d16" +// CHECK-VFP4-D16: "-target-feature" "+vfp4" // CHECK-VFP4-D16: "-target-feature" "-neon" // RUN: %clang -target arm-linux-eabi -mfpu=fp4-sp-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FP4-SP-D16 %s // RUN: %clang -target arm-linux-eabi -mfpu=fpv4-sp-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FP4-SP-D16 %s -// CHECK-FP4-SP-D16: "-target-feature" "+vfp4" -// CHECK-FP4-SP-D16: "-target-feature" "+d16" // CHECK-FP4-SP-D16: "-target-feature" "+fp-only-sp" +// CHECK-FP4-SP-D16: "-target-feature" "+d16" +// CHECK-FP4-SP-D16: "-target-feature" "+vfp4" // CHECK-FP4-SP-D16: "-target-feature" "-neon" // RUN: %clang -target arm-linux-eabi -mfpu=fp5-sp-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FP5-SP-D16 %s // RUN: %clang -target arm-linux-eabi -mfpu=fpv5-sp-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FP5-SP-D16 %s -// CHECK-FP5-SP-D16: "-target-feature" "+fp-armv8" // CHECK-FP5-SP-D16: "-target-feature" "+fp-only-sp" // CHECK-FP5-SP-D16: "-target-feature" "+d16" +// CHECK-FP5-SP-D16: "-target-feature" "+fp-armv8" // CHECK-FP5-SP-D16: "-target-feature" "-neon" // CHECK-FP5-SP-D16: "-target-feature" "-crypto" @@ -77,8 +77,8 @@ // RUN: | FileCheck --check-prefix=CHECK-FP5-DP-D16 %s // RUN: %clang -target arm-linux-eabi -mfpu=fpv5-dp-d16 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FP5-DP-D16 %s -// CHECK-FP5-DP-D16: "-target-feature" "+fp-armv8" // CHECK-FP5-DP-D16: "-target-feature" "+d16" +// CHECK-FP5-DP-D16: "-target-feature" "+fp-armv8" // CHECK-FP5-DP-D16: "-target-feature" "-neon" // CHECK-FP5-DP-D16: "-target-feature" "-crypto" @@ -88,7 +88,6 @@ // RUN: %clang -target arm-linux-eabi -mfpu=neon-vfpv3 %s -### -o %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NEON-VFPV3 %s -// CHECK-NEON-VFPV3: "-target-feature" "+vfp3" // CHECK-NEON-VFPV3: "-target-feature" "+neon" // RUN: %clang -target arm-linux-eabi -mfpu=neon-vfpv4 %s -### -o %t.o 2>&1 \