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