Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
35266 views
//===--- PPC.cpp - Implement PPC target feature support -------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements PPC TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#include "PPC.h"13#include "clang/Basic/Diagnostic.h"14#include "clang/Basic/MacroBuilder.h"15#include "clang/Basic/TargetBuiltins.h"1617using namespace clang;18using namespace clang::targets;1920static constexpr Builtin::Info BuiltinInfo[] = {21#define BUILTIN(ID, TYPE, ATTRS) \22{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},23#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \24{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},25#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \26{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},27#include "clang/Basic/BuiltinsPPC.def"28};2930/// handleTargetFeatures - Perform initialization based on the user31/// configured set of features.32bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,33DiagnosticsEngine &Diags) {34FloatABI = HardFloat;35for (const auto &Feature : Features) {36if (Feature == "+altivec") {37HasAltivec = true;38} else if (Feature == "+vsx") {39HasVSX = true;40} else if (Feature == "+crbits") {41UseCRBits = true;42} else if (Feature == "+bpermd") {43HasBPERMD = true;44} else if (Feature == "+extdiv") {45HasExtDiv = true;46} else if (Feature == "+power8-vector") {47HasP8Vector = true;48} else if (Feature == "+crypto") {49HasP8Crypto = true;50} else if (Feature == "+direct-move") {51HasDirectMove = true;52} else if (Feature == "+htm") {53HasHTM = true;54} else if (Feature == "+float128") {55HasFloat128 = !getTriple().isOSAIX();56} else if (Feature == "+power9-vector") {57HasP9Vector = true;58} else if (Feature == "+power10-vector") {59HasP10Vector = true;60} else if (Feature == "+pcrelative-memops") {61HasPCRelativeMemops = true;62} else if (Feature == "+prefix-instrs") {63HasPrefixInstrs = true;64} else if (Feature == "+spe" || Feature == "+efpu2") {65HasStrictFP = false;66HasSPE = true;67LongDoubleWidth = LongDoubleAlign = 64;68LongDoubleFormat = &llvm::APFloat::IEEEdouble();69} else if (Feature == "-hard-float") {70FloatABI = SoftFloat;71} else if (Feature == "+paired-vector-memops") {72PairedVectorMemops = true;73} else if (Feature == "+mma") {74HasMMA = true;75} else if (Feature == "+rop-protect") {76HasROPProtect = true;77} else if (Feature == "+privileged") {78HasPrivileged = true;79} else if (Feature == "+aix-small-local-exec-tls") {80HasAIXSmallLocalExecTLS = true;81} else if (Feature == "+aix-small-local-dynamic-tls") {82HasAIXSmallLocalDynamicTLS = true;83} else if (Feature == "+isa-v206-instructions") {84IsISA2_06 = true;85} else if (Feature == "+isa-v207-instructions") {86IsISA2_07 = true;87} else if (Feature == "+isa-v30-instructions") {88IsISA3_0 = true;89} else if (Feature == "+isa-v31-instructions") {90IsISA3_1 = true;91} else if (Feature == "+quadword-atomics") {92HasQuadwordAtomics = true;93} else if (Feature == "+aix-shared-lib-tls-model-opt") {94HasAIXShLibTLSModelOpt = true;95} else if (Feature == "+longcall") {96UseLongCalls = true;97}98// TODO: Finish this list and add an assert that we've handled them99// all.100}101102return true;103}104105static void defineXLCompatMacros(MacroBuilder &Builder) {106Builder.defineMacro("__popcntb", "__builtin_ppc_popcntb");107Builder.defineMacro("__poppar4", "__builtin_ppc_poppar4");108Builder.defineMacro("__poppar8", "__builtin_ppc_poppar8");109Builder.defineMacro("__eieio", "__builtin_ppc_eieio");110Builder.defineMacro("__iospace_eieio", "__builtin_ppc_iospace_eieio");111Builder.defineMacro("__isync", "__builtin_ppc_isync");112Builder.defineMacro("__lwsync", "__builtin_ppc_lwsync");113Builder.defineMacro("__iospace_lwsync", "__builtin_ppc_iospace_lwsync");114Builder.defineMacro("__sync", "__builtin_ppc_sync");115Builder.defineMacro("__iospace_sync", "__builtin_ppc_iospace_sync");116Builder.defineMacro("__dcbfl", "__builtin_ppc_dcbfl");117Builder.defineMacro("__dcbflp", "__builtin_ppc_dcbflp");118Builder.defineMacro("__dcbst", "__builtin_ppc_dcbst");119Builder.defineMacro("__dcbt", "__builtin_ppc_dcbt");120Builder.defineMacro("__dcbtst", "__builtin_ppc_dcbtst");121Builder.defineMacro("__dcbz", "__builtin_ppc_dcbz");122Builder.defineMacro("__icbt", "__builtin_ppc_icbt");123Builder.defineMacro("__compare_and_swap", "__builtin_ppc_compare_and_swap");124Builder.defineMacro("__compare_and_swaplp",125"__builtin_ppc_compare_and_swaplp");126Builder.defineMacro("__fetch_and_add", "__builtin_ppc_fetch_and_add");127Builder.defineMacro("__fetch_and_addlp", "__builtin_ppc_fetch_and_addlp");128Builder.defineMacro("__fetch_and_and", "__builtin_ppc_fetch_and_and");129Builder.defineMacro("__fetch_and_andlp", "__builtin_ppc_fetch_and_andlp");130Builder.defineMacro("__fetch_and_or", "__builtin_ppc_fetch_and_or");131Builder.defineMacro("__fetch_and_orlp", "__builtin_ppc_fetch_and_orlp");132Builder.defineMacro("__fetch_and_swap", "__builtin_ppc_fetch_and_swap");133Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_and_swaplp");134Builder.defineMacro("__ldarx", "__builtin_ppc_ldarx");135Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");136Builder.defineMacro("__lharx", "__builtin_ppc_lharx");137Builder.defineMacro("__lbarx", "__builtin_ppc_lbarx");138Builder.defineMacro("__stfiw", "__builtin_ppc_stfiw");139Builder.defineMacro("__stdcx", "__builtin_ppc_stdcx");140Builder.defineMacro("__stwcx", "__builtin_ppc_stwcx");141Builder.defineMacro("__sthcx", "__builtin_ppc_sthcx");142Builder.defineMacro("__stbcx", "__builtin_ppc_stbcx");143Builder.defineMacro("__tdw", "__builtin_ppc_tdw");144Builder.defineMacro("__tw", "__builtin_ppc_tw");145Builder.defineMacro("__trap", "__builtin_ppc_trap");146Builder.defineMacro("__trapd", "__builtin_ppc_trapd");147Builder.defineMacro("__fcfid", "__builtin_ppc_fcfid");148Builder.defineMacro("__fcfud", "__builtin_ppc_fcfud");149Builder.defineMacro("__fctid", "__builtin_ppc_fctid");150Builder.defineMacro("__fctidz", "__builtin_ppc_fctidz");151Builder.defineMacro("__fctiw", "__builtin_ppc_fctiw");152Builder.defineMacro("__fctiwz", "__builtin_ppc_fctiwz");153Builder.defineMacro("__fctudz", "__builtin_ppc_fctudz");154Builder.defineMacro("__fctuwz", "__builtin_ppc_fctuwz");155Builder.defineMacro("__cmpeqb", "__builtin_ppc_cmpeqb");156Builder.defineMacro("__cmprb", "__builtin_ppc_cmprb");157Builder.defineMacro("__setb", "__builtin_ppc_setb");158Builder.defineMacro("__cmpb", "__builtin_ppc_cmpb");159Builder.defineMacro("__mulhd", "__builtin_ppc_mulhd");160Builder.defineMacro("__mulhdu", "__builtin_ppc_mulhdu");161Builder.defineMacro("__mulhw", "__builtin_ppc_mulhw");162Builder.defineMacro("__mulhwu", "__builtin_ppc_mulhwu");163Builder.defineMacro("__maddhd", "__builtin_ppc_maddhd");164Builder.defineMacro("__maddhdu", "__builtin_ppc_maddhdu");165Builder.defineMacro("__maddld", "__builtin_ppc_maddld");166Builder.defineMacro("__rlwnm", "__builtin_ppc_rlwnm");167Builder.defineMacro("__rlwimi", "__builtin_ppc_rlwimi");168Builder.defineMacro("__rldimi", "__builtin_ppc_rldimi");169Builder.defineMacro("__load2r", "__builtin_ppc_load2r");170Builder.defineMacro("__load4r", "__builtin_ppc_load4r");171Builder.defineMacro("__load8r", "__builtin_ppc_load8r");172Builder.defineMacro("__store2r", "__builtin_ppc_store2r");173Builder.defineMacro("__store4r", "__builtin_ppc_store4r");174Builder.defineMacro("__store8r", "__builtin_ppc_store8r");175Builder.defineMacro("__extract_exp", "__builtin_ppc_extract_exp");176Builder.defineMacro("__extract_sig", "__builtin_ppc_extract_sig");177Builder.defineMacro("__mtfsb0", "__builtin_ppc_mtfsb0");178Builder.defineMacro("__mtfsb1", "__builtin_ppc_mtfsb1");179Builder.defineMacro("__mtfsf", "__builtin_ppc_mtfsf");180Builder.defineMacro("__mtfsfi", "__builtin_ppc_mtfsfi");181Builder.defineMacro("__insert_exp", "__builtin_ppc_insert_exp");182Builder.defineMacro("__fmsub", "__builtin_ppc_fmsub");183Builder.defineMacro("__fmsubs", "__builtin_ppc_fmsubs");184Builder.defineMacro("__fnmadd", "__builtin_ppc_fnmadd");185Builder.defineMacro("__fnmadds", "__builtin_ppc_fnmadds");186Builder.defineMacro("__fnmsub", "__builtin_ppc_fnmsub");187Builder.defineMacro("__fnmsubs", "__builtin_ppc_fnmsubs");188Builder.defineMacro("__fre", "__builtin_ppc_fre");189Builder.defineMacro("__fres", "__builtin_ppc_fres");190Builder.defineMacro("__swdiv_nochk", "__builtin_ppc_swdiv_nochk");191Builder.defineMacro("__swdivs_nochk", "__builtin_ppc_swdivs_nochk");192Builder.defineMacro("__alloca", "__builtin_alloca");193Builder.defineMacro("__vcipher", "__builtin_altivec_crypto_vcipher");194Builder.defineMacro("__vcipherlast", "__builtin_altivec_crypto_vcipherlast");195Builder.defineMacro("__vncipher", "__builtin_altivec_crypto_vncipher");196Builder.defineMacro("__vncipherlast",197"__builtin_altivec_crypto_vncipherlast");198Builder.defineMacro("__vpermxor", "__builtin_altivec_crypto_vpermxor");199Builder.defineMacro("__vpmsumb", "__builtin_altivec_crypto_vpmsumb");200Builder.defineMacro("__vpmsumd", "__builtin_altivec_crypto_vpmsumd");201Builder.defineMacro("__vpmsumh", "__builtin_altivec_crypto_vpmsumh");202Builder.defineMacro("__vpmsumw", "__builtin_altivec_crypto_vpmsumw");203Builder.defineMacro("__divde", "__builtin_divde");204Builder.defineMacro("__divwe", "__builtin_divwe");205Builder.defineMacro("__divdeu", "__builtin_divdeu");206Builder.defineMacro("__divweu", "__builtin_divweu");207Builder.defineMacro("__alignx", "__builtin_ppc_alignx");208Builder.defineMacro("__bcopy", "bcopy");209Builder.defineMacro("__bpermd", "__builtin_bpermd");210Builder.defineMacro("__cntlz4", "__builtin_clz");211Builder.defineMacro("__cntlz8", "__builtin_clzll");212Builder.defineMacro("__cmplx", "__builtin_complex");213Builder.defineMacro("__cmplxf", "__builtin_complex");214Builder.defineMacro("__cnttz4", "__builtin_ctz");215Builder.defineMacro("__cnttz8", "__builtin_ctzll");216Builder.defineMacro("__darn", "__builtin_darn");217Builder.defineMacro("__darn_32", "__builtin_darn_32");218Builder.defineMacro("__darn_raw", "__builtin_darn_raw");219Builder.defineMacro("__dcbf", "__builtin_dcbf");220Builder.defineMacro("__fence", "__builtin_ppc_fence");221Builder.defineMacro("__fmadd", "__builtin_fma");222Builder.defineMacro("__fmadds", "__builtin_fmaf");223Builder.defineMacro("__abs", "__builtin_abs");224Builder.defineMacro("__labs", "__builtin_labs");225Builder.defineMacro("__llabs", "__builtin_llabs");226Builder.defineMacro("__popcnt4", "__builtin_popcount");227Builder.defineMacro("__popcnt8", "__builtin_popcountll");228Builder.defineMacro("__readflm", "__builtin_readflm");229Builder.defineMacro("__rotatel4", "__builtin_rotateleft32");230Builder.defineMacro("__rotatel8", "__builtin_rotateleft64");231Builder.defineMacro("__rdlam", "__builtin_ppc_rdlam");232Builder.defineMacro("__setflm", "__builtin_setflm");233Builder.defineMacro("__setrnd", "__builtin_setrnd");234Builder.defineMacro("__dcbtstt", "__builtin_ppc_dcbtstt");235Builder.defineMacro("__dcbtt", "__builtin_ppc_dcbtt");236Builder.defineMacro("__mftbu", "__builtin_ppc_mftbu");237Builder.defineMacro("__mfmsr", "__builtin_ppc_mfmsr");238Builder.defineMacro("__mtmsr", "__builtin_ppc_mtmsr");239Builder.defineMacro("__mfspr", "__builtin_ppc_mfspr");240Builder.defineMacro("__mtspr", "__builtin_ppc_mtspr");241Builder.defineMacro("__fric", "__builtin_ppc_fric");242Builder.defineMacro("__frim", "__builtin_ppc_frim");243Builder.defineMacro("__frims", "__builtin_ppc_frims");244Builder.defineMacro("__frin", "__builtin_ppc_frin");245Builder.defineMacro("__frins", "__builtin_ppc_frins");246Builder.defineMacro("__frip", "__builtin_ppc_frip");247Builder.defineMacro("__frips", "__builtin_ppc_frips");248Builder.defineMacro("__friz", "__builtin_ppc_friz");249Builder.defineMacro("__frizs", "__builtin_ppc_frizs");250Builder.defineMacro("__fsel", "__builtin_ppc_fsel");251Builder.defineMacro("__fsels", "__builtin_ppc_fsels");252Builder.defineMacro("__frsqrte", "__builtin_ppc_frsqrte");253Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes");254Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt");255Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");256Builder.defineMacro("__addex", "__builtin_ppc_addex");257Builder.defineMacro("__cmplxl", "__builtin_complex");258Builder.defineMacro("__compare_exp_uo", "__builtin_ppc_compare_exp_uo");259Builder.defineMacro("__compare_exp_lt", "__builtin_ppc_compare_exp_lt");260Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt");261Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq");262Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");263Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv");264Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs");265Builder.defineMacro("__fnabs", "__builtin_ppc_fnabs");266Builder.defineMacro("__fnabss", "__builtin_ppc_fnabss");267Builder.defineMacro("__builtin_maxfe", "__builtin_ppc_maxfe");268Builder.defineMacro("__builtin_maxfl", "__builtin_ppc_maxfl");269Builder.defineMacro("__builtin_maxfs", "__builtin_ppc_maxfs");270Builder.defineMacro("__builtin_minfe", "__builtin_ppc_minfe");271Builder.defineMacro("__builtin_minfl", "__builtin_ppc_minfl");272Builder.defineMacro("__builtin_minfs", "__builtin_ppc_minfs");273Builder.defineMacro("__builtin_mffs", "__builtin_ppc_mffs");274Builder.defineMacro("__builtin_mffsl", "__builtin_ppc_mffsl");275Builder.defineMacro("__builtin_mtfsf", "__builtin_ppc_mtfsf");276Builder.defineMacro("__builtin_set_fpscr_rn", "__builtin_ppc_set_fpscr_rn");277}278279/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific280/// #defines that are not tied to a specific subtarget.281void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,282MacroBuilder &Builder) const {283284// We define the XLC compatibility macros only on AIX and Linux since XLC285// was never available on any other platforms.286if (getTriple().isOSAIX() || getTriple().isOSLinux())287defineXLCompatMacros(Builder);288289// Target identification.290Builder.defineMacro("__ppc__");291Builder.defineMacro("__PPC__");292Builder.defineMacro("_ARCH_PPC");293Builder.defineMacro("__powerpc__");294Builder.defineMacro("__POWERPC__");295if (PointerWidth == 64) {296Builder.defineMacro("_ARCH_PPC64");297Builder.defineMacro("__powerpc64__");298Builder.defineMacro("__PPC64__");299} else if (getTriple().isOSAIX()) {300// The XL compilers on AIX define _ARCH_PPC64 for both 32 and 64-bit modes.301Builder.defineMacro("_ARCH_PPC64");302}303if (getTriple().isOSAIX()) {304Builder.defineMacro("__THW_PPC__");305// Define __PPC and __powerpc for AIX XL C/C++ compatibility306Builder.defineMacro("__PPC");307Builder.defineMacro("__powerpc");308}309310// Target properties.311if (getTriple().getArch() == llvm::Triple::ppc64le ||312getTriple().getArch() == llvm::Triple::ppcle) {313Builder.defineMacro("_LITTLE_ENDIAN");314} else {315if (!getTriple().isOSNetBSD() &&316!getTriple().isOSOpenBSD())317Builder.defineMacro("_BIG_ENDIAN");318}319320// ABI options.321if (ABI == "elfv1")322Builder.defineMacro("_CALL_ELF", "1");323if (ABI == "elfv2")324Builder.defineMacro("_CALL_ELF", "2");325326// This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but327// our support post-dates this and it should work on all 64-bit ppc linux328// platforms. It is guaranteed to work on all elfv2 platforms.329if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)330Builder.defineMacro("_CALL_LINUX", "1");331332// Subtarget options.333if (!getTriple().isOSAIX()){334Builder.defineMacro("__NATURAL_ALIGNMENT__");335}336Builder.defineMacro("__REGISTER_PREFIX__", "");337338// FIXME: Should be controlled by command line option.339if (LongDoubleWidth == 128) {340Builder.defineMacro("__LONG_DOUBLE_128__");341Builder.defineMacro("__LONGDOUBLE128");342if (Opts.PPCIEEELongDouble)343Builder.defineMacro("__LONG_DOUBLE_IEEE128__");344else345Builder.defineMacro("__LONG_DOUBLE_IBM128__");346}347348if (getTriple().isOSAIX() && Opts.LongDoubleSize == 64) {349assert(LongDoubleWidth == 64);350Builder.defineMacro("__LONGDOUBLE64");351}352353// Define this for elfv2 (64-bit only).354if (ABI == "elfv2")355Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");356357if (ArchDefs & ArchDefineName)358Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));359if (ArchDefs & ArchDefinePpcgr)360Builder.defineMacro("_ARCH_PPCGR");361if (ArchDefs & ArchDefinePpcsq)362Builder.defineMacro("_ARCH_PPCSQ");363if (ArchDefs & ArchDefine440)364Builder.defineMacro("_ARCH_440");365if (ArchDefs & ArchDefine603)366Builder.defineMacro("_ARCH_603");367if (ArchDefs & ArchDefine604)368Builder.defineMacro("_ARCH_604");369if (ArchDefs & ArchDefinePwr4)370Builder.defineMacro("_ARCH_PWR4");371if (ArchDefs & ArchDefinePwr5)372Builder.defineMacro("_ARCH_PWR5");373if (ArchDefs & ArchDefinePwr5x)374Builder.defineMacro("_ARCH_PWR5X");375if (ArchDefs & ArchDefinePwr6)376Builder.defineMacro("_ARCH_PWR6");377if (ArchDefs & ArchDefinePwr6x)378Builder.defineMacro("_ARCH_PWR6X");379if (ArchDefs & ArchDefinePwr7)380Builder.defineMacro("_ARCH_PWR7");381if (ArchDefs & ArchDefinePwr8)382Builder.defineMacro("_ARCH_PWR8");383if (ArchDefs & ArchDefinePwr9)384Builder.defineMacro("_ARCH_PWR9");385if (ArchDefs & ArchDefinePwr10)386Builder.defineMacro("_ARCH_PWR10");387if (ArchDefs & ArchDefinePwr11)388Builder.defineMacro("_ARCH_PWR11");389if (ArchDefs & ArchDefineA2)390Builder.defineMacro("_ARCH_A2");391if (ArchDefs & ArchDefineE500)392Builder.defineMacro("__NO_LWSYNC__");393if (ArchDefs & ArchDefineFuture)394Builder.defineMacro("_ARCH_PWR_FUTURE");395396if (HasAltivec) {397Builder.defineMacro("__VEC__", "10206");398Builder.defineMacro("__ALTIVEC__");399}400if (HasSPE) {401Builder.defineMacro("__SPE__");402Builder.defineMacro("__NO_FPRS__");403}404if (HasVSX)405Builder.defineMacro("__VSX__");406if (HasP8Vector)407Builder.defineMacro("__POWER8_VECTOR__");408if (HasP8Crypto)409Builder.defineMacro("__CRYPTO__");410if (HasHTM)411Builder.defineMacro("__HTM__");412if (HasFloat128)413Builder.defineMacro("__FLOAT128__");414if (HasP9Vector)415Builder.defineMacro("__POWER9_VECTOR__");416if (HasMMA)417Builder.defineMacro("__MMA__");418if (HasROPProtect)419Builder.defineMacro("__ROP_PROTECT__");420if (HasP10Vector)421Builder.defineMacro("__POWER10_VECTOR__");422if (HasPCRelativeMemops)423Builder.defineMacro("__PCREL__");424425Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");426Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");427Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");428if (PointerWidth == 64)429Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");430431// We have support for the bswap intrinsics so we can define this.432Builder.defineMacro("__HAVE_BSWAP__", "1");433434// FIXME: The following are not yet generated here by Clang, but are435// generated by GCC:436//437// _SOFT_FLOAT_438// __RECIP_PRECISION__439// __APPLE_ALTIVEC__440// __RECIP__441// __RECIPF__442// __RSQRTE__443// __RSQRTEF__444// _SOFT_DOUBLE_445// __NO_LWSYNC__446// __CMODEL_MEDIUM__447// __CMODEL_LARGE__448// _CALL_SYSV449// _CALL_DARWIN450}451452// Handle explicit options being passed to the compiler here:453// - if we've explicitly turned off vsx and turned on any of:454// - power8-vector455// - direct-move456// - float128457// - power9-vector458// - paired-vector-memops459// - mma460// - power10-vector461// - if we've explicitly turned on vsx and turned off altivec.462// - if we've explicitly turned off hard-float and turned on altivec.463// then go ahead and error since the customer has expressed an incompatible464// set of options.465static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,466const std::vector<std::string> &FeaturesVec) {467// Cannot allow soft-float with Altivec.468if (llvm::is_contained(FeaturesVec, "-hard-float") &&469llvm::is_contained(FeaturesVec, "+altivec")) {470Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float"471<< "-maltivec";472return false;473}474475// Cannot allow soft-float with VSX.476if (llvm::is_contained(FeaturesVec, "-hard-float") &&477llvm::is_contained(FeaturesVec, "+vsx")) {478Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float"479<< "-mvsx";480return false;481}482483// Cannot allow VSX with no Altivec.484if (llvm::is_contained(FeaturesVec, "+vsx") &&485llvm::is_contained(FeaturesVec, "-altivec")) {486Diags.Report(diag::err_opt_not_valid_with_opt) << "-mvsx"487<< "-mno-altivec";488return false;489}490491// vsx was not explicitly turned off.492if (!llvm::is_contained(FeaturesVec, "-vsx"))493return true;494495auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) {496if (llvm::is_contained(FeaturesVec, Feature)) {497Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx";498return true;499}500return false;501};502503bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector");504Found |= FindVSXSubfeature("+direct-move", "-mdirect-move");505Found |= FindVSXSubfeature("+float128", "-mfloat128");506Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector");507Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops");508Found |= FindVSXSubfeature("+mma", "-mmma");509Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector");510511// Return false if any vsx subfeatures was found.512return !Found;513}514515bool PPCTargetInfo::initFeatureMap(516llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,517const std::vector<std::string> &FeaturesVec) const {518Features["altivec"] = llvm::StringSwitch<bool>(CPU)519.Case("7400", true)520.Case("g4", true)521.Case("7450", true)522.Case("g4+", true)523.Case("970", true)524.Case("g5", true)525.Case("pwr6", true)526.Case("pwr7", true)527.Case("pwr8", true)528.Case("pwr9", true)529.Case("ppc64", true)530.Case("ppc64le", true)531.Default(false);532533Features["power9-vector"] = (CPU == "pwr9");534Features["crypto"] = llvm::StringSwitch<bool>(CPU)535.Case("ppc64le", true)536.Case("pwr9", true)537.Case("pwr8", true)538.Default(false);539Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)540.Case("ppc64le", true)541.Case("pwr9", true)542.Case("pwr8", true)543.Default(false);544Features["bpermd"] = llvm::StringSwitch<bool>(CPU)545.Case("ppc64le", true)546.Case("pwr9", true)547.Case("pwr8", true)548.Case("pwr7", true)549.Default(false);550Features["extdiv"] = llvm::StringSwitch<bool>(CPU)551.Case("ppc64le", true)552.Case("pwr9", true)553.Case("pwr8", true)554.Case("pwr7", true)555.Default(false);556Features["direct-move"] = llvm::StringSwitch<bool>(CPU)557.Case("ppc64le", true)558.Case("pwr9", true)559.Case("pwr8", true)560.Default(false);561Features["crbits"] = llvm::StringSwitch<bool>(CPU)562.Case("ppc64le", true)563.Case("pwr9", true)564.Case("pwr8", true)565.Default(false);566Features["vsx"] = llvm::StringSwitch<bool>(CPU)567.Case("ppc64le", true)568.Case("pwr9", true)569.Case("pwr8", true)570.Case("pwr7", true)571.Default(false);572Features["htm"] = llvm::StringSwitch<bool>(CPU)573.Case("ppc64le", true)574.Case("pwr9", true)575.Case("pwr8", true)576.Default(false);577578// ROP Protect is off by default.579Features["rop-protect"] = false;580// Privileged instructions are off by default.581Features["privileged"] = false;582583// The code generated by the -maix-small-local-[exec|dynamic]-tls option is584// turned off by default.585Features["aix-small-local-exec-tls"] = false;586Features["aix-small-local-dynamic-tls"] = false;587588// Turn off TLS model opt by default.589Features["aix-shared-lib-tls-model-opt"] = false;590591Features["spe"] = llvm::StringSwitch<bool>(CPU)592.Case("8548", true)593.Case("e500", true)594.Default(false);595596Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU)597.Case("ppc64le", true)598.Case("pwr9", true)599.Case("pwr8", true)600.Case("pwr7", true)601.Case("a2", true)602.Default(false);603604Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU)605.Case("ppc64le", true)606.Case("pwr9", true)607.Case("pwr8", true)608.Default(false);609610Features["isa-v30-instructions"] =611llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false);612613Features["quadword-atomics"] =614getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU)615.Case("pwr9", true)616.Case("pwr8", true)617.Default(false);618619// Power10 includes all the same features as Power9 plus any features specific620// to the Power10 core.621if (CPU == "pwr10" || CPU == "power10") {622initFeatureMap(Features, Diags, "pwr9", FeaturesVec);623addP10SpecificFeatures(Features);624}625626// Power11 includes all the same features as Power10 plus any features627// specific to the Power11 core.628if (CPU == "pwr11" || CPU == "power11") {629initFeatureMap(Features, Diags, "pwr10", FeaturesVec);630addP11SpecificFeatures(Features);631}632633// Future CPU should include all of the features of Power 11 as well as any634// additional features (yet to be determined) specific to it.635if (CPU == "future") {636initFeatureMap(Features, Diags, "pwr11", FeaturesVec);637addFutureSpecificFeatures(Features);638}639640if (!ppcUserFeaturesCheck(Diags, FeaturesVec))641return false;642643if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) &&644llvm::is_contained(FeaturesVec, "+float128")) {645// We have __float128 on PPC but not pre-VSX targets.646Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;647return false;648}649650if (!(ArchDefs & ArchDefinePwr10)) {651if (llvm::is_contained(FeaturesVec, "+mma")) {652// MMA operations are not available pre-Power10.653Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;654return false;655}656if (llvm::is_contained(FeaturesVec, "+pcrel")) {657// PC-Relative instructions are not available pre-Power10,658// and these instructions also require prefixed instructions support.659Diags.Report(diag::err_opt_not_valid_without_opt)660<< "-mpcrel"661<< "-mcpu=pwr10 -mprefixed";662return false;663}664if (llvm::is_contained(FeaturesVec, "+prefixed")) {665// Prefixed instructions are not available pre-Power10.666Diags.Report(diag::err_opt_not_valid_without_opt) << "-mprefixed"667<< "-mcpu=pwr10";668return false;669}670if (llvm::is_contained(FeaturesVec, "+paired-vector-memops")) {671// Paired vector memops are not available pre-Power10.672Diags.Report(diag::err_opt_not_valid_without_opt)673<< "-mpaired-vector-memops"674<< "-mcpu=pwr10";675return false;676}677}678679if (!(ArchDefs & ArchDefinePwr8) &&680llvm::is_contained(FeaturesVec, "+rop-protect")) {681// We can turn on ROP Protect on Power 8 and above.682Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU;683return false;684}685686if (!(ArchDefs & ArchDefinePwr8) &&687llvm::is_contained(FeaturesVec, "+privileged")) {688Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU;689return false;690}691692return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);693}694695// Add any Power10 specific features.696void PPCTargetInfo::addP10SpecificFeatures(697llvm::StringMap<bool> &Features) const {698Features["htm"] = false; // HTM was removed for P10.699Features["paired-vector-memops"] = true;700Features["mma"] = true;701Features["power10-vector"] = true;702Features["pcrelative-memops"] = true;703Features["prefix-instrs"] = true;704Features["isa-v31-instructions"] = true;705}706707// Add any Power11 specific features.708void PPCTargetInfo::addP11SpecificFeatures(709llvm::StringMap<bool> &Features) const {}710711// Add features specific to the "Future" CPU.712void PPCTargetInfo::addFutureSpecificFeatures(713llvm::StringMap<bool> &Features) const {}714715bool PPCTargetInfo::hasFeature(StringRef Feature) const {716return llvm::StringSwitch<bool>(Feature)717.Case("powerpc", true)718.Case("altivec", HasAltivec)719.Case("vsx", HasVSX)720.Case("crbits", UseCRBits)721.Case("power8-vector", HasP8Vector)722.Case("crypto", HasP8Crypto)723.Case("direct-move", HasDirectMove)724.Case("htm", HasHTM)725.Case("bpermd", HasBPERMD)726.Case("extdiv", HasExtDiv)727.Case("float128", HasFloat128)728.Case("power9-vector", HasP9Vector)729.Case("paired-vector-memops", PairedVectorMemops)730.Case("power10-vector", HasP10Vector)731.Case("pcrelative-memops", HasPCRelativeMemops)732.Case("prefix-instrs", HasPrefixInstrs)733.Case("spe", HasSPE)734.Case("mma", HasMMA)735.Case("rop-protect", HasROPProtect)736.Case("privileged", HasPrivileged)737.Case("aix-small-local-exec-tls", HasAIXSmallLocalExecTLS)738.Case("aix-small-local-dynamic-tls", HasAIXSmallLocalDynamicTLS)739.Case("isa-v206-instructions", IsISA2_06)740.Case("isa-v207-instructions", IsISA2_07)741.Case("isa-v30-instructions", IsISA3_0)742.Case("isa-v31-instructions", IsISA3_1)743.Case("quadword-atomics", HasQuadwordAtomics)744.Case("aix-shared-lib-tls-model-opt", HasAIXShLibTLSModelOpt)745.Case("longcall", UseLongCalls)746.Default(false);747}748749void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,750StringRef Name, bool Enabled) const {751if (Enabled) {752if (Name == "efpu2")753Features["spe"] = true;754// If we're enabling any of the vsx based features then enable vsx and755// altivec. We'll diagnose any problems later.756bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)757.Case("vsx", true)758.Case("direct-move", true)759.Case("power8-vector", true)760.Case("power9-vector", true)761.Case("paired-vector-memops", true)762.Case("power10-vector", true)763.Case("float128", true)764.Case("mma", true)765.Default(false);766if (FeatureHasVSX)767Features["vsx"] = Features["altivec"] = true;768if (Name == "power9-vector")769Features["power8-vector"] = true;770else if (Name == "power10-vector")771Features["power8-vector"] = Features["power9-vector"] = true;772if (Name == "pcrel")773Features["pcrelative-memops"] = true;774else if (Name == "prefixed")775Features["prefix-instrs"] = true;776else777Features[Name] = true;778} else {779if (Name == "spe")780Features["efpu2"] = false;781// If we're disabling altivec or vsx go ahead and disable all of the vsx782// features.783if ((Name == "altivec") || (Name == "vsx"))784Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =785Features["float128"] = Features["power9-vector"] =786Features["paired-vector-memops"] = Features["mma"] =787Features["power10-vector"] = false;788if (Name == "power8-vector")789Features["power9-vector"] = Features["paired-vector-memops"] =790Features["mma"] = Features["power10-vector"] = false;791else if (Name == "power9-vector")792Features["paired-vector-memops"] = Features["mma"] =793Features["power10-vector"] = false;794if (Name == "pcrel")795Features["pcrelative-memops"] = false;796else if (Name == "prefixed")797Features["prefix-instrs"] = false;798else799Features[Name] = false;800}801}802803// Make sure that registers are added in the correct array index which should be804// the DWARF number for PPC registers.805const char *const PPCTargetInfo::GCCRegNames[] = {806"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",807"r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",808"r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",809"r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3",810"f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",811"f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",812"f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",813"f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3",814"cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3",815"v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12",816"v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",817"v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30",818"v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"819};820821ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {822return llvm::ArrayRef(GCCRegNames);823}824825const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {826// While some of these aliases do map to different registers827// they still share the same register name.828{{"0"}, "r0"}, {{"1", "sp"}, "r1"}, {{"2"}, "r2"},829{{"3"}, "r3"}, {{"4"}, "r4"}, {{"5"}, "r5"},830{{"6"}, "r6"}, {{"7"}, "r7"}, {{"8"}, "r8"},831{{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"},832{{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"},833{{"15"}, "r15"}, {{"16"}, "r16"}, {{"17"}, "r17"},834{{"18"}, "r18"}, {{"19"}, "r19"}, {{"20"}, "r20"},835{{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"},836{{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"},837{{"27"}, "r27"}, {{"28"}, "r28"}, {{"29"}, "r29"},838{{"30"}, "r30"}, {{"31"}, "r31"}, {{"fr0"}, "f0"},839{{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"},840{{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"},841{{"fr7"}, "f7"}, {{"fr8"}, "f8"}, {{"fr9"}, "f9"},842{{"fr10"}, "f10"}, {{"fr11"}, "f11"}, {{"fr12"}, "f12"},843{{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},844{{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"},845{{"fr19"}, "f19"}, {{"fr20"}, "f20"}, {{"fr21"}, "f21"},846{{"fr22"}, "f22"}, {{"fr23"}, "f23"}, {{"fr24"}, "f24"},847{{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},848{{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"},849{{"fr31"}, "f31"}, {{"cc"}, "cr0"},850};851852ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {853return llvm::ArrayRef(GCCRegAliases);854}855856// PPC ELFABIv2 DWARF Definition "Table 2.26. Mappings of Common Registers".857// vs0 ~ vs31 is mapping to 32 - 63,858// vs32 ~ vs63 is mapping to 77 - 108.859// And this mapping applies to all OSes which run on powerpc.860const TargetInfo::AddlRegName GCCAddlRegNames[] = {861// Table of additional register names to use in user input.862{{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35},863{{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39},864{{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43},865{{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47},866{{"vs16"}, 48}, {{"vs17"}, 49}, {{"vs18"}, 50}, {{"vs19"}, 51},867{{"vs20"}, 52}, {{"vs21"}, 53}, {{"vs22"}, 54}, {{"vs23"}, 55},868{{"vs24"}, 56}, {{"vs25"}, 57}, {{"vs26"}, 58}, {{"vs27"}, 59},869{{"vs28"}, 60}, {{"vs29"}, 61}, {{"vs30"}, 62}, {{"vs31"}, 63},870{{"vs32"}, 77}, {{"vs33"}, 78}, {{"vs34"}, 79}, {{"vs35"}, 80},871{{"vs36"}, 81}, {{"vs37"}, 82}, {{"vs38"}, 83}, {{"vs39"}, 84},872{{"vs40"}, 85}, {{"vs41"}, 86}, {{"vs42"}, 87}, {{"vs43"}, 88},873{{"vs44"}, 89}, {{"vs45"}, 90}, {{"vs46"}, 91}, {{"vs47"}, 92},874{{"vs48"}, 93}, {{"vs49"}, 94}, {{"vs50"}, 95}, {{"vs51"}, 96},875{{"vs52"}, 97}, {{"vs53"}, 98}, {{"vs54"}, 99}, {{"vs55"}, 100},876{{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104},877{{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108},878};879880ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {881return llvm::ArrayRef(GCCAddlRegNames);882}883884static constexpr llvm::StringLiteral ValidCPUNames[] = {885{"generic"}, {"440"}, {"450"}, {"601"}, {"602"},886{"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"},887{"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"},888{"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"},889{"g5"}, {"a2"}, {"e500"}, {"e500mc"}, {"e5500"},890{"power3"}, {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"},891{"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"},892{"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"},893{"pwr8"}, {"power9"}, {"pwr9"}, {"power10"}, {"pwr10"},894{"power11"}, {"pwr11"}, {"powerpc"}, {"ppc"}, {"ppc32"},895{"powerpc64"}, {"ppc64"}, {"powerpc64le"}, {"ppc64le"}, {"future"}};896897bool PPCTargetInfo::isValidCPUName(StringRef Name) const {898return llvm::is_contained(ValidCPUNames, Name);899}900901void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {902Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));903}904905void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {906if (HasAltivec)907Opts.AltiVec = 1;908TargetInfo::adjust(Diags, Opts);909if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())910LongDoubleFormat = Opts.PPCIEEELongDouble911? &llvm::APFloat::IEEEquad()912: &llvm::APFloat::PPCDoubleDouble();913Opts.IEEE128 = 1;914if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI &&915HasQuadwordAtomics)916MaxAtomicInlineWidth = 128;917}918919ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {920return llvm::ArrayRef(BuiltinInfo,921clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin);922}923924bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const {925llvm::Triple Triple = getTriple();926if (Triple.isOSAIX()) {927#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP, \928VALUE) \929.Case(NAME, true)930return llvm::StringSwitch<bool>(FeatureStr)931#include "llvm/TargetParser/PPCTargetParser.def"932.Default(false);933}934935assert(Triple.isOSLinux() &&936"__builtin_cpu_supports() is only supported for AIX and Linux.");937938#define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true)939return llvm::StringSwitch<bool>(FeatureStr)940#include "llvm/TargetParser/PPCTargetParser.def"941.Default(false);942}943944bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const {945llvm::Triple Triple = getTriple();946assert((Triple.isOSAIX() || Triple.isOSLinux()) &&947"__builtin_cpu_is() is only supported for AIX and Linux.");948949#define PPC_CPU(NAME, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, \950AIXID) \951.Case(NAME, {Linux_SUPPORT_METHOD, AIX_SUPPORT_METHOD})952953std::pair<unsigned, unsigned> SuppportMethod =954llvm::StringSwitch<std::pair<unsigned, unsigned>>(CPUName)955#include "llvm/TargetParser/PPCTargetParser.def"956.Default({BUILTIN_PPC_UNSUPPORTED, BUILTIN_PPC_UNSUPPORTED});957return Triple.isOSLinux()958? (SuppportMethod.first != BUILTIN_PPC_UNSUPPORTED)959: (SuppportMethod.second != BUILTIN_PPC_UNSUPPORTED);960}961962963