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/TargetParser/CSKYTargetParser.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringSwitch.h" 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_hi"); 48 Features.push_back("+fpuv3_sf"); 49 Features.push_back("+fpuv3_df"); 50 break; 51 case FK_FPV3_HF: 52 Features.push_back("+fpuv3_hf"); 53 Features.push_back("+fpuv3_hi"); 54 break; 55 case FK_FPV3_HSF: 56 Features.push_back("+fpuv3_hf"); 57 Features.push_back("+fpuv3_hi"); 58 Features.push_back("+fpuv3_sf"); 59 break; 60 case FK_FPV3_SDF: 61 Features.push_back("+fpuv3_sf"); 62 Features.push_back("+fpuv3_df"); 63 break; 64 default: 65 llvm_unreachable("Unknown FPU Kind"); 66 return false; 67 } 68 69 return true; 70 } 71 72 // ======================================================= // 73 // Information by ID 74 // ======================================================= // 75 76 StringRef CSKY::getArchName(ArchKind AK) { 77 return ARCHNames[static_cast<unsigned>(AK)].getName(); 78 } 79 80 // The default cpu's name is same as arch name. 81 StringRef CSKY::getDefaultCPU(StringRef Arch) { 82 ArchKind AK = parseArch(Arch); 83 if (AK == CSKY::ArchKind::INVALID) 84 return StringRef(); 85 86 return Arch; 87 } 88 89 // ======================================================= // 90 // Parsers 91 // ======================================================= // 92 CSKY::ArchKind CSKY::parseArch(StringRef Arch) { 93 for (const auto A : ARCHNames) { 94 if (A.getName() == Arch) 95 return A.ID; 96 } 97 98 return CSKY::ArchKind::INVALID; 99 } 100 101 CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) { 102 for (const auto C : CPUNames) { 103 if (CPU == C.getName()) 104 return C.ArchID; 105 } 106 107 return CSKY::ArchKind::INVALID; 108 } 109 110 uint64_t CSKY::parseArchExt(StringRef ArchExt) { 111 for (const auto &A : CSKYARCHExtNames) { 112 if (ArchExt == A.getName()) 113 return A.ID; 114 } 115 return AEK_INVALID; 116 } 117 118 void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { 119 for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) { 120 if (Arch.ArchID != CSKY::ArchKind::INVALID) 121 Values.push_back(Arch.getName()); 122 } 123 } 124 125 StringRef CSKY::getFPUName(unsigned FPUKind) { 126 if (FPUKind >= FK_LAST) 127 return StringRef(); 128 return FPUNames[FPUKind].getName(); 129 } 130 131 CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) { 132 if (FPUKind >= FK_LAST) 133 return FPUVersion::NONE; 134 return FPUNames[FPUKind].FPUVer; 135 } 136 137 uint64_t CSKY::getDefaultExtensions(StringRef CPU) { 138 return StringSwitch<uint64_t>(CPU) 139 #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT) \ 140 .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt | \ 141 DEFAULT_EXT) 142 #include "llvm/TargetParser/CSKYTargetParser.def" 143 .Default(CSKY::AEK_INVALID); 144 } 145 146 StringRef CSKY::getArchExtName(uint64_t ArchExtKind) { 147 for (const auto &AE : CSKYARCHExtNames) 148 if (ArchExtKind == AE.ID) 149 return AE.getName(); 150 return StringRef(); 151 } 152 153 static bool stripNegationPrefix(StringRef &Name) { 154 if (Name.starts_with("no")) { 155 Name = Name.substr(2); 156 return true; 157 } 158 return false; 159 } 160 161 StringRef CSKY::getArchExtFeature(StringRef ArchExt) { 162 bool Negated = stripNegationPrefix(ArchExt); 163 for (const auto &AE : CSKYARCHExtNames) { 164 if (AE.Feature && ArchExt == AE.getName()) 165 return StringRef(Negated ? AE.NegFeature : AE.Feature); 166 } 167 168 return StringRef(); 169 } 170 171 bool CSKY::getExtensionFeatures(uint64_t Extensions, 172 std::vector<StringRef> &Features) { 173 if (Extensions == CSKY::AEK_INVALID) 174 return false; 175 176 for (const auto &AE : CSKYARCHExtNames) { 177 if ((Extensions & AE.ID) == AE.ID && AE.Feature) 178 Features.push_back(AE.Feature); 179 } 180 181 return true; 182 } 183