1 //===--- Sparc.cpp - Implement Sparc target feature support ---------------===// 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 Sparc TargetInfo objects. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Sparc.h" 15 #include "Targets.h" 16 #include "clang/Basic/MacroBuilder.h" 17 #include "llvm/ADT/StringSwitch.h" 18 19 using namespace clang; 20 using namespace clang::targets; 21 22 const char *const SparcTargetInfo::GCCRegNames[] = { 23 // Integer registers 24 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 25 "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", 26 "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 27 28 // Floating-point registers 29 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", 30 "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", 31 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32", 32 "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54", 33 "f56", "f58", "f60", "f62", 34 }; 35 36 ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const { 37 return llvm::makeArrayRef(GCCRegNames); 38 } 39 40 const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = { 41 {{"g0"}, "r0"}, {{"g1"}, "r1"}, {{"g2"}, "r2"}, {{"g3"}, "r3"}, 42 {{"g4"}, "r4"}, {{"g5"}, "r5"}, {{"g6"}, "r6"}, {{"g7"}, "r7"}, 43 {{"o0"}, "r8"}, {{"o1"}, "r9"}, {{"o2"}, "r10"}, {{"o3"}, "r11"}, 44 {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"}, 45 {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"}, {{"l3"}, "r19"}, 46 {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"}, {{"l7"}, "r23"}, 47 {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"}, {{"i3"}, "r27"}, 48 {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"}, 49 }; 50 51 ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const { 52 return llvm::makeArrayRef(GCCRegAliases); 53 } 54 55 bool SparcTargetInfo::hasFeature(StringRef Feature) const { 56 return llvm::StringSwitch<bool>(Feature) 57 .Case("softfloat", SoftFloat) 58 .Case("sparc", true) 59 .Default(false); 60 } 61 62 struct SparcCPUInfo { 63 llvm::StringLiteral Name; 64 SparcTargetInfo::CPUKind Kind; 65 SparcTargetInfo::CPUGeneration Generation; 66 }; 67 68 static constexpr SparcCPUInfo CPUInfo[] = { 69 {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8}, 70 {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8}, 71 {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8}, 72 {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8}, 73 {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8}, 74 {{"sparclite86x"}, 75 SparcTargetInfo::CK_SPARCLITE86X, 76 SparcTargetInfo::CG_V8}, 77 {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8}, 78 {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8}, 79 {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9}, 80 {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9}, 81 {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9}, 82 {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9}, 83 {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9}, 84 {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9}, 85 {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9}, 86 {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, 87 {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8}, 88 {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8}, 89 {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8}, 90 {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8}, 91 {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, 92 {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8}, 93 {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8}, 94 {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8}, 95 {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8}, 96 {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, 97 // FIXME: the myriad2[.n] spellings are obsolete, 98 // but a grace period is needed to allow updating dependent builds. 99 {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, 100 {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, 101 {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, 102 {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, 103 {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, 104 {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, 105 {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, 106 {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8}, 107 {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8}, 108 {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8}, 109 {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8}, 110 {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8}, 111 }; 112 113 SparcTargetInfo::CPUGeneration 114 SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { 115 if (Kind == CK_GENERIC) 116 return CG_V8; 117 const SparcCPUInfo *Item = llvm::find_if( 118 CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; }); 119 if (Item == std::end(CPUInfo)) 120 llvm_unreachable("Unexpected CPU kind"); 121 return Item->Generation; 122 } 123 124 SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { 125 const SparcCPUInfo *Item = llvm::find_if( 126 CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; }); 127 128 if (Item == std::end(CPUInfo)) 129 return CK_GENERIC; 130 return Item->Kind; 131 } 132 133 void SparcTargetInfo::fillValidCPUList( 134 SmallVectorImpl<StringRef> &Values) const { 135 for (const SparcCPUInfo &Info : CPUInfo) 136 Values.push_back(Info.Name); 137 } 138 139 void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, 140 MacroBuilder &Builder) const { 141 DefineStd(Builder, "sparc", Opts); 142 Builder.defineMacro("__REGISTER_PREFIX__", ""); 143 144 if (SoftFloat) 145 Builder.defineMacro("SOFT_FLOAT", "1"); 146 } 147 148 void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, 149 MacroBuilder &Builder) const { 150 SparcTargetInfo::getTargetDefines(Opts, Builder); 151 switch (getCPUGeneration(CPU)) { 152 case CG_V8: 153 Builder.defineMacro("__sparcv8"); 154 if (getTriple().getOS() != llvm::Triple::Solaris) 155 Builder.defineMacro("__sparcv8__"); 156 break; 157 case CG_V9: 158 Builder.defineMacro("__sparcv9"); 159 if (getTriple().getOS() != llvm::Triple::Solaris) { 160 Builder.defineMacro("__sparcv9__"); 161 Builder.defineMacro("__sparc_v9__"); 162 } 163 break; 164 } 165 if (getTriple().getVendor() == llvm::Triple::Myriad) { 166 std::string MyriadArchValue, Myriad2Value; 167 Builder.defineMacro("__sparc_v8__"); 168 Builder.defineMacro("__leon__"); 169 switch (CPU) { 170 case CK_MYRIAD2100: 171 MyriadArchValue = "__ma2100"; 172 Myriad2Value = "1"; 173 break; 174 case CK_MYRIAD2150: 175 MyriadArchValue = "__ma2150"; 176 Myriad2Value = "2"; 177 break; 178 case CK_MYRIAD2155: 179 MyriadArchValue = "__ma2155"; 180 Myriad2Value = "2"; 181 break; 182 case CK_MYRIAD2450: 183 MyriadArchValue = "__ma2450"; 184 Myriad2Value = "2"; 185 break; 186 case CK_MYRIAD2455: 187 MyriadArchValue = "__ma2455"; 188 Myriad2Value = "2"; 189 break; 190 case CK_MYRIAD2x5x: 191 Myriad2Value = "2"; 192 break; 193 case CK_MYRIAD2080: 194 MyriadArchValue = "__ma2080"; 195 Myriad2Value = "3"; 196 break; 197 case CK_MYRIAD2085: 198 MyriadArchValue = "__ma2085"; 199 Myriad2Value = "3"; 200 break; 201 case CK_MYRIAD2480: 202 MyriadArchValue = "__ma2480"; 203 Myriad2Value = "3"; 204 break; 205 case CK_MYRIAD2485: 206 MyriadArchValue = "__ma2485"; 207 Myriad2Value = "3"; 208 break; 209 case CK_MYRIAD2x8x: 210 Myriad2Value = "3"; 211 break; 212 default: 213 MyriadArchValue = "__ma2100"; 214 Myriad2Value = "1"; 215 break; 216 } 217 if (!MyriadArchValue.empty()) { 218 Builder.defineMacro(MyriadArchValue, "1"); 219 Builder.defineMacro(MyriadArchValue + "__", "1"); 220 } 221 if (Myriad2Value == "2") { 222 Builder.defineMacro("__ma2x5x", "1"); 223 Builder.defineMacro("__ma2x5x__", "1"); 224 } else if (Myriad2Value == "3") { 225 Builder.defineMacro("__ma2x8x", "1"); 226 Builder.defineMacro("__ma2x8x__", "1"); 227 } 228 Builder.defineMacro("__myriad2__", Myriad2Value); 229 Builder.defineMacro("__myriad2", Myriad2Value); 230 } 231 } 232 233 void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, 234 MacroBuilder &Builder) const { 235 SparcTargetInfo::getTargetDefines(Opts, Builder); 236 Builder.defineMacro("__sparcv9"); 237 Builder.defineMacro("__arch64__"); 238 // Solaris doesn't need these variants, but the BSDs do. 239 if (getTriple().getOS() != llvm::Triple::Solaris) { 240 Builder.defineMacro("__sparc64__"); 241 Builder.defineMacro("__sparc_v9__"); 242 Builder.defineMacro("__sparcv9__"); 243 } 244 } 245 246 void SparcV9TargetInfo::fillValidCPUList( 247 SmallVectorImpl<StringRef> &Values) const { 248 for (const SparcCPUInfo &Info : CPUInfo) 249 if (Info.Generation == CG_V9) 250 Values.push_back(Info.Name); 251 } 252