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