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