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