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