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