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