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