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