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