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