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