Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -108,6 +108,7 @@ } } +// FIXME: Use ARMTargetParser. static const char *GetArmArchForMArch(StringRef Value) { return llvm::StringSwitch(Value) .Case("armv6k", "armv6") @@ -125,6 +126,7 @@ .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") Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ 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 @@ 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. + // 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"); + 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"); - } else if (FPU == "vfp") { + break; + case llvm::ARM::VFP: + case llvm::ARM::VFPV2: Features.push_back("+vfp2"); Features.push_back("-neon"); - } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") { - Features.push_back("+vfp3"); + break; + case llvm::ARM::VFPV3_D16: Features.push_back("+d16"); - Features.push_back("-neon"); - } else if (FPU == "vfp3" || FPU == "vfpv3") { + // fall-through + case llvm::ARM::VFPV3: Features.push_back("+vfp3"); Features.push_back("-neon"); - } else if (FPU == "vfp4-d16" || FPU == "vfpv4-d16") { - Features.push_back("+vfp4"); + break; + case llvm::ARM::VFPV4_D16: 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") { + // fall-through + case llvm::ARM::VFPV4: 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"); + break; + case llvm::ARM::FPV5_D16: Features.push_back("+d16"); - Features.push_back("-neon"); - Features.push_back("-crypto"); - } else if (FPU == "fp-armv8") { + // fall-through + case llvm::ARM::FP_ARMV8: Features.push_back("+fp-armv8"); Features.push_back("-neon"); Features.push_back("-crypto"); - } else if (FPU == "neon-fp-armv8") { + break; + case llvm::ARM::NEON_FP_ARMV8: Features.push_back("+fp-armv8"); Features.push_back("+neon"); Features.push_back("-crypto"); - } else if (FPU == "crypto-neon-fp-armv8") { + break; + case llvm::ARM::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"); + break; + case llvm::ARM::NEON: Features.push_back("+neon"); - } else if (FPU == "neon-vfpv4") { + break; + case llvm::ARM::NEON_VFPV4: Features.push_back("+neon"); Features.push_back("+vfp4"); - } else 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 + break; + default: D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); + } } // Select the float ABI as determined by -msoft-float, -mhard-float, and @@ -5644,6 +5647,7 @@ // // 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") Index: test/Driver/arm-mfpu.c =================================================================== --- test/Driver/arm-mfpu.c +++ 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 \