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