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