diff options
Diffstat (limited to 'lib/Driver/ToolChains/Arch/ARM.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Arch/ARM.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp index 44c8871d0e1fc..886d947c586b8 100644 --- a/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/lib/Driver/ToolChains/Arch/ARM.cpp @@ -232,7 +232,7 @@ arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) { break; case llvm::Triple::OpenBSD: - ABI = FloatABI::Soft; + ABI = FloatABI::SoftFP; break; default: @@ -391,12 +391,22 @@ void arm::getARMTargetFeatures(const ToolChain &TC, } else if (HDivArg) getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features); - // Setting -msoft-float effectively disables NEON because of the GCC - // implementation, although the same isn't true of VFP or VFP3. + // Setting -msoft-float/-mfloat-abi=soft effectively disables the FPU (GCC + // ignores the -mfpu options in this case). + // Note that the ABI can also be set implicitly by the target selected. if (ABI == arm::FloatABI::Soft) { - Features.push_back("-neon"); - // Also need to explicitly disable features which imply NEON. - Features.push_back("-crypto"); + llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features); + + // Disable hardware FP features which have been enabled. + // FIXME: Disabling vfp2 and neon should be enough as all the other + // features are dependent on these 2 features in LLVM. However + // there is currently no easy way to test this in clang, so for + // now just be explicit and disable all known dependent features + // as well. + for (std::string Feature : {"vfp2", "vfp3", "vfp4", "fp-armv8", "fullfp16", + "neon", "crypto", "dotprod"}) + if (std::find(std::begin(Features), std::end(Features), "+" + Feature) != std::end(Features)) + Features.push_back(Args.MakeArgString("-" + Feature)); } // En/disable crc code generation. @@ -438,7 +448,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC, if (B->getOption().matches(options::OPT_mlong_calls)) D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args); } - Features.push_back("+execute-only"); + Features.push_back("+execute-only"); } } } |