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