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