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