diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
| commit | b1c73532ee8997fe5dfbeb7d223027bdf99758a0 (patch) | |
| tree | 7d6e51c294ab6719475d660217aa0c0ad0526292 /llvm/lib/TargetParser/ARMTargetParser.cpp | |
| parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
Diffstat (limited to 'llvm/lib/TargetParser/ARMTargetParser.cpp')
| -rw-r--r-- | llvm/lib/TargetParser/ARMTargetParser.cpp | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp index 785e9a4fe3fb..d09992441909 100644 --- a/llvm/lib/TargetParser/ARMTargetParser.cpp +++ b/llvm/lib/TargetParser/ARMTargetParser.cpp @@ -13,6 +13,8 @@ #include "llvm/TargetParser/ARMTargetParser.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/ARMTargetParserCommon.h" #include "llvm/TargetParser/Triple.h" #include <cctype> @@ -364,26 +366,51 @@ StringRef ARM::getArchExtFeature(StringRef ArchExt) { } static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind) { + if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE) + return ARM::FK_INVALID; + const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind]; // If the input FPU already supports double-precision, then there // isn't any different FPU we can return here. - // - // The current available FPURestriction values are None (no - // restriction), D16 (only 16 d-regs) and SP_D16 (16 d-regs - // and single precision only); there's no value representing - // SP restriction without D16. So this test just means 'is it - // SP only?'. - if (InputFPU.Restriction != ARM::FPURestriction::SP_D16) + if (ARM::isDoublePrecision(InputFPU.Restriction)) + return InputFPUKind; + + // Otherwise, look for an FPU entry with all the same fields, except + // that it supports double precision. + for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) { + if (CandidateFPU.FPUVer == InputFPU.FPUVer && + CandidateFPU.NeonSupport == InputFPU.NeonSupport && + ARM::has32Regs(CandidateFPU.Restriction) == + ARM::has32Regs(InputFPU.Restriction) && + ARM::isDoublePrecision(CandidateFPU.Restriction)) { + return CandidateFPU.ID; + } + } + + // nothing found + return ARM::FK_INVALID; +} + +static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) { + if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE) return ARM::FK_INVALID; + const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind]; + + // If the input FPU already is single-precision only, then there + // isn't any different FPU we can return here. + if (!ARM::isDoublePrecision(InputFPU.Restriction)) + return InputFPUKind; + // Otherwise, look for an FPU entry with all the same fields, except - // that SP_D16 has been replaced with just D16, representing adding - // double precision and not changing anything else. + // that it does not support double precision. for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) { if (CandidateFPU.FPUVer == InputFPU.FPUVer && CandidateFPU.NeonSupport == InputFPU.NeonSupport && - CandidateFPU.Restriction == ARM::FPURestriction::D16) { + ARM::has32Regs(CandidateFPU.Restriction) == + ARM::has32Regs(InputFPU.Restriction) && + !ARM::isDoublePrecision(CandidateFPU.Restriction)) { return CandidateFPU.ID; } } @@ -418,20 +445,35 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, CPU = "generic"; if (ArchExt == "fp" || ArchExt == "fp.dp") { + const ARM::FPUKind DefaultFPU = getDefaultFPU(CPU, AK); ARM::FPUKind FPUKind; if (ArchExt == "fp.dp") { + const bool IsDP = ArgFPUKind != ARM::FK_INVALID && + ArgFPUKind != ARM::FK_NONE && + isDoublePrecision(getFPURestriction(ArgFPUKind)); if (Negated) { - Features.push_back("-fp64"); - return true; + /* If there is no FPU selected yet, we still need to set ArgFPUKind, as + * leaving it as FK_INVALID, would cause default FPU to be selected + * later and that could be double precision one. */ + if (ArgFPUKind != ARM::FK_INVALID && !IsDP) + return true; + FPUKind = findSinglePrecisionFPU(DefaultFPU); + if (FPUKind == ARM::FK_INVALID) + FPUKind = ARM::FK_NONE; + } else { + if (IsDP) + return true; + FPUKind = findDoublePrecisionFPU(DefaultFPU); + if (FPUKind == ARM::FK_INVALID) + return false; } - FPUKind = findDoublePrecisionFPU(getDefaultFPU(CPU, AK)); } else if (Negated) { FPUKind = ARM::FK_NONE; } else { - FPUKind = getDefaultFPU(CPU, AK); + FPUKind = DefaultFPU; } ArgFPUKind = FPUKind; - return ARM::getFPUFeatures(FPUKind, Features); + return true; } return StartingNumFeatures != Features.size(); } @@ -517,6 +559,7 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { case Triple::GNUEABIHF: case Triple::MuslEABI: case Triple::MuslEABIHF: + case Triple::OpenHOS: return "aapcs-linux"; case Triple::EABIHF: case Triple::EABI: @@ -524,7 +567,8 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { default: if (TT.isOSNetBSD()) return "apcs-gnu"; - if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOHOSFamily()) + if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOSHaiku() || + TT.isOHOSFamily()) return "aapcs-linux"; return "aapcs"; } @@ -540,6 +584,7 @@ StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) { case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: case llvm::Triple::OpenBSD: + case llvm::Triple::Haiku: if (!MArch.empty() && MArch == "v6") return "arm1176jzf-s"; if (!MArch.empty() && MArch == "v7") @@ -572,6 +617,8 @@ StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) { // If no specific architecture version is requested, return the minimum CPU // required by the OS and environment. switch (Triple.getOS()) { + case llvm::Triple::Haiku: + return "arm1176jzf-s"; case llvm::Triple::NetBSD: switch (Triple.getEnvironment()) { case llvm::Triple::EABI: @@ -598,3 +645,18 @@ StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) { llvm_unreachable("invalid arch name"); } + +void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) { + outs() << "All available -march extensions for ARM\n\n" + << " " << left_justify("Name", 20) + << (DescMap.empty() ? "\n" : "Description\n"); + for (const auto &Ext : ARCHExtNames) { + // Extensions without a feature cannot be used with -march. + if (!Ext.Feature.empty()) { + std::string Description = DescMap[Ext.Name].str(); + outs() << " " + << format(Description.empty() ? "%s\n" : "%-20s%s\n", + Ext.Name.str().c_str(), Description.c_str()); + } + } +} |
