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