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