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