1bdd1243dSDimitry Andric //===-- TargetParser - Parser for target features ---------------*- C++ -*-===// 2bdd1243dSDimitry Andric // 3bdd1243dSDimitry Andric // The LLVM Compiler Infrastructure 4bdd1243dSDimitry Andric // 5bdd1243dSDimitry Andric // This file is distributed under the University of Illinois Open Source 6bdd1243dSDimitry Andric // License. See LICENSE.TXT for details. 7bdd1243dSDimitry Andric // 8bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 9bdd1243dSDimitry Andric // 10bdd1243dSDimitry Andric // This file implements a target parser to recognise CSKY hardware features 11bdd1243dSDimitry Andric // such as CPU/ARCH names. 12bdd1243dSDimitry Andric // 13bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 14bdd1243dSDimitry Andric 15bdd1243dSDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.h" 16bdd1243dSDimitry Andric #include "llvm/ADT/StringSwitch.h" 17bdd1243dSDimitry Andric 18bdd1243dSDimitry Andric using namespace llvm; 19bdd1243dSDimitry Andric getFPUFeatures(CSKYFPUKind CSKYFPUKind,std::vector<StringRef> & Features)20bdd1243dSDimitry Andricbool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind, 21bdd1243dSDimitry Andric std::vector<StringRef> &Features) { 22bdd1243dSDimitry Andric 23bdd1243dSDimitry Andric if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID) 24bdd1243dSDimitry Andric return false; 25bdd1243dSDimitry Andric 26bdd1243dSDimitry Andric switch (CSKYFPUKind) { 27bdd1243dSDimitry Andric case FK_AUTO: 28bdd1243dSDimitry Andric Features.push_back("+fpuv2_sf"); 29bdd1243dSDimitry Andric Features.push_back("+fpuv2_df"); 30bdd1243dSDimitry Andric Features.push_back("+fdivdu"); 31bdd1243dSDimitry Andric break; 32bdd1243dSDimitry Andric case FK_FPV2: 33bdd1243dSDimitry Andric Features.push_back("+fpuv2_sf"); 34bdd1243dSDimitry Andric Features.push_back("+fpuv2_df"); 35bdd1243dSDimitry Andric break; 36bdd1243dSDimitry Andric case FK_FPV2_DIVD: 37bdd1243dSDimitry Andric Features.push_back("+fpuv2_sf"); 38bdd1243dSDimitry Andric Features.push_back("+fpuv2_df"); 39bdd1243dSDimitry Andric Features.push_back("+fdivdu"); 40bdd1243dSDimitry Andric break; 41bdd1243dSDimitry Andric case FK_FPV2_SF: 42bdd1243dSDimitry Andric Features.push_back("+fpuv2_sf"); 43bdd1243dSDimitry Andric break; 44bdd1243dSDimitry Andric case FK_FPV3: 45bdd1243dSDimitry Andric Features.push_back("+fpuv3_hf"); 46bdd1243dSDimitry Andric Features.push_back("+fpuv3_hi"); 47bdd1243dSDimitry Andric Features.push_back("+fpuv3_sf"); 48bdd1243dSDimitry Andric Features.push_back("+fpuv3_df"); 49bdd1243dSDimitry Andric break; 50bdd1243dSDimitry Andric case FK_FPV3_HF: 51bdd1243dSDimitry Andric Features.push_back("+fpuv3_hf"); 52bdd1243dSDimitry Andric Features.push_back("+fpuv3_hi"); 53bdd1243dSDimitry Andric break; 54bdd1243dSDimitry Andric case FK_FPV3_HSF: 55bdd1243dSDimitry Andric Features.push_back("+fpuv3_hf"); 56bdd1243dSDimitry Andric Features.push_back("+fpuv3_hi"); 57bdd1243dSDimitry Andric Features.push_back("+fpuv3_sf"); 58bdd1243dSDimitry Andric break; 59bdd1243dSDimitry Andric case FK_FPV3_SDF: 60bdd1243dSDimitry Andric Features.push_back("+fpuv3_sf"); 61bdd1243dSDimitry Andric Features.push_back("+fpuv3_df"); 62bdd1243dSDimitry Andric break; 63bdd1243dSDimitry Andric default: 64bdd1243dSDimitry Andric llvm_unreachable("Unknown FPU Kind"); 65bdd1243dSDimitry Andric return false; 66bdd1243dSDimitry Andric } 67bdd1243dSDimitry Andric 68bdd1243dSDimitry Andric return true; 69bdd1243dSDimitry Andric } 70bdd1243dSDimitry Andric 71bdd1243dSDimitry Andric // ======================================================= // 72bdd1243dSDimitry Andric // Information by ID 73bdd1243dSDimitry Andric // ======================================================= // 74bdd1243dSDimitry Andric getArchName(ArchKind AK)75bdd1243dSDimitry AndricStringRef CSKY::getArchName(ArchKind AK) { 76bdd1243dSDimitry Andric return ARCHNames[static_cast<unsigned>(AK)].getName(); 77bdd1243dSDimitry Andric } 78bdd1243dSDimitry Andric 79bdd1243dSDimitry Andric // The default cpu's name is same as arch name. getDefaultCPU(StringRef Arch)80bdd1243dSDimitry AndricStringRef CSKY::getDefaultCPU(StringRef Arch) { 81bdd1243dSDimitry Andric ArchKind AK = parseArch(Arch); 82bdd1243dSDimitry Andric if (AK == CSKY::ArchKind::INVALID) 83bdd1243dSDimitry Andric return StringRef(); 84bdd1243dSDimitry Andric 85bdd1243dSDimitry Andric return Arch; 86bdd1243dSDimitry Andric } 87bdd1243dSDimitry Andric 88bdd1243dSDimitry Andric // ======================================================= // 89bdd1243dSDimitry Andric // Parsers 90bdd1243dSDimitry Andric // ======================================================= // parseArch(StringRef Arch)91bdd1243dSDimitry AndricCSKY::ArchKind CSKY::parseArch(StringRef Arch) { 92bdd1243dSDimitry Andric for (const auto A : ARCHNames) { 93bdd1243dSDimitry Andric if (A.getName() == Arch) 94bdd1243dSDimitry Andric return A.ID; 95bdd1243dSDimitry Andric } 96bdd1243dSDimitry Andric 97bdd1243dSDimitry Andric return CSKY::ArchKind::INVALID; 98bdd1243dSDimitry Andric } 99bdd1243dSDimitry Andric parseCPUArch(StringRef CPU)100bdd1243dSDimitry AndricCSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) { 101bdd1243dSDimitry Andric for (const auto C : CPUNames) { 102bdd1243dSDimitry Andric if (CPU == C.getName()) 103bdd1243dSDimitry Andric return C.ArchID; 104bdd1243dSDimitry Andric } 105bdd1243dSDimitry Andric 106bdd1243dSDimitry Andric return CSKY::ArchKind::INVALID; 107bdd1243dSDimitry Andric } 108bdd1243dSDimitry Andric parseArchExt(StringRef ArchExt)109bdd1243dSDimitry Andricuint64_t CSKY::parseArchExt(StringRef ArchExt) { 110bdd1243dSDimitry Andric for (const auto &A : CSKYARCHExtNames) { 111bdd1243dSDimitry Andric if (ArchExt == A.getName()) 112bdd1243dSDimitry Andric return A.ID; 113bdd1243dSDimitry Andric } 114bdd1243dSDimitry Andric return AEK_INVALID; 115bdd1243dSDimitry Andric } 116bdd1243dSDimitry Andric fillValidCPUArchList(SmallVectorImpl<StringRef> & Values)117bdd1243dSDimitry Andricvoid CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { 118bdd1243dSDimitry Andric for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) { 119bdd1243dSDimitry Andric if (Arch.ArchID != CSKY::ArchKind::INVALID) 120bdd1243dSDimitry Andric Values.push_back(Arch.getName()); 121bdd1243dSDimitry Andric } 122bdd1243dSDimitry Andric } 123bdd1243dSDimitry Andric getFPUName(unsigned FPUKind)124bdd1243dSDimitry AndricStringRef CSKY::getFPUName(unsigned FPUKind) { 125bdd1243dSDimitry Andric if (FPUKind >= FK_LAST) 126bdd1243dSDimitry Andric return StringRef(); 127bdd1243dSDimitry Andric return FPUNames[FPUKind].getName(); 128bdd1243dSDimitry Andric } 129bdd1243dSDimitry Andric getFPUVersion(unsigned FPUKind)130bdd1243dSDimitry AndricCSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) { 131bdd1243dSDimitry Andric if (FPUKind >= FK_LAST) 132bdd1243dSDimitry Andric return FPUVersion::NONE; 133bdd1243dSDimitry Andric return FPUNames[FPUKind].FPUVer; 134bdd1243dSDimitry Andric } 135bdd1243dSDimitry Andric getDefaultExtensions(StringRef CPU)136bdd1243dSDimitry Andricuint64_t CSKY::getDefaultExtensions(StringRef CPU) { 137bdd1243dSDimitry Andric return StringSwitch<uint64_t>(CPU) 138bdd1243dSDimitry Andric #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT) \ 139bdd1243dSDimitry Andric .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt | \ 140bdd1243dSDimitry Andric DEFAULT_EXT) 141bdd1243dSDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.def" 142bdd1243dSDimitry Andric .Default(CSKY::AEK_INVALID); 143bdd1243dSDimitry Andric } 144bdd1243dSDimitry Andric getArchExtName(uint64_t ArchExtKind)145bdd1243dSDimitry AndricStringRef CSKY::getArchExtName(uint64_t ArchExtKind) { 146bdd1243dSDimitry Andric for (const auto &AE : CSKYARCHExtNames) 147bdd1243dSDimitry Andric if (ArchExtKind == AE.ID) 148bdd1243dSDimitry Andric return AE.getName(); 149bdd1243dSDimitry Andric return StringRef(); 150bdd1243dSDimitry Andric } 151bdd1243dSDimitry Andric stripNegationPrefix(StringRef & Name)152bdd1243dSDimitry Andricstatic bool stripNegationPrefix(StringRef &Name) { 153*5f757f3fSDimitry Andric if (Name.starts_with("no")) { 154bdd1243dSDimitry Andric Name = Name.substr(2); 155bdd1243dSDimitry Andric return true; 156bdd1243dSDimitry Andric } 157bdd1243dSDimitry Andric return false; 158bdd1243dSDimitry Andric } 159bdd1243dSDimitry Andric getArchExtFeature(StringRef ArchExt)160bdd1243dSDimitry AndricStringRef CSKY::getArchExtFeature(StringRef ArchExt) { 161bdd1243dSDimitry Andric bool Negated = stripNegationPrefix(ArchExt); 162bdd1243dSDimitry Andric for (const auto &AE : CSKYARCHExtNames) { 163bdd1243dSDimitry Andric if (AE.Feature && ArchExt == AE.getName()) 164bdd1243dSDimitry Andric return StringRef(Negated ? AE.NegFeature : AE.Feature); 165bdd1243dSDimitry Andric } 166bdd1243dSDimitry Andric 167bdd1243dSDimitry Andric return StringRef(); 168bdd1243dSDimitry Andric } 169bdd1243dSDimitry Andric getExtensionFeatures(uint64_t Extensions,std::vector<StringRef> & Features)170bdd1243dSDimitry Andricbool CSKY::getExtensionFeatures(uint64_t Extensions, 171bdd1243dSDimitry Andric std::vector<StringRef> &Features) { 172bdd1243dSDimitry Andric if (Extensions == CSKY::AEK_INVALID) 173bdd1243dSDimitry Andric return false; 174bdd1243dSDimitry Andric 175bdd1243dSDimitry Andric for (const auto &AE : CSKYARCHExtNames) { 176bdd1243dSDimitry Andric if ((Extensions & AE.ID) == AE.ID && AE.Feature) 177bdd1243dSDimitry Andric Features.push_back(AE.Feature); 178bdd1243dSDimitry Andric } 179bdd1243dSDimitry Andric 180bdd1243dSDimitry Andric return true; 181bdd1243dSDimitry Andric } 182