aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/CSKYTargetParser.cpp181
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;
+}