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