//===-- 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/TargetParser/CSKYTargetParser.h" #include "llvm/ADT/StringSwitch.h" using namespace llvm; bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind, std::vector &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(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 &Values) { for (const CpuNames &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(CPU) #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT) \ .Case(NAME, ARCHNames[static_cast(ArchKind::ID)].archBaseExt | \ DEFAULT_EXT) #include "llvm/TargetParser/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 &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; }