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