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