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