1145449b1SDimitry Andric //===-- TargetParser - Parser for target features ---------------*- C++ -*-===// 2145449b1SDimitry Andric // 3145449b1SDimitry Andric // The LLVM Compiler Infrastructure 4145449b1SDimitry Andric // 5145449b1SDimitry Andric // This file is distributed under the University of Illinois Open Source 6145449b1SDimitry Andric // License. See LICENSE.TXT for details. 7145449b1SDimitry Andric // 8145449b1SDimitry Andric //===----------------------------------------------------------------------===// 9145449b1SDimitry Andric // 10145449b1SDimitry Andric // This file implements a target parser to recognise CSKY hardware features 11145449b1SDimitry Andric // such as CPU/ARCH names. 12145449b1SDimitry Andric // 13145449b1SDimitry Andric //===----------------------------------------------------------------------===// 14145449b1SDimitry Andric 15e3b55780SDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.h" 16145449b1SDimitry Andric #include "llvm/ADT/StringSwitch.h" 17145449b1SDimitry Andric 18145449b1SDimitry Andric using namespace llvm; 19145449b1SDimitry Andric getFPUFeatures(CSKYFPUKind CSKYFPUKind,std::vector<StringRef> & Features)20145449b1SDimitry Andricbool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind, 21145449b1SDimitry Andric std::vector<StringRef> &Features) { 22145449b1SDimitry Andric 23145449b1SDimitry Andric if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID) 24145449b1SDimitry Andric return false; 25145449b1SDimitry Andric 26145449b1SDimitry Andric switch (CSKYFPUKind) { 27145449b1SDimitry Andric case FK_AUTO: 28145449b1SDimitry Andric Features.push_back("+fpuv2_sf"); 29145449b1SDimitry Andric Features.push_back("+fpuv2_df"); 30145449b1SDimitry Andric Features.push_back("+fdivdu"); 31145449b1SDimitry Andric break; 32145449b1SDimitry Andric case FK_FPV2: 33145449b1SDimitry Andric Features.push_back("+fpuv2_sf"); 34145449b1SDimitry Andric Features.push_back("+fpuv2_df"); 35145449b1SDimitry Andric break; 36145449b1SDimitry Andric case FK_FPV2_DIVD: 37145449b1SDimitry Andric Features.push_back("+fpuv2_sf"); 38145449b1SDimitry Andric Features.push_back("+fpuv2_df"); 39145449b1SDimitry Andric Features.push_back("+fdivdu"); 40145449b1SDimitry Andric break; 41145449b1SDimitry Andric case FK_FPV2_SF: 42145449b1SDimitry Andric Features.push_back("+fpuv2_sf"); 43145449b1SDimitry Andric break; 44145449b1SDimitry Andric case FK_FPV3: 45145449b1SDimitry Andric Features.push_back("+fpuv3_hf"); 46145449b1SDimitry Andric Features.push_back("+fpuv3_hi"); 47145449b1SDimitry Andric Features.push_back("+fpuv3_sf"); 48145449b1SDimitry Andric Features.push_back("+fpuv3_df"); 49145449b1SDimitry Andric break; 50145449b1SDimitry Andric case FK_FPV3_HF: 51145449b1SDimitry Andric Features.push_back("+fpuv3_hf"); 52145449b1SDimitry Andric Features.push_back("+fpuv3_hi"); 53145449b1SDimitry Andric break; 54145449b1SDimitry Andric case FK_FPV3_HSF: 55145449b1SDimitry Andric Features.push_back("+fpuv3_hf"); 56145449b1SDimitry Andric Features.push_back("+fpuv3_hi"); 57145449b1SDimitry Andric Features.push_back("+fpuv3_sf"); 58145449b1SDimitry Andric break; 59145449b1SDimitry Andric case FK_FPV3_SDF: 60145449b1SDimitry Andric Features.push_back("+fpuv3_sf"); 61145449b1SDimitry Andric Features.push_back("+fpuv3_df"); 62145449b1SDimitry Andric break; 63145449b1SDimitry Andric default: 64145449b1SDimitry Andric llvm_unreachable("Unknown FPU Kind"); 65145449b1SDimitry Andric return false; 66145449b1SDimitry Andric } 67145449b1SDimitry Andric 68145449b1SDimitry Andric return true; 69145449b1SDimitry Andric } 70145449b1SDimitry Andric 71145449b1SDimitry Andric // ======================================================= // 72145449b1SDimitry Andric // Information by ID 73145449b1SDimitry Andric // ======================================================= // 74145449b1SDimitry Andric getArchName(ArchKind AK)75145449b1SDimitry AndricStringRef CSKY::getArchName(ArchKind AK) { 76145449b1SDimitry Andric return ARCHNames[static_cast<unsigned>(AK)].getName(); 77145449b1SDimitry Andric } 78145449b1SDimitry Andric 79145449b1SDimitry Andric // The default cpu's name is same as arch name. getDefaultCPU(StringRef Arch)80145449b1SDimitry AndricStringRef CSKY::getDefaultCPU(StringRef Arch) { 81145449b1SDimitry Andric ArchKind AK = parseArch(Arch); 82145449b1SDimitry Andric if (AK == CSKY::ArchKind::INVALID) 83145449b1SDimitry Andric return StringRef(); 84145449b1SDimitry Andric 85145449b1SDimitry Andric return Arch; 86145449b1SDimitry Andric } 87145449b1SDimitry Andric 88145449b1SDimitry Andric // ======================================================= // 89145449b1SDimitry Andric // Parsers 90145449b1SDimitry Andric // ======================================================= // parseArch(StringRef Arch)91145449b1SDimitry AndricCSKY::ArchKind CSKY::parseArch(StringRef Arch) { 92145449b1SDimitry Andric for (const auto A : ARCHNames) { 93145449b1SDimitry Andric if (A.getName() == Arch) 94145449b1SDimitry Andric return A.ID; 95145449b1SDimitry Andric } 96145449b1SDimitry Andric 97145449b1SDimitry Andric return CSKY::ArchKind::INVALID; 98145449b1SDimitry Andric } 99145449b1SDimitry Andric parseCPUArch(StringRef CPU)100145449b1SDimitry AndricCSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) { 101145449b1SDimitry Andric for (const auto C : CPUNames) { 102145449b1SDimitry Andric if (CPU == C.getName()) 103145449b1SDimitry Andric return C.ArchID; 104145449b1SDimitry Andric } 105145449b1SDimitry Andric 106145449b1SDimitry Andric return CSKY::ArchKind::INVALID; 107145449b1SDimitry Andric } 108145449b1SDimitry Andric parseArchExt(StringRef ArchExt)109145449b1SDimitry Andricuint64_t CSKY::parseArchExt(StringRef ArchExt) { 110145449b1SDimitry Andric for (const auto &A : CSKYARCHExtNames) { 111145449b1SDimitry Andric if (ArchExt == A.getName()) 112145449b1SDimitry Andric return A.ID; 113145449b1SDimitry Andric } 114145449b1SDimitry Andric return AEK_INVALID; 115145449b1SDimitry Andric } 116145449b1SDimitry Andric fillValidCPUArchList(SmallVectorImpl<StringRef> & Values)117145449b1SDimitry Andricvoid CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { 118145449b1SDimitry Andric for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) { 119145449b1SDimitry Andric if (Arch.ArchID != CSKY::ArchKind::INVALID) 120145449b1SDimitry Andric Values.push_back(Arch.getName()); 121145449b1SDimitry Andric } 122145449b1SDimitry Andric } 123145449b1SDimitry Andric getFPUName(unsigned FPUKind)124145449b1SDimitry AndricStringRef CSKY::getFPUName(unsigned FPUKind) { 125145449b1SDimitry Andric if (FPUKind >= FK_LAST) 126145449b1SDimitry Andric return StringRef(); 127145449b1SDimitry Andric return FPUNames[FPUKind].getName(); 128145449b1SDimitry Andric } 129145449b1SDimitry Andric getFPUVersion(unsigned FPUKind)130145449b1SDimitry AndricCSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) { 131145449b1SDimitry Andric if (FPUKind >= FK_LAST) 132145449b1SDimitry Andric return FPUVersion::NONE; 133145449b1SDimitry Andric return FPUNames[FPUKind].FPUVer; 134145449b1SDimitry Andric } 135145449b1SDimitry Andric getDefaultExtensions(StringRef CPU)136145449b1SDimitry Andricuint64_t CSKY::getDefaultExtensions(StringRef CPU) { 137145449b1SDimitry Andric return StringSwitch<uint64_t>(CPU) 138145449b1SDimitry Andric #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT) \ 139145449b1SDimitry Andric .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt | \ 140145449b1SDimitry Andric DEFAULT_EXT) 141e3b55780SDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.def" 142145449b1SDimitry Andric .Default(CSKY::AEK_INVALID); 143145449b1SDimitry Andric } 144145449b1SDimitry Andric getArchExtName(uint64_t ArchExtKind)145145449b1SDimitry AndricStringRef CSKY::getArchExtName(uint64_t ArchExtKind) { 146145449b1SDimitry Andric for (const auto &AE : CSKYARCHExtNames) 147145449b1SDimitry Andric if (ArchExtKind == AE.ID) 148145449b1SDimitry Andric return AE.getName(); 149145449b1SDimitry Andric return StringRef(); 150145449b1SDimitry Andric } 151145449b1SDimitry Andric stripNegationPrefix(StringRef & Name)152145449b1SDimitry Andricstatic bool stripNegationPrefix(StringRef &Name) { 153312c0ed1SDimitry Andric if (Name.starts_with("no")) { 154145449b1SDimitry Andric Name = Name.substr(2); 155145449b1SDimitry Andric return true; 156145449b1SDimitry Andric } 157145449b1SDimitry Andric return false; 158145449b1SDimitry Andric } 159145449b1SDimitry Andric getArchExtFeature(StringRef ArchExt)160145449b1SDimitry AndricStringRef CSKY::getArchExtFeature(StringRef ArchExt) { 161145449b1SDimitry Andric bool Negated = stripNegationPrefix(ArchExt); 162145449b1SDimitry Andric for (const auto &AE : CSKYARCHExtNames) { 163145449b1SDimitry Andric if (AE.Feature && ArchExt == AE.getName()) 164145449b1SDimitry Andric return StringRef(Negated ? AE.NegFeature : AE.Feature); 165145449b1SDimitry Andric } 166145449b1SDimitry Andric 167145449b1SDimitry Andric return StringRef(); 168145449b1SDimitry Andric } 169145449b1SDimitry Andric getExtensionFeatures(uint64_t Extensions,std::vector<StringRef> & Features)170145449b1SDimitry Andricbool CSKY::getExtensionFeatures(uint64_t Extensions, 171145449b1SDimitry Andric std::vector<StringRef> &Features) { 172145449b1SDimitry Andric if (Extensions == CSKY::AEK_INVALID) 173145449b1SDimitry Andric return false; 174145449b1SDimitry Andric 175145449b1SDimitry Andric for (const auto &AE : CSKYARCHExtNames) { 176145449b1SDimitry Andric if ((Extensions & AE.ID) == AE.ID && AE.Feature) 177145449b1SDimitry Andric Features.push_back(AE.Feature); 178145449b1SDimitry Andric } 179145449b1SDimitry Andric 180145449b1SDimitry Andric return true; 181145449b1SDimitry Andric } 182