1 //===--- PPC.cpp - Implement PPC 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 PPC TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "PPC.h" 14 #include "clang/Basic/Diagnostic.h" 15 #include "clang/Basic/MacroBuilder.h" 16 #include "clang/Basic/TargetBuiltins.h" 17 18 using namespace clang; 19 using namespace clang::targets; 20 21 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { 22 #define BUILTIN(ID, TYPE, ATTRS) \ 23 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 24 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 25 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 26 #include "clang/Basic/BuiltinsPPC.def" 27 }; 28 29 /// handleTargetFeatures - Perform initialization based on the user 30 /// configured set of features. 31 bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 32 DiagnosticsEngine &Diags) { 33 FloatABI = HardFloat; 34 for (const auto &Feature : Features) { 35 if (Feature == "+altivec") { 36 HasAltivec = true; 37 } else if (Feature == "+vsx") { 38 HasVSX = true; 39 } else if (Feature == "+bpermd") { 40 HasBPERMD = true; 41 } else if (Feature == "+extdiv") { 42 HasExtDiv = true; 43 } else if (Feature == "+power8-vector") { 44 HasP8Vector = true; 45 } else if (Feature == "+crypto") { 46 HasP8Crypto = true; 47 } else if (Feature == "+direct-move") { 48 HasDirectMove = true; 49 } else if (Feature == "+htm") { 50 HasHTM = true; 51 } else if (Feature == "+float128") { 52 HasFloat128 = true; 53 } else if (Feature == "+power9-vector") { 54 HasP9Vector = true; 55 } else if (Feature == "+power10-vector") { 56 HasP10Vector = true; 57 } else if (Feature == "+pcrelative-memops") { 58 HasPCRelativeMemops = true; 59 } else if (Feature == "+prefix-instrs") { 60 HasPrefixInstrs = true; 61 } else if (Feature == "+spe" || Feature == "+efpu2") { 62 HasStrictFP = false; 63 HasSPE = true; 64 LongDoubleWidth = LongDoubleAlign = 64; 65 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 66 } else if (Feature == "-hard-float") { 67 FloatABI = SoftFloat; 68 } else if (Feature == "+paired-vector-memops") { 69 PairedVectorMemops = true; 70 } else if (Feature == "+mma") { 71 HasMMA = true; 72 } else if (Feature == "+rop-protect") { 73 HasROPProtect = true; 74 } else if (Feature == "+privileged") { 75 HasPrivileged = true; 76 } 77 // TODO: Finish this list and add an assert that we've handled them 78 // all. 79 } 80 81 return true; 82 } 83 84 static void defineXLCompatMacros(MacroBuilder &Builder) { 85 Builder.defineMacro("__popcntb", "__builtin_ppc_popcntb"); 86 Builder.defineMacro("__eieio", "__builtin_ppc_eieio"); 87 Builder.defineMacro("__iospace_eieio", "__builtin_ppc_iospace_eieio"); 88 Builder.defineMacro("__isync", "__builtin_ppc_isync"); 89 Builder.defineMacro("__lwsync", "__builtin_ppc_lwsync"); 90 Builder.defineMacro("__iospace_lwsync", "__builtin_ppc_iospace_lwsync"); 91 Builder.defineMacro("__sync", "__builtin_ppc_sync"); 92 Builder.defineMacro("__iospace_sync", "__builtin_ppc_iospace_sync"); 93 Builder.defineMacro("__dcbfl", "__builtin_ppc_dcbfl"); 94 Builder.defineMacro("__dcbflp", "__builtin_ppc_dcbflp"); 95 Builder.defineMacro("__dcbst", "__builtin_ppc_dcbst"); 96 Builder.defineMacro("__dcbt", "__builtin_ppc_dcbt"); 97 Builder.defineMacro("__dcbtst", "__builtin_ppc_dcbtst"); 98 Builder.defineMacro("__dcbz", "__builtin_ppc_dcbz"); 99 Builder.defineMacro("__icbt", "__builtin_ppc_icbt"); 100 Builder.defineMacro("__compare_and_swap", "__builtin_ppc_compare_and_swap"); 101 Builder.defineMacro("__compare_and_swaplp", 102 "__builtin_ppc_compare_and_swaplp"); 103 Builder.defineMacro("__fetch_and_add", "__builtin_ppc_fetch_and_add"); 104 Builder.defineMacro("__fetch_and_addlp", "__builtin_ppc_fetch_and_addlp"); 105 Builder.defineMacro("__fetch_and_and", "__builtin_ppc_fetch_and_and"); 106 Builder.defineMacro("__fetch_and_andlp", "__builtin_ppc_fetch_and_andlp"); 107 Builder.defineMacro("__fetch_and_or", "__builtin_ppc_fetch_and_or"); 108 Builder.defineMacro("__fetch_and_orlp", "__builtin_ppc_fetch_and_orlp"); 109 Builder.defineMacro("__fetch_and_swap", "__builtin_ppc_fetch_and_swap"); 110 Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_and_swaplp"); 111 } 112 113 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific 114 /// #defines that are not tied to a specific subtarget. 115 void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, 116 MacroBuilder &Builder) const { 117 118 defineXLCompatMacros(Builder); 119 120 // Target identification. 121 Builder.defineMacro("__ppc__"); 122 Builder.defineMacro("__PPC__"); 123 Builder.defineMacro("_ARCH_PPC"); 124 Builder.defineMacro("__powerpc__"); 125 Builder.defineMacro("__POWERPC__"); 126 if (PointerWidth == 64) { 127 Builder.defineMacro("_ARCH_PPC64"); 128 Builder.defineMacro("__powerpc64__"); 129 Builder.defineMacro("__ppc64__"); 130 Builder.defineMacro("__PPC64__"); 131 } 132 133 // Target properties. 134 if (getTriple().getArch() == llvm::Triple::ppc64le || 135 getTriple().getArch() == llvm::Triple::ppcle) { 136 Builder.defineMacro("_LITTLE_ENDIAN"); 137 } else { 138 if (!getTriple().isOSNetBSD() && 139 !getTriple().isOSOpenBSD()) 140 Builder.defineMacro("_BIG_ENDIAN"); 141 } 142 143 // ABI options. 144 if (ABI == "elfv1") 145 Builder.defineMacro("_CALL_ELF", "1"); 146 if (ABI == "elfv2") 147 Builder.defineMacro("_CALL_ELF", "2"); 148 149 // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but 150 // our support post-dates this and it should work on all 64-bit ppc linux 151 // platforms. It is guaranteed to work on all elfv2 platforms. 152 if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64) 153 Builder.defineMacro("_CALL_LINUX", "1"); 154 155 // Subtarget options. 156 if (!getTriple().isOSAIX()){ 157 Builder.defineMacro("__NATURAL_ALIGNMENT__"); 158 } 159 Builder.defineMacro("__REGISTER_PREFIX__", ""); 160 161 // FIXME: Should be controlled by command line option. 162 if (LongDoubleWidth == 128) { 163 Builder.defineMacro("__LONG_DOUBLE_128__"); 164 Builder.defineMacro("__LONGDOUBLE128"); 165 if (Opts.PPCIEEELongDouble) 166 Builder.defineMacro("__LONG_DOUBLE_IEEE128__"); 167 else 168 Builder.defineMacro("__LONG_DOUBLE_IBM128__"); 169 } 170 171 // Define this for elfv2 (64-bit only) or 64-bit darwin. 172 if (ABI == "elfv2" || 173 (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64)) 174 Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); 175 176 if (ArchDefs & ArchDefineName) 177 Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); 178 if (ArchDefs & ArchDefinePpcgr) 179 Builder.defineMacro("_ARCH_PPCGR"); 180 if (ArchDefs & ArchDefinePpcsq) 181 Builder.defineMacro("_ARCH_PPCSQ"); 182 if (ArchDefs & ArchDefine440) 183 Builder.defineMacro("_ARCH_440"); 184 if (ArchDefs & ArchDefine603) 185 Builder.defineMacro("_ARCH_603"); 186 if (ArchDefs & ArchDefine604) 187 Builder.defineMacro("_ARCH_604"); 188 if (ArchDefs & ArchDefinePwr4) 189 Builder.defineMacro("_ARCH_PWR4"); 190 if (ArchDefs & ArchDefinePwr5) 191 Builder.defineMacro("_ARCH_PWR5"); 192 if (ArchDefs & ArchDefinePwr5x) 193 Builder.defineMacro("_ARCH_PWR5X"); 194 if (ArchDefs & ArchDefinePwr6) 195 Builder.defineMacro("_ARCH_PWR6"); 196 if (ArchDefs & ArchDefinePwr6x) 197 Builder.defineMacro("_ARCH_PWR6X"); 198 if (ArchDefs & ArchDefinePwr7) 199 Builder.defineMacro("_ARCH_PWR7"); 200 if (ArchDefs & ArchDefinePwr8) 201 Builder.defineMacro("_ARCH_PWR8"); 202 if (ArchDefs & ArchDefinePwr9) 203 Builder.defineMacro("_ARCH_PWR9"); 204 if (ArchDefs & ArchDefinePwr10) 205 Builder.defineMacro("_ARCH_PWR10"); 206 if (ArchDefs & ArchDefineA2) 207 Builder.defineMacro("_ARCH_A2"); 208 if (ArchDefs & ArchDefineE500) 209 Builder.defineMacro("__NO_LWSYNC__"); 210 if (ArchDefs & ArchDefineFuture) 211 Builder.defineMacro("_ARCH_PWR_FUTURE"); 212 213 if (HasAltivec) { 214 Builder.defineMacro("__VEC__", "10206"); 215 Builder.defineMacro("__ALTIVEC__"); 216 } 217 if (HasSPE) { 218 Builder.defineMacro("__SPE__"); 219 Builder.defineMacro("__NO_FPRS__"); 220 } 221 if (HasVSX) 222 Builder.defineMacro("__VSX__"); 223 if (HasP8Vector) 224 Builder.defineMacro("__POWER8_VECTOR__"); 225 if (HasP8Crypto) 226 Builder.defineMacro("__CRYPTO__"); 227 if (HasHTM) 228 Builder.defineMacro("__HTM__"); 229 if (HasFloat128) 230 Builder.defineMacro("__FLOAT128__"); 231 if (HasP9Vector) 232 Builder.defineMacro("__POWER9_VECTOR__"); 233 if (HasMMA) 234 Builder.defineMacro("__MMA__"); 235 if (HasROPProtect) 236 Builder.defineMacro("__ROP_PROTECT__"); 237 if (HasPrivileged) 238 Builder.defineMacro("__PRIVILEGED__"); 239 if (HasP10Vector) 240 Builder.defineMacro("__POWER10_VECTOR__"); 241 if (HasPCRelativeMemops) 242 Builder.defineMacro("__PCREL__"); 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 if (PointerWidth == 64) 248 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 249 250 // We have support for the bswap intrinsics so we can define this. 251 Builder.defineMacro("__HAVE_BSWAP__", "1"); 252 253 // FIXME: The following are not yet generated here by Clang, but are 254 // generated by GCC: 255 // 256 // _SOFT_FLOAT_ 257 // __RECIP_PRECISION__ 258 // __APPLE_ALTIVEC__ 259 // __RECIP__ 260 // __RECIPF__ 261 // __RSQRTE__ 262 // __RSQRTEF__ 263 // _SOFT_DOUBLE_ 264 // __NO_LWSYNC__ 265 // __CMODEL_MEDIUM__ 266 // __CMODEL_LARGE__ 267 // _CALL_SYSV 268 // _CALL_DARWIN 269 } 270 271 // Handle explicit options being passed to the compiler here: if we've 272 // explicitly turned off vsx and turned on any of: 273 // - power8-vector 274 // - direct-move 275 // - float128 276 // - power9-vector 277 // - paired-vector-memops 278 // - mma 279 // - power10-vector 280 // then go ahead and error since the customer has expressed an incompatible 281 // set of options. 282 static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, 283 const std::vector<std::string> &FeaturesVec) { 284 285 // vsx was not explicitly turned off. 286 if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end()) 287 return true; 288 289 auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) { 290 if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) { 291 Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx"; 292 return true; 293 } 294 return false; 295 }; 296 297 bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector"); 298 Found |= FindVSXSubfeature("+direct-move", "-mdirect-move"); 299 Found |= FindVSXSubfeature("+float128", "-mfloat128"); 300 Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector"); 301 Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops"); 302 Found |= FindVSXSubfeature("+mma", "-mmma"); 303 Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector"); 304 305 // Return false if any vsx subfeatures was found. 306 return !Found; 307 } 308 309 bool PPCTargetInfo::initFeatureMap( 310 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 311 const std::vector<std::string> &FeaturesVec) const { 312 Features["altivec"] = llvm::StringSwitch<bool>(CPU) 313 .Case("7400", true) 314 .Case("g4", true) 315 .Case("7450", true) 316 .Case("g4+", true) 317 .Case("970", true) 318 .Case("g5", true) 319 .Case("pwr6", true) 320 .Case("pwr7", true) 321 .Case("pwr8", true) 322 .Case("pwr9", true) 323 .Case("ppc64", true) 324 .Case("ppc64le", true) 325 .Default(false); 326 327 Features["power9-vector"] = (CPU == "pwr9"); 328 Features["crypto"] = llvm::StringSwitch<bool>(CPU) 329 .Case("ppc64le", true) 330 .Case("pwr9", true) 331 .Case("pwr8", true) 332 .Default(false); 333 Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) 334 .Case("ppc64le", true) 335 .Case("pwr9", true) 336 .Case("pwr8", true) 337 .Default(false); 338 Features["bpermd"] = llvm::StringSwitch<bool>(CPU) 339 .Case("ppc64le", true) 340 .Case("pwr9", true) 341 .Case("pwr8", true) 342 .Case("pwr7", true) 343 .Default(false); 344 Features["extdiv"] = llvm::StringSwitch<bool>(CPU) 345 .Case("ppc64le", true) 346 .Case("pwr9", true) 347 .Case("pwr8", true) 348 .Case("pwr7", true) 349 .Default(false); 350 Features["direct-move"] = llvm::StringSwitch<bool>(CPU) 351 .Case("ppc64le", true) 352 .Case("pwr9", true) 353 .Case("pwr8", true) 354 .Default(false); 355 Features["vsx"] = llvm::StringSwitch<bool>(CPU) 356 .Case("ppc64le", true) 357 .Case("pwr9", true) 358 .Case("pwr8", true) 359 .Case("pwr7", true) 360 .Default(false); 361 Features["htm"] = llvm::StringSwitch<bool>(CPU) 362 .Case("ppc64le", true) 363 .Case("pwr9", true) 364 .Case("pwr8", true) 365 .Default(false); 366 367 // ROP Protect is off by default. 368 Features["rop-protect"] = false; 369 // Privileged instructions are off by default. 370 Features["privileged"] = false; 371 372 Features["spe"] = llvm::StringSwitch<bool>(CPU) 373 .Case("8548", true) 374 .Case("e500", true) 375 .Default(false); 376 377 // Power10 includes all the same features as Power9 plus any features specific 378 // to the Power10 core. 379 if (CPU == "pwr10" || CPU == "power10") { 380 initFeatureMap(Features, Diags, "pwr9", FeaturesVec); 381 addP10SpecificFeatures(Features); 382 } 383 384 // Future CPU should include all of the features of Power 10 as well as any 385 // additional features (yet to be determined) specific to it. 386 if (CPU == "future") { 387 initFeatureMap(Features, Diags, "pwr10", FeaturesVec); 388 addFutureSpecificFeatures(Features); 389 } 390 391 if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) 392 return false; 393 394 if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) && 395 llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) { 396 // We have __float128 on PPC but not power 9 and above. 397 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; 398 return false; 399 } 400 401 if (!(ArchDefs & ArchDefinePwr10) && 402 llvm::find(FeaturesVec, "+mma") != FeaturesVec.end()) { 403 // We have MMA on PPC but not power 10 and above. 404 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU; 405 return false; 406 } 407 408 if (!(ArchDefs & ArchDefinePwr8) && 409 llvm::find(FeaturesVec, "+rop-protect") != FeaturesVec.end()) { 410 // We can turn on ROP Protect on Power 8 and above. 411 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU; 412 return false; 413 } 414 415 if (!(ArchDefs & ArchDefinePwr8) && 416 llvm::find(FeaturesVec, "+privileged") != FeaturesVec.end()) { 417 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU; 418 return false; 419 } 420 421 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 422 } 423 424 // Add any Power10 specific features. 425 void PPCTargetInfo::addP10SpecificFeatures( 426 llvm::StringMap<bool> &Features) const { 427 Features["htm"] = false; // HTM was removed for P10. 428 Features["paired-vector-memops"] = true; 429 Features["mma"] = true; 430 Features["power10-vector"] = true; 431 Features["pcrelative-memops"] = true; 432 Features["prefix-instrs"] = true; 433 return; 434 } 435 436 // Add features specific to the "Future" CPU. 437 void PPCTargetInfo::addFutureSpecificFeatures( 438 llvm::StringMap<bool> &Features) const { 439 return; 440 } 441 442 bool PPCTargetInfo::hasFeature(StringRef Feature) const { 443 return llvm::StringSwitch<bool>(Feature) 444 .Case("powerpc", true) 445 .Case("altivec", HasAltivec) 446 .Case("vsx", HasVSX) 447 .Case("power8-vector", HasP8Vector) 448 .Case("crypto", HasP8Crypto) 449 .Case("direct-move", HasDirectMove) 450 .Case("htm", HasHTM) 451 .Case("bpermd", HasBPERMD) 452 .Case("extdiv", HasExtDiv) 453 .Case("float128", HasFloat128) 454 .Case("power9-vector", HasP9Vector) 455 .Case("paired-vector-memops", PairedVectorMemops) 456 .Case("power10-vector", HasP10Vector) 457 .Case("pcrelative-memops", HasPCRelativeMemops) 458 .Case("prefix-instrs", HasPrefixInstrs) 459 .Case("spe", HasSPE) 460 .Case("mma", HasMMA) 461 .Case("rop-protect", HasROPProtect) 462 .Case("privileged", HasPrivileged) 463 .Default(false); 464 } 465 466 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 467 StringRef Name, bool Enabled) const { 468 if (Enabled) { 469 if (Name == "efpu2") 470 Features["spe"] = true; 471 // If we're enabling any of the vsx based features then enable vsx and 472 // altivec. We'll diagnose any problems later. 473 bool FeatureHasVSX = llvm::StringSwitch<bool>(Name) 474 .Case("vsx", true) 475 .Case("direct-move", true) 476 .Case("power8-vector", true) 477 .Case("power9-vector", true) 478 .Case("paired-vector-memops", true) 479 .Case("power10-vector", true) 480 .Case("float128", true) 481 .Case("mma", true) 482 .Default(false); 483 if (FeatureHasVSX) 484 Features["vsx"] = Features["altivec"] = true; 485 if (Name == "power9-vector") 486 Features["power8-vector"] = true; 487 else if (Name == "power10-vector") 488 Features["power8-vector"] = Features["power9-vector"] = true; 489 if (Name == "pcrel") 490 Features["pcrelative-memops"] = true; 491 else if (Name == "prefixed") 492 Features["prefix-instrs"] = true; 493 else 494 Features[Name] = true; 495 } else { 496 if (Name == "spe") 497 Features["efpu2"] = false; 498 // If we're disabling altivec or vsx go ahead and disable all of the vsx 499 // features. 500 if ((Name == "altivec") || (Name == "vsx")) 501 Features["vsx"] = Features["direct-move"] = Features["power8-vector"] = 502 Features["float128"] = Features["power9-vector"] = 503 Features["paired-vector-memops"] = Features["mma"] = 504 Features["power10-vector"] = false; 505 if (Name == "power8-vector") 506 Features["power9-vector"] = Features["paired-vector-memops"] = 507 Features["mma"] = Features["power10-vector"] = false; 508 else if (Name == "power9-vector") 509 Features["paired-vector-memops"] = Features["mma"] = 510 Features["power10-vector"] = false; 511 if (Name == "pcrel") 512 Features["pcrelative-memops"] = false; 513 else if (Name == "prefixed") 514 Features["prefix-instrs"] = false; 515 else 516 Features[Name] = false; 517 } 518 } 519 520 const char *const PPCTargetInfo::GCCRegNames[] = { 521 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", 522 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", 523 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", 524 "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3", 525 "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", 526 "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", 527 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", 528 "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3", 529 "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3", 530 "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", 531 "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", 532 "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", 533 "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp" 534 }; 535 536 ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { 537 return llvm::makeArrayRef(GCCRegNames); 538 } 539 540 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { 541 // While some of these aliases do map to different registers 542 // they still share the same register name. 543 {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, 544 {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, 545 {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, 546 {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, 547 {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, 548 {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, 549 {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, 550 {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, 551 {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, 552 {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, 553 {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, 554 {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, 555 {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, 556 {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, 557 {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, 558 {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, 559 {{"cc"}, "cr0"}, 560 }; 561 562 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { 563 return llvm::makeArrayRef(GCCRegAliases); 564 } 565 566 // PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers". 567 // vs0 ~ vs31 is mapping to 32 - 63, 568 // vs32 ~ vs63 is mapping to 77 - 108. 569 const TargetInfo::AddlRegName GCCAddlRegNames[] = { 570 // Table of additional register names to use in user input. 571 {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35}, 572 {{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39}, 573 {{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43}, 574 {{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47}, 575 {{"vs16"}, 48}, {{"vs17"}, 49}, {{"vs18"}, 50}, {{"vs19"}, 51}, 576 {{"vs20"}, 52}, {{"vs21"}, 53}, {{"vs22"}, 54}, {{"vs23"}, 55}, 577 {{"vs24"}, 56}, {{"vs25"}, 57}, {{"vs26"}, 58}, {{"vs27"}, 59}, 578 {{"vs28"}, 60}, {{"vs29"}, 61}, {{"vs30"}, 62}, {{"vs31"}, 63}, 579 {{"vs32"}, 77}, {{"vs33"}, 78}, {{"vs34"}, 79}, {{"vs35"}, 80}, 580 {{"vs36"}, 81}, {{"vs37"}, 82}, {{"vs38"}, 83}, {{"vs39"}, 84}, 581 {{"vs40"}, 85}, {{"vs41"}, 86}, {{"vs42"}, 87}, {{"vs43"}, 88}, 582 {{"vs44"}, 89}, {{"vs45"}, 90}, {{"vs46"}, 91}, {{"vs47"}, 92}, 583 {{"vs48"}, 93}, {{"vs49"}, 94}, {{"vs50"}, 95}, {{"vs51"}, 96}, 584 {{"vs52"}, 97}, {{"vs53"}, 98}, {{"vs54"}, 99}, {{"vs55"}, 100}, 585 {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104}, 586 {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108}, 587 }; 588 589 ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { 590 if (ABI == "elfv2") 591 return llvm::makeArrayRef(GCCAddlRegNames); 592 else 593 return TargetInfo::getGCCAddlRegNames(); 594 } 595 596 static constexpr llvm::StringLiteral ValidCPUNames[] = { 597 {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, 598 {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, 599 {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, 600 {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"}, 601 {"g5"}, {"a2"}, {"e500"}, {"e500mc"}, {"e5500"}, 602 {"power3"}, {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, 603 {"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, 604 {"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, 605 {"pwr8"}, {"power9"}, {"pwr9"}, {"power10"}, {"pwr10"}, 606 {"powerpc"}, {"ppc"}, {"ppc32"}, {"powerpc64"}, {"ppc64"}, 607 {"powerpc64le"}, {"ppc64le"}, {"future"}}; 608 609 bool PPCTargetInfo::isValidCPUName(StringRef Name) const { 610 return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); 611 } 612 613 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 614 Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); 615 } 616 617 void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { 618 if (HasAltivec) 619 Opts.AltiVec = 1; 620 TargetInfo::adjust(Diags, Opts); 621 if (LongDoubleFormat != &llvm::APFloat::IEEEdouble()) 622 LongDoubleFormat = Opts.PPCIEEELongDouble 623 ? &llvm::APFloat::IEEEquad() 624 : &llvm::APFloat::PPCDoubleDouble(); 625 Opts.IEEE128 = 1; 626 } 627 628 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { 629 return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin - 630 Builtin::FirstTSBuiltin); 631 } 632