diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index dd48bc18e816..ff50169e44fd 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -573,8 +573,36 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) { // // FIXME: Centralize feature selection, defaulting shouldn't be also in the // frontend target. -static void getFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args, - std::vector &Features) { +static void getAArch64FPUFeatures(const Driver &D, const Arg *A, + const ArgList &Args, + std::vector &Features) { + StringRef FPU = A->getValue(); + if (FPU == "fp-armv8") { + Features.push_back("+fp-armv8"); + } else if (FPU == "neon-fp-armv8") { + Features.push_back("+fp-armv8"); + Features.push_back("+neon"); + } 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 == "none") { + Features.push_back("-fp-armv8"); + Features.push_back("-crypto"); + Features.push_back("-neon"); + } else + D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); +} + +// Handle -mfpu=. +// +// FIXME: Centralize feature selection, defaulting shouldn't be also in the +// frontend target. +static void getARMFPUFeatures(const Driver &D, const Arg *A, + const ArgList &Args, + std::vector &Features) { StringRef FPU = A->getValue(); // Set the target features based on the FPU. @@ -603,6 +631,13 @@ static void getFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args, Features.push_back("+fp-armv8"); } else if (FPU == "neon") { Features.push_back("+neon"); + } 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 D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -704,7 +739,7 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, // Honor -mfpu=. if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) - getFPUFeatures(D, A, Args, Features); + getARMFPUFeatures(D, A, Args, Features); // Setting -msoft-float effectively disables NEON because of the GCC // implementation, although the same isn't true of VFP or VFP3. @@ -1384,7 +1419,7 @@ static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args, std::vector &Features) { // Honor -mfpu=. if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) - getFPUFeatures(D, A, Args, Features); + getAArch64FPUFeatures(D, A, Args, Features); } static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, diff --git a/clang/test/Driver/arm-mfpu.c b/clang/test/Driver/arm-mfpu.c index d92563a499a3..d9eb55129454 100644 --- a/clang/test/Driver/arm-mfpu.c +++ b/clang/test/Driver/arm-mfpu.c @@ -61,6 +61,15 @@ // CHECK-CRYPTO-NEON-FP-ARMV8: "-target-feature" "+crypto" // CHECK-CRYPTO-NEON-FP-ARMV8: "-target-feature" "+fp-armv8" +// RUN: %clang -target armv8-linux-gnueabi -mfpu=none %s -### 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-FP %s +// CHECK-NO-FP: "-target-feature" "-vfp2" +// CHECK-NO-FP: "-target-feature" "-vfp3" +// CHECK-NO-FP: "-target-feature" "-vfp4" +// CHECK-NO-FP: "-target-feature" "-fp-armv8" +// CHECK-NO-FP: "-target-feature" "-crypto" +// CHECK-NO-FP: "-target-feature" "-neon" + // RUN: %clang -target arm-linux-gnueabihf %s -### 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-HF %s // CHECK-HF: "-target-cpu" "arm1136jf-s"