diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp b/contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp new file mode 100644 index 000000000000..7e9d2ca0428d --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp @@ -0,0 +1,181 @@ +//===-- TargetParser - Parser for target features ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a target parser to recognise CSKY hardware features +// such as CPU/ARCH names. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CSKYTargetParser.h" +#include "llvm/ADT/StringSwitch.h" + +using namespace llvm; + +bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind, + std::vector<StringRef> &Features) { + + if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID) + return false; + + switch (CSKYFPUKind) { + case FK_AUTO: + Features.push_back("+fpuv2_sf"); + Features.push_back("+fpuv2_df"); + Features.push_back("+fdivdu"); + break; + case FK_FPV2: + Features.push_back("+fpuv2_sf"); + Features.push_back("+fpuv2_df"); + break; + case FK_FPV2_DIVD: + Features.push_back("+fpuv2_sf"); + Features.push_back("+fpuv2_df"); + Features.push_back("+fdivdu"); + break; + case FK_FPV2_SF: + Features.push_back("+fpuv2_sf"); + break; + case FK_FPV3: + Features.push_back("+fpuv3_hf"); + Features.push_back("+fpuv3_hi"); + Features.push_back("+fpuv3_sf"); + Features.push_back("+fpuv3_df"); + break; + case FK_FPV3_HF: + Features.push_back("+fpuv3_hf"); + Features.push_back("+fpuv3_hi"); + break; + case FK_FPV3_HSF: + Features.push_back("+fpuv3_hf"); + Features.push_back("+fpuv3_hi"); + Features.push_back("+fpuv3_sf"); + break; + case FK_FPV3_SDF: + Features.push_back("+fpuv3_sf"); + Features.push_back("+fpuv3_df"); + break; + default: + llvm_unreachable("Unknown FPU Kind"); + return false; + } + + return true; +} + +// ======================================================= // +// Information by ID +// ======================================================= // + +StringRef CSKY::getArchName(ArchKind AK) { + return ARCHNames[static_cast<unsigned>(AK)].getName(); +} + +// The default cpu's name is same as arch name. +StringRef CSKY::getDefaultCPU(StringRef Arch) { + ArchKind AK = parseArch(Arch); + if (AK == CSKY::ArchKind::INVALID) + return StringRef(); + + return Arch; +} + +// ======================================================= // +// Parsers +// ======================================================= // +CSKY::ArchKind CSKY::parseArch(StringRef Arch) { + for (const auto A : ARCHNames) { + if (A.getName() == Arch) + return A.ID; + } + + return CSKY::ArchKind::INVALID; +} + +CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) { + for (const auto C : CPUNames) { + if (CPU == C.getName()) + return C.ArchID; + } + + return CSKY::ArchKind::INVALID; +} + +uint64_t CSKY::parseArchExt(StringRef ArchExt) { + for (const auto &A : CSKYARCHExtNames) { + if (ArchExt == A.getName()) + return A.ID; + } + return AEK_INVALID; +} + +void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { + for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) { + if (Arch.ArchID != CSKY::ArchKind::INVALID) + Values.push_back(Arch.getName()); + } +} + +StringRef CSKY::getFPUName(unsigned FPUKind) { + if (FPUKind >= FK_LAST) + return StringRef(); + return FPUNames[FPUKind].getName(); +} + +CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) { + if (FPUKind >= FK_LAST) + return FPUVersion::NONE; + return FPUNames[FPUKind].FPUVer; +} + +uint64_t CSKY::getDefaultExtensions(StringRef CPU) { + return StringSwitch<uint64_t>(CPU) +#define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT) \ + .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt | \ + DEFAULT_EXT) +#include "llvm/Support/CSKYTargetParser.def" + .Default(CSKY::AEK_INVALID); +} + +StringRef CSKY::getArchExtName(uint64_t ArchExtKind) { + for (const auto &AE : CSKYARCHExtNames) + if (ArchExtKind == AE.ID) + return AE.getName(); + return StringRef(); +} + +static bool stripNegationPrefix(StringRef &Name) { + if (Name.startswith("no")) { + Name = Name.substr(2); + return true; + } + return false; +} + +StringRef CSKY::getArchExtFeature(StringRef ArchExt) { + bool Negated = stripNegationPrefix(ArchExt); + for (const auto &AE : CSKYARCHExtNames) { + if (AE.Feature && ArchExt == AE.getName()) + return StringRef(Negated ? AE.NegFeature : AE.Feature); + } + + return StringRef(); +} + +bool CSKY::getExtensionFeatures(uint64_t Extensions, + std::vector<StringRef> &Features) { + if (Extensions == CSKY::AEK_INVALID) + return false; + + for (const auto &AE : CSKYARCHExtNames) { + if ((Extensions & AE.ID) == AE.ID && AE.Feature) + Features.push_back(AE.Feature); + } + + return true; +} |