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