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