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