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