xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp (revision 36b606ae6aa4b24061096ba18582e0a08ccd5dba)
10b57cec5SDimitry Andric //===--- PPC.cpp - Implement PPC target feature support -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements PPC TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "PPC.h"
140b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
150b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h"
160b57cec5SDimitry Andric #include "clang/Basic/TargetBuiltins.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace clang;
190b57cec5SDimitry Andric using namespace clang::targets;
200b57cec5SDimitry Andric 
21bdd1243dSDimitry Andric static constexpr Builtin::Info BuiltinInfo[] = {
220b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
23bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
2406c3fb27SDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
2506c3fb27SDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
260b57cec5SDimitry Andric #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
27bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
280b57cec5SDimitry Andric #include "clang/Basic/BuiltinsPPC.def"
290b57cec5SDimitry Andric };
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric /// handleTargetFeatures - Perform initialization based on the user
320b57cec5SDimitry Andric /// configured set of features.
330b57cec5SDimitry Andric bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
340b57cec5SDimitry Andric                                          DiagnosticsEngine &Diags) {
350b57cec5SDimitry Andric   FloatABI = HardFloat;
360b57cec5SDimitry Andric   for (const auto &Feature : Features) {
370b57cec5SDimitry Andric     if (Feature == "+altivec") {
380b57cec5SDimitry Andric       HasAltivec = true;
390b57cec5SDimitry Andric     } else if (Feature == "+vsx") {
400b57cec5SDimitry Andric       HasVSX = true;
4181ad6265SDimitry Andric     } else if (Feature == "+crbits") {
4281ad6265SDimitry Andric       UseCRBits = true;
430b57cec5SDimitry Andric     } else if (Feature == "+bpermd") {
440b57cec5SDimitry Andric       HasBPERMD = true;
450b57cec5SDimitry Andric     } else if (Feature == "+extdiv") {
460b57cec5SDimitry Andric       HasExtDiv = true;
470b57cec5SDimitry Andric     } else if (Feature == "+power8-vector") {
480b57cec5SDimitry Andric       HasP8Vector = true;
490b57cec5SDimitry Andric     } else if (Feature == "+crypto") {
500b57cec5SDimitry Andric       HasP8Crypto = true;
510b57cec5SDimitry Andric     } else if (Feature == "+direct-move") {
520b57cec5SDimitry Andric       HasDirectMove = true;
530b57cec5SDimitry Andric     } else if (Feature == "+htm") {
540b57cec5SDimitry Andric       HasHTM = true;
550b57cec5SDimitry Andric     } else if (Feature == "+float128") {
565f757f3fSDimitry Andric       HasFloat128 = !getTriple().isOSAIX();
570b57cec5SDimitry Andric     } else if (Feature == "+power9-vector") {
580b57cec5SDimitry Andric       HasP9Vector = true;
595ffd83dbSDimitry Andric     } else if (Feature == "+power10-vector") {
605ffd83dbSDimitry Andric       HasP10Vector = true;
615ffd83dbSDimitry Andric     } else if (Feature == "+pcrelative-memops") {
625ffd83dbSDimitry Andric       HasPCRelativeMemops = true;
63fe6060f1SDimitry Andric     } else if (Feature == "+prefix-instrs") {
64fe6060f1SDimitry Andric       HasPrefixInstrs = true;
65e8d8bef9SDimitry Andric     } else if (Feature == "+spe" || Feature == "+efpu2") {
66715df83aSDimitry Andric       HasStrictFP = false;
670b57cec5SDimitry Andric       HasSPE = true;
680b57cec5SDimitry Andric       LongDoubleWidth = LongDoubleAlign = 64;
690b57cec5SDimitry Andric       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
700b57cec5SDimitry Andric     } else if (Feature == "-hard-float") {
710b57cec5SDimitry Andric       FloatABI = SoftFloat;
72e8d8bef9SDimitry Andric     } else if (Feature == "+paired-vector-memops") {
73e8d8bef9SDimitry Andric       PairedVectorMemops = true;
74e8d8bef9SDimitry Andric     } else if (Feature == "+mma") {
75e8d8bef9SDimitry Andric       HasMMA = true;
76fe6060f1SDimitry Andric     } else if (Feature == "+rop-protect") {
77fe6060f1SDimitry Andric       HasROPProtect = true;
78fe6060f1SDimitry Andric     } else if (Feature == "+privileged") {
79fe6060f1SDimitry Andric       HasPrivileged = true;
805f757f3fSDimitry Andric     } else if (Feature == "+aix-small-local-exec-tls") {
815f757f3fSDimitry Andric       HasAIXSmallLocalExecTLS = true;
820fca6ea1SDimitry Andric     } else if (Feature == "+aix-small-local-dynamic-tls") {
830fca6ea1SDimitry Andric       HasAIXSmallLocalDynamicTLS = true;
84349cc55cSDimitry Andric     } else if (Feature == "+isa-v206-instructions") {
85349cc55cSDimitry Andric       IsISA2_06 = true;
86fe6060f1SDimitry Andric     } else if (Feature == "+isa-v207-instructions") {
87fe6060f1SDimitry Andric       IsISA2_07 = true;
88fe6060f1SDimitry Andric     } else if (Feature == "+isa-v30-instructions") {
89fe6060f1SDimitry Andric       IsISA3_0 = true;
90fe6060f1SDimitry Andric     } else if (Feature == "+isa-v31-instructions") {
91fe6060f1SDimitry Andric       IsISA3_1 = true;
9281ad6265SDimitry Andric     } else if (Feature == "+quadword-atomics") {
9381ad6265SDimitry Andric       HasQuadwordAtomics = true;
940fca6ea1SDimitry Andric     } else if (Feature == "+aix-shared-lib-tls-model-opt") {
950fca6ea1SDimitry Andric       HasAIXShLibTLSModelOpt = true;
960fca6ea1SDimitry Andric     } else if (Feature == "+longcall") {
970fca6ea1SDimitry Andric       UseLongCalls = true;
980b57cec5SDimitry Andric     }
990b57cec5SDimitry Andric     // TODO: Finish this list and add an assert that we've handled them
1000b57cec5SDimitry Andric     // all.
1010b57cec5SDimitry Andric   }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   return true;
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
106fe6060f1SDimitry Andric static void defineXLCompatMacros(MacroBuilder &Builder) {
107fe6060f1SDimitry Andric   Builder.defineMacro("__popcntb", "__builtin_ppc_popcntb");
108fe6060f1SDimitry Andric   Builder.defineMacro("__poppar4", "__builtin_ppc_poppar4");
109fe6060f1SDimitry Andric   Builder.defineMacro("__poppar8", "__builtin_ppc_poppar8");
110fe6060f1SDimitry Andric   Builder.defineMacro("__eieio", "__builtin_ppc_eieio");
111fe6060f1SDimitry Andric   Builder.defineMacro("__iospace_eieio", "__builtin_ppc_iospace_eieio");
112fe6060f1SDimitry Andric   Builder.defineMacro("__isync", "__builtin_ppc_isync");
113fe6060f1SDimitry Andric   Builder.defineMacro("__lwsync", "__builtin_ppc_lwsync");
114fe6060f1SDimitry Andric   Builder.defineMacro("__iospace_lwsync", "__builtin_ppc_iospace_lwsync");
115fe6060f1SDimitry Andric   Builder.defineMacro("__sync", "__builtin_ppc_sync");
116fe6060f1SDimitry Andric   Builder.defineMacro("__iospace_sync", "__builtin_ppc_iospace_sync");
117fe6060f1SDimitry Andric   Builder.defineMacro("__dcbfl", "__builtin_ppc_dcbfl");
118fe6060f1SDimitry Andric   Builder.defineMacro("__dcbflp", "__builtin_ppc_dcbflp");
119fe6060f1SDimitry Andric   Builder.defineMacro("__dcbst", "__builtin_ppc_dcbst");
120fe6060f1SDimitry Andric   Builder.defineMacro("__dcbt", "__builtin_ppc_dcbt");
121fe6060f1SDimitry Andric   Builder.defineMacro("__dcbtst", "__builtin_ppc_dcbtst");
122fe6060f1SDimitry Andric   Builder.defineMacro("__dcbz", "__builtin_ppc_dcbz");
123fe6060f1SDimitry Andric   Builder.defineMacro("__icbt", "__builtin_ppc_icbt");
124fe6060f1SDimitry Andric   Builder.defineMacro("__compare_and_swap", "__builtin_ppc_compare_and_swap");
125fe6060f1SDimitry Andric   Builder.defineMacro("__compare_and_swaplp",
126fe6060f1SDimitry Andric                       "__builtin_ppc_compare_and_swaplp");
127fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_add", "__builtin_ppc_fetch_and_add");
128fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_addlp", "__builtin_ppc_fetch_and_addlp");
129fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_and", "__builtin_ppc_fetch_and_and");
130fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_andlp", "__builtin_ppc_fetch_and_andlp");
131fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_or", "__builtin_ppc_fetch_and_or");
132fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_orlp", "__builtin_ppc_fetch_and_orlp");
133fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_swap", "__builtin_ppc_fetch_and_swap");
134fe6060f1SDimitry Andric   Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_and_swaplp");
135fe6060f1SDimitry Andric   Builder.defineMacro("__ldarx", "__builtin_ppc_ldarx");
136fe6060f1SDimitry Andric   Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");
137fe6060f1SDimitry Andric   Builder.defineMacro("__lharx", "__builtin_ppc_lharx");
138fe6060f1SDimitry Andric   Builder.defineMacro("__lbarx", "__builtin_ppc_lbarx");
139fe6060f1SDimitry Andric   Builder.defineMacro("__stfiw", "__builtin_ppc_stfiw");
140fe6060f1SDimitry Andric   Builder.defineMacro("__stdcx", "__builtin_ppc_stdcx");
141fe6060f1SDimitry Andric   Builder.defineMacro("__stwcx", "__builtin_ppc_stwcx");
142fe6060f1SDimitry Andric   Builder.defineMacro("__sthcx", "__builtin_ppc_sthcx");
143fe6060f1SDimitry Andric   Builder.defineMacro("__stbcx", "__builtin_ppc_stbcx");
144fe6060f1SDimitry Andric   Builder.defineMacro("__tdw", "__builtin_ppc_tdw");
145fe6060f1SDimitry Andric   Builder.defineMacro("__tw", "__builtin_ppc_tw");
146fe6060f1SDimitry Andric   Builder.defineMacro("__trap", "__builtin_ppc_trap");
147fe6060f1SDimitry Andric   Builder.defineMacro("__trapd", "__builtin_ppc_trapd");
148fe6060f1SDimitry Andric   Builder.defineMacro("__fcfid", "__builtin_ppc_fcfid");
149fe6060f1SDimitry Andric   Builder.defineMacro("__fcfud", "__builtin_ppc_fcfud");
150fe6060f1SDimitry Andric   Builder.defineMacro("__fctid", "__builtin_ppc_fctid");
151fe6060f1SDimitry Andric   Builder.defineMacro("__fctidz", "__builtin_ppc_fctidz");
152fe6060f1SDimitry Andric   Builder.defineMacro("__fctiw", "__builtin_ppc_fctiw");
153fe6060f1SDimitry Andric   Builder.defineMacro("__fctiwz", "__builtin_ppc_fctiwz");
154fe6060f1SDimitry Andric   Builder.defineMacro("__fctudz", "__builtin_ppc_fctudz");
155fe6060f1SDimitry Andric   Builder.defineMacro("__fctuwz", "__builtin_ppc_fctuwz");
156fe6060f1SDimitry Andric   Builder.defineMacro("__cmpeqb", "__builtin_ppc_cmpeqb");
157fe6060f1SDimitry Andric   Builder.defineMacro("__cmprb", "__builtin_ppc_cmprb");
158fe6060f1SDimitry Andric   Builder.defineMacro("__setb", "__builtin_ppc_setb");
159fe6060f1SDimitry Andric   Builder.defineMacro("__cmpb", "__builtin_ppc_cmpb");
160fe6060f1SDimitry Andric   Builder.defineMacro("__mulhd", "__builtin_ppc_mulhd");
161fe6060f1SDimitry Andric   Builder.defineMacro("__mulhdu", "__builtin_ppc_mulhdu");
162fe6060f1SDimitry Andric   Builder.defineMacro("__mulhw", "__builtin_ppc_mulhw");
163fe6060f1SDimitry Andric   Builder.defineMacro("__mulhwu", "__builtin_ppc_mulhwu");
164fe6060f1SDimitry Andric   Builder.defineMacro("__maddhd", "__builtin_ppc_maddhd");
165fe6060f1SDimitry Andric   Builder.defineMacro("__maddhdu", "__builtin_ppc_maddhdu");
166fe6060f1SDimitry Andric   Builder.defineMacro("__maddld", "__builtin_ppc_maddld");
167fe6060f1SDimitry Andric   Builder.defineMacro("__rlwnm", "__builtin_ppc_rlwnm");
168fe6060f1SDimitry Andric   Builder.defineMacro("__rlwimi", "__builtin_ppc_rlwimi");
169fe6060f1SDimitry Andric   Builder.defineMacro("__rldimi", "__builtin_ppc_rldimi");
170fe6060f1SDimitry Andric   Builder.defineMacro("__load2r", "__builtin_ppc_load2r");
171fe6060f1SDimitry Andric   Builder.defineMacro("__load4r", "__builtin_ppc_load4r");
172fe6060f1SDimitry Andric   Builder.defineMacro("__load8r", "__builtin_ppc_load8r");
173fe6060f1SDimitry Andric   Builder.defineMacro("__store2r", "__builtin_ppc_store2r");
174fe6060f1SDimitry Andric   Builder.defineMacro("__store4r", "__builtin_ppc_store4r");
175fe6060f1SDimitry Andric   Builder.defineMacro("__store8r", "__builtin_ppc_store8r");
176fe6060f1SDimitry Andric   Builder.defineMacro("__extract_exp", "__builtin_ppc_extract_exp");
177fe6060f1SDimitry Andric   Builder.defineMacro("__extract_sig", "__builtin_ppc_extract_sig");
178fe6060f1SDimitry Andric   Builder.defineMacro("__mtfsb0", "__builtin_ppc_mtfsb0");
179fe6060f1SDimitry Andric   Builder.defineMacro("__mtfsb1", "__builtin_ppc_mtfsb1");
180fe6060f1SDimitry Andric   Builder.defineMacro("__mtfsf", "__builtin_ppc_mtfsf");
181fe6060f1SDimitry Andric   Builder.defineMacro("__mtfsfi", "__builtin_ppc_mtfsfi");
182fe6060f1SDimitry Andric   Builder.defineMacro("__insert_exp", "__builtin_ppc_insert_exp");
183fe6060f1SDimitry Andric   Builder.defineMacro("__fmsub", "__builtin_ppc_fmsub");
184fe6060f1SDimitry Andric   Builder.defineMacro("__fmsubs", "__builtin_ppc_fmsubs");
185fe6060f1SDimitry Andric   Builder.defineMacro("__fnmadd", "__builtin_ppc_fnmadd");
186fe6060f1SDimitry Andric   Builder.defineMacro("__fnmadds", "__builtin_ppc_fnmadds");
187fe6060f1SDimitry Andric   Builder.defineMacro("__fnmsub", "__builtin_ppc_fnmsub");
188fe6060f1SDimitry Andric   Builder.defineMacro("__fnmsubs", "__builtin_ppc_fnmsubs");
189fe6060f1SDimitry Andric   Builder.defineMacro("__fre", "__builtin_ppc_fre");
190fe6060f1SDimitry Andric   Builder.defineMacro("__fres", "__builtin_ppc_fres");
191fe6060f1SDimitry Andric   Builder.defineMacro("__swdiv_nochk", "__builtin_ppc_swdiv_nochk");
192fe6060f1SDimitry Andric   Builder.defineMacro("__swdivs_nochk", "__builtin_ppc_swdivs_nochk");
193fe6060f1SDimitry Andric   Builder.defineMacro("__alloca", "__builtin_alloca");
194fe6060f1SDimitry Andric   Builder.defineMacro("__vcipher", "__builtin_altivec_crypto_vcipher");
195fe6060f1SDimitry Andric   Builder.defineMacro("__vcipherlast", "__builtin_altivec_crypto_vcipherlast");
196fe6060f1SDimitry Andric   Builder.defineMacro("__vncipher", "__builtin_altivec_crypto_vncipher");
197fe6060f1SDimitry Andric   Builder.defineMacro("__vncipherlast",
198fe6060f1SDimitry Andric                       "__builtin_altivec_crypto_vncipherlast");
199fe6060f1SDimitry Andric   Builder.defineMacro("__vpermxor", "__builtin_altivec_crypto_vpermxor");
200fe6060f1SDimitry Andric   Builder.defineMacro("__vpmsumb", "__builtin_altivec_crypto_vpmsumb");
201fe6060f1SDimitry Andric   Builder.defineMacro("__vpmsumd", "__builtin_altivec_crypto_vpmsumd");
202fe6060f1SDimitry Andric   Builder.defineMacro("__vpmsumh", "__builtin_altivec_crypto_vpmsumh");
203fe6060f1SDimitry Andric   Builder.defineMacro("__vpmsumw", "__builtin_altivec_crypto_vpmsumw");
204fe6060f1SDimitry Andric   Builder.defineMacro("__divde", "__builtin_divde");
205fe6060f1SDimitry Andric   Builder.defineMacro("__divwe", "__builtin_divwe");
206fe6060f1SDimitry Andric   Builder.defineMacro("__divdeu", "__builtin_divdeu");
207fe6060f1SDimitry Andric   Builder.defineMacro("__divweu", "__builtin_divweu");
208fe6060f1SDimitry Andric   Builder.defineMacro("__alignx", "__builtin_ppc_alignx");
209fe6060f1SDimitry Andric   Builder.defineMacro("__bcopy", "bcopy");
210fe6060f1SDimitry Andric   Builder.defineMacro("__bpermd", "__builtin_bpermd");
211fe6060f1SDimitry Andric   Builder.defineMacro("__cntlz4", "__builtin_clz");
212fe6060f1SDimitry Andric   Builder.defineMacro("__cntlz8", "__builtin_clzll");
213fe6060f1SDimitry Andric   Builder.defineMacro("__cmplx", "__builtin_complex");
214fe6060f1SDimitry Andric   Builder.defineMacro("__cmplxf", "__builtin_complex");
215fe6060f1SDimitry Andric   Builder.defineMacro("__cnttz4", "__builtin_ctz");
216fe6060f1SDimitry Andric   Builder.defineMacro("__cnttz8", "__builtin_ctzll");
217fe6060f1SDimitry Andric   Builder.defineMacro("__darn", "__builtin_darn");
218fe6060f1SDimitry Andric   Builder.defineMacro("__darn_32", "__builtin_darn_32");
219fe6060f1SDimitry Andric   Builder.defineMacro("__darn_raw", "__builtin_darn_raw");
220fe6060f1SDimitry Andric   Builder.defineMacro("__dcbf", "__builtin_dcbf");
2217a6dacacSDimitry Andric   Builder.defineMacro("__fence", "__builtin_ppc_fence");
222fe6060f1SDimitry Andric   Builder.defineMacro("__fmadd", "__builtin_fma");
223fe6060f1SDimitry Andric   Builder.defineMacro("__fmadds", "__builtin_fmaf");
22481ad6265SDimitry Andric   Builder.defineMacro("__abs", "__builtin_abs");
225fe6060f1SDimitry Andric   Builder.defineMacro("__labs", "__builtin_labs");
226fe6060f1SDimitry Andric   Builder.defineMacro("__llabs", "__builtin_llabs");
227fe6060f1SDimitry Andric   Builder.defineMacro("__popcnt4", "__builtin_popcount");
228fe6060f1SDimitry Andric   Builder.defineMacro("__popcnt8", "__builtin_popcountll");
229fe6060f1SDimitry Andric   Builder.defineMacro("__readflm", "__builtin_readflm");
230fe6060f1SDimitry Andric   Builder.defineMacro("__rotatel4", "__builtin_rotateleft32");
231fe6060f1SDimitry Andric   Builder.defineMacro("__rotatel8", "__builtin_rotateleft64");
232fe6060f1SDimitry Andric   Builder.defineMacro("__rdlam", "__builtin_ppc_rdlam");
233fe6060f1SDimitry Andric   Builder.defineMacro("__setflm", "__builtin_setflm");
234fe6060f1SDimitry Andric   Builder.defineMacro("__setrnd", "__builtin_setrnd");
235fe6060f1SDimitry Andric   Builder.defineMacro("__dcbtstt", "__builtin_ppc_dcbtstt");
236fe6060f1SDimitry Andric   Builder.defineMacro("__dcbtt", "__builtin_ppc_dcbtt");
237fe6060f1SDimitry Andric   Builder.defineMacro("__mftbu", "__builtin_ppc_mftbu");
238fe6060f1SDimitry Andric   Builder.defineMacro("__mfmsr", "__builtin_ppc_mfmsr");
239fe6060f1SDimitry Andric   Builder.defineMacro("__mtmsr", "__builtin_ppc_mtmsr");
240fe6060f1SDimitry Andric   Builder.defineMacro("__mfspr", "__builtin_ppc_mfspr");
241fe6060f1SDimitry Andric   Builder.defineMacro("__mtspr", "__builtin_ppc_mtspr");
242fe6060f1SDimitry Andric   Builder.defineMacro("__fric", "__builtin_ppc_fric");
243fe6060f1SDimitry Andric   Builder.defineMacro("__frim", "__builtin_ppc_frim");
244fe6060f1SDimitry Andric   Builder.defineMacro("__frims", "__builtin_ppc_frims");
245fe6060f1SDimitry Andric   Builder.defineMacro("__frin", "__builtin_ppc_frin");
246fe6060f1SDimitry Andric   Builder.defineMacro("__frins", "__builtin_ppc_frins");
247fe6060f1SDimitry Andric   Builder.defineMacro("__frip", "__builtin_ppc_frip");
248fe6060f1SDimitry Andric   Builder.defineMacro("__frips", "__builtin_ppc_frips");
249fe6060f1SDimitry Andric   Builder.defineMacro("__friz", "__builtin_ppc_friz");
250fe6060f1SDimitry Andric   Builder.defineMacro("__frizs", "__builtin_ppc_frizs");
251fe6060f1SDimitry Andric   Builder.defineMacro("__fsel", "__builtin_ppc_fsel");
252fe6060f1SDimitry Andric   Builder.defineMacro("__fsels", "__builtin_ppc_fsels");
253fe6060f1SDimitry Andric   Builder.defineMacro("__frsqrte", "__builtin_ppc_frsqrte");
254fe6060f1SDimitry Andric   Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes");
255fe6060f1SDimitry Andric   Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt");
256fe6060f1SDimitry Andric   Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
257349cc55cSDimitry Andric   Builder.defineMacro("__addex", "__builtin_ppc_addex");
258349cc55cSDimitry Andric   Builder.defineMacro("__cmplxl", "__builtin_complex");
259349cc55cSDimitry Andric   Builder.defineMacro("__compare_exp_uo", "__builtin_ppc_compare_exp_uo");
260349cc55cSDimitry Andric   Builder.defineMacro("__compare_exp_lt", "__builtin_ppc_compare_exp_lt");
261349cc55cSDimitry Andric   Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt");
262349cc55cSDimitry Andric   Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq");
263349cc55cSDimitry Andric   Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");
264349cc55cSDimitry Andric   Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv");
265349cc55cSDimitry Andric   Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs");
26681ad6265SDimitry Andric   Builder.defineMacro("__fnabs", "__builtin_ppc_fnabs");
26781ad6265SDimitry Andric   Builder.defineMacro("__fnabss", "__builtin_ppc_fnabss");
26881ad6265SDimitry Andric   Builder.defineMacro("__builtin_maxfe", "__builtin_ppc_maxfe");
26981ad6265SDimitry Andric   Builder.defineMacro("__builtin_maxfl", "__builtin_ppc_maxfl");
27081ad6265SDimitry Andric   Builder.defineMacro("__builtin_maxfs", "__builtin_ppc_maxfs");
27181ad6265SDimitry Andric   Builder.defineMacro("__builtin_minfe", "__builtin_ppc_minfe");
27281ad6265SDimitry Andric   Builder.defineMacro("__builtin_minfl", "__builtin_ppc_minfl");
27381ad6265SDimitry Andric   Builder.defineMacro("__builtin_minfs", "__builtin_ppc_minfs");
2745f757f3fSDimitry Andric   Builder.defineMacro("__builtin_mffs", "__builtin_ppc_mffs");
2755f757f3fSDimitry Andric   Builder.defineMacro("__builtin_mffsl", "__builtin_ppc_mffsl");
2765f757f3fSDimitry Andric   Builder.defineMacro("__builtin_mtfsf", "__builtin_ppc_mtfsf");
2775f757f3fSDimitry Andric   Builder.defineMacro("__builtin_set_fpscr_rn", "__builtin_ppc_set_fpscr_rn");
278fe6060f1SDimitry Andric }
279fe6060f1SDimitry Andric 
2800b57cec5SDimitry Andric /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
2810b57cec5SDimitry Andric /// #defines that are not tied to a specific subtarget.
2820b57cec5SDimitry Andric void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
2830b57cec5SDimitry Andric                                      MacroBuilder &Builder) const {
284fe6060f1SDimitry Andric 
28539dadd06SDimitry Andric   // We define the XLC compatibility macros only on AIX and Linux since XLC
28639dadd06SDimitry Andric   // was never available on any other platforms.
28739dadd06SDimitry Andric   if (getTriple().isOSAIX() || getTriple().isOSLinux())
288fe6060f1SDimitry Andric     defineXLCompatMacros(Builder);
289fe6060f1SDimitry Andric 
2900b57cec5SDimitry Andric   // Target identification.
2910b57cec5SDimitry Andric   Builder.defineMacro("__ppc__");
2920b57cec5SDimitry Andric   Builder.defineMacro("__PPC__");
2930b57cec5SDimitry Andric   Builder.defineMacro("_ARCH_PPC");
2940b57cec5SDimitry Andric   Builder.defineMacro("__powerpc__");
2950b57cec5SDimitry Andric   Builder.defineMacro("__POWERPC__");
2960b57cec5SDimitry Andric   if (PointerWidth == 64) {
2970b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PPC64");
2980b57cec5SDimitry Andric     Builder.defineMacro("__powerpc64__");
2990b57cec5SDimitry Andric     Builder.defineMacro("__PPC64__");
300349cc55cSDimitry Andric   } else if (getTriple().isOSAIX()) {
301349cc55cSDimitry Andric     // The XL compilers on AIX define _ARCH_PPC64 for both 32 and 64-bit modes.
302349cc55cSDimitry Andric     Builder.defineMacro("_ARCH_PPC64");
303349cc55cSDimitry Andric   }
304349cc55cSDimitry Andric   if (getTriple().isOSAIX()) {
305349cc55cSDimitry Andric     Builder.defineMacro("__THW_PPC__");
306349cc55cSDimitry Andric     // Define __PPC and __powerpc for AIX XL C/C++ compatibility
307349cc55cSDimitry Andric     Builder.defineMacro("__PPC");
308349cc55cSDimitry Andric     Builder.defineMacro("__powerpc");
3090b57cec5SDimitry Andric   }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   // Target properties.
312e8d8bef9SDimitry Andric   if (getTriple().getArch() == llvm::Triple::ppc64le ||
313e8d8bef9SDimitry Andric       getTriple().getArch() == llvm::Triple::ppcle) {
3140b57cec5SDimitry Andric     Builder.defineMacro("_LITTLE_ENDIAN");
3150b57cec5SDimitry Andric   } else {
3160b57cec5SDimitry Andric     if (!getTriple().isOSNetBSD() &&
3170b57cec5SDimitry Andric         !getTriple().isOSOpenBSD())
3180b57cec5SDimitry Andric       Builder.defineMacro("_BIG_ENDIAN");
3190b57cec5SDimitry Andric   }
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   // ABI options.
322e8d8bef9SDimitry Andric   if (ABI == "elfv1")
3230b57cec5SDimitry Andric     Builder.defineMacro("_CALL_ELF", "1");
3240b57cec5SDimitry Andric   if (ABI == "elfv2")
3250b57cec5SDimitry Andric     Builder.defineMacro("_CALL_ELF", "2");
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
3280b57cec5SDimitry Andric   // our support post-dates this and it should work on all 64-bit ppc linux
3290b57cec5SDimitry Andric   // platforms. It is guaranteed to work on all elfv2 platforms.
3300b57cec5SDimitry Andric   if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
3310b57cec5SDimitry Andric     Builder.defineMacro("_CALL_LINUX", "1");
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   // Subtarget options.
3340b57cec5SDimitry Andric   if (!getTriple().isOSAIX()){
3350b57cec5SDimitry Andric     Builder.defineMacro("__NATURAL_ALIGNMENT__");
3360b57cec5SDimitry Andric   }
3370b57cec5SDimitry Andric   Builder.defineMacro("__REGISTER_PREFIX__", "");
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   // FIXME: Should be controlled by command line option.
3400b57cec5SDimitry Andric   if (LongDoubleWidth == 128) {
3410b57cec5SDimitry Andric     Builder.defineMacro("__LONG_DOUBLE_128__");
3420b57cec5SDimitry Andric     Builder.defineMacro("__LONGDOUBLE128");
343e8d8bef9SDimitry Andric     if (Opts.PPCIEEELongDouble)
344e8d8bef9SDimitry Andric       Builder.defineMacro("__LONG_DOUBLE_IEEE128__");
345e8d8bef9SDimitry Andric     else
346e8d8bef9SDimitry Andric       Builder.defineMacro("__LONG_DOUBLE_IBM128__");
3470b57cec5SDimitry Andric   }
3480b57cec5SDimitry Andric 
349fe6060f1SDimitry Andric   if (getTriple().isOSAIX() && Opts.LongDoubleSize == 64) {
350fe6060f1SDimitry Andric     assert(LongDoubleWidth == 64);
351fe6060f1SDimitry Andric     Builder.defineMacro("__LONGDOUBLE64");
352fe6060f1SDimitry Andric   }
353fe6060f1SDimitry Andric 
35406c3fb27SDimitry Andric   // Define this for elfv2 (64-bit only).
35506c3fb27SDimitry Andric   if (ABI == "elfv2")
3560b57cec5SDimitry Andric     Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   if (ArchDefs & ArchDefineName)
3590b57cec5SDimitry Andric     Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
3600b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePpcgr)
3610b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PPCGR");
3620b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePpcsq)
3630b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PPCSQ");
3640b57cec5SDimitry Andric   if (ArchDefs & ArchDefine440)
3650b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_440");
3660b57cec5SDimitry Andric   if (ArchDefs & ArchDefine603)
3670b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_603");
3680b57cec5SDimitry Andric   if (ArchDefs & ArchDefine604)
3690b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_604");
3700b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr4)
3710b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR4");
3720b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr5)
3730b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR5");
3740b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr5x)
3750b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR5X");
3760b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr6)
3770b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR6");
3780b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr6x)
3790b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR6X");
3800b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr7)
3810b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR7");
3820b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr8)
3830b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR8");
3840b57cec5SDimitry Andric   if (ArchDefs & ArchDefinePwr9)
3850b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PWR9");
3865ffd83dbSDimitry Andric   if (ArchDefs & ArchDefinePwr10)
3875ffd83dbSDimitry Andric     Builder.defineMacro("_ARCH_PWR10");
388*36b606aeSDimitry Andric   if (ArchDefs & ArchDefinePwr11)
389*36b606aeSDimitry Andric     Builder.defineMacro("_ARCH_PWR11");
3900b57cec5SDimitry Andric   if (ArchDefs & ArchDefineA2)
3910b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_A2");
392f8e1cfadSDimitry Andric   if (ArchDefs & ArchDefineE500)
393f8e1cfadSDimitry Andric     Builder.defineMacro("__NO_LWSYNC__");
394480093f4SDimitry Andric   if (ArchDefs & ArchDefineFuture)
395480093f4SDimitry Andric     Builder.defineMacro("_ARCH_PWR_FUTURE");
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   if (HasAltivec) {
3980b57cec5SDimitry Andric     Builder.defineMacro("__VEC__", "10206");
3990b57cec5SDimitry Andric     Builder.defineMacro("__ALTIVEC__");
4000b57cec5SDimitry Andric   }
4010b57cec5SDimitry Andric   if (HasSPE) {
4020b57cec5SDimitry Andric     Builder.defineMacro("__SPE__");
4030b57cec5SDimitry Andric     Builder.defineMacro("__NO_FPRS__");
4040b57cec5SDimitry Andric   }
4050b57cec5SDimitry Andric   if (HasVSX)
4060b57cec5SDimitry Andric     Builder.defineMacro("__VSX__");
4070b57cec5SDimitry Andric   if (HasP8Vector)
4080b57cec5SDimitry Andric     Builder.defineMacro("__POWER8_VECTOR__");
4090b57cec5SDimitry Andric   if (HasP8Crypto)
4100b57cec5SDimitry Andric     Builder.defineMacro("__CRYPTO__");
4110b57cec5SDimitry Andric   if (HasHTM)
4120b57cec5SDimitry Andric     Builder.defineMacro("__HTM__");
4130b57cec5SDimitry Andric   if (HasFloat128)
4140b57cec5SDimitry Andric     Builder.defineMacro("__FLOAT128__");
4150b57cec5SDimitry Andric   if (HasP9Vector)
4160b57cec5SDimitry Andric     Builder.defineMacro("__POWER9_VECTOR__");
417e8d8bef9SDimitry Andric   if (HasMMA)
418e8d8bef9SDimitry Andric     Builder.defineMacro("__MMA__");
419fe6060f1SDimitry Andric   if (HasROPProtect)
420fe6060f1SDimitry Andric     Builder.defineMacro("__ROP_PROTECT__");
4215ffd83dbSDimitry Andric   if (HasP10Vector)
4225ffd83dbSDimitry Andric     Builder.defineMacro("__POWER10_VECTOR__");
423fe6060f1SDimitry Andric   if (HasPCRelativeMemops)
424fe6060f1SDimitry Andric     Builder.defineMacro("__PCREL__");
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
4270b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
4280b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
4290b57cec5SDimitry Andric   if (PointerWidth == 64)
4300b57cec5SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   // We have support for the bswap intrinsics so we can define this.
4330b57cec5SDimitry Andric   Builder.defineMacro("__HAVE_BSWAP__", "1");
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   // FIXME: The following are not yet generated here by Clang, but are
4360b57cec5SDimitry Andric   //        generated by GCC:
4370b57cec5SDimitry Andric   //
4380b57cec5SDimitry Andric   //   _SOFT_FLOAT_
4390b57cec5SDimitry Andric   //   __RECIP_PRECISION__
4400b57cec5SDimitry Andric   //   __APPLE_ALTIVEC__
4410b57cec5SDimitry Andric   //   __RECIP__
4420b57cec5SDimitry Andric   //   __RECIPF__
4430b57cec5SDimitry Andric   //   __RSQRTE__
4440b57cec5SDimitry Andric   //   __RSQRTEF__
4450b57cec5SDimitry Andric   //   _SOFT_DOUBLE_
4460b57cec5SDimitry Andric   //   __NO_LWSYNC__
4470b57cec5SDimitry Andric   //   __CMODEL_MEDIUM__
4480b57cec5SDimitry Andric   //   __CMODEL_LARGE__
4490b57cec5SDimitry Andric   //   _CALL_SYSV
4500b57cec5SDimitry Andric   //   _CALL_DARWIN
4510b57cec5SDimitry Andric }
4520b57cec5SDimitry Andric 
4530fca6ea1SDimitry Andric // Handle explicit options being passed to the compiler here:
4540fca6ea1SDimitry Andric // - if we've explicitly turned off vsx and turned on any of:
4550b57cec5SDimitry Andric //   - power8-vector
4560b57cec5SDimitry Andric //   - direct-move
4570b57cec5SDimitry Andric //   - float128
4580b57cec5SDimitry Andric //   - power9-vector
459e8d8bef9SDimitry Andric //   - paired-vector-memops
460e8d8bef9SDimitry Andric //   - mma
4615ffd83dbSDimitry Andric //   - power10-vector
4620fca6ea1SDimitry Andric // - if we've explicitly turned on vsx and turned off altivec.
4630fca6ea1SDimitry Andric // - if we've explicitly turned off hard-float and turned on altivec.
4640b57cec5SDimitry Andric // then go ahead and error since the customer has expressed an incompatible
4650b57cec5SDimitry Andric // set of options.
4660b57cec5SDimitry Andric static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
4670b57cec5SDimitry Andric                                  const std::vector<std::string> &FeaturesVec) {
4680fca6ea1SDimitry Andric   // Cannot allow soft-float with Altivec.
4690fca6ea1SDimitry Andric   if (llvm::is_contained(FeaturesVec, "-hard-float") &&
4700fca6ea1SDimitry Andric       llvm::is_contained(FeaturesVec, "+altivec")) {
4710fca6ea1SDimitry Andric     Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float"
4720fca6ea1SDimitry Andric                                                    << "-maltivec";
4730fca6ea1SDimitry Andric     return false;
4740fca6ea1SDimitry Andric   }
4750fca6ea1SDimitry Andric 
4760fca6ea1SDimitry Andric   // Cannot allow soft-float with VSX.
4770fca6ea1SDimitry Andric   if (llvm::is_contained(FeaturesVec, "-hard-float") &&
4780fca6ea1SDimitry Andric       llvm::is_contained(FeaturesVec, "+vsx")) {
4790fca6ea1SDimitry Andric     Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float"
4800fca6ea1SDimitry Andric                                                    << "-mvsx";
4810fca6ea1SDimitry Andric     return false;
4820fca6ea1SDimitry Andric   }
4830fca6ea1SDimitry Andric 
4840fca6ea1SDimitry Andric   // Cannot allow VSX with no Altivec.
4850fca6ea1SDimitry Andric   if (llvm::is_contained(FeaturesVec, "+vsx") &&
4860fca6ea1SDimitry Andric       llvm::is_contained(FeaturesVec, "-altivec")) {
4870fca6ea1SDimitry Andric     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mvsx"
4880fca6ea1SDimitry Andric                                                    << "-mno-altivec";
4890fca6ea1SDimitry Andric     return false;
4900fca6ea1SDimitry Andric   }
4910b57cec5SDimitry Andric 
4925ffd83dbSDimitry Andric   // vsx was not explicitly turned off.
493349cc55cSDimitry Andric   if (!llvm::is_contained(FeaturesVec, "-vsx"))
4940b57cec5SDimitry Andric     return true;
4955ffd83dbSDimitry Andric 
4965ffd83dbSDimitry Andric   auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) {
497349cc55cSDimitry Andric     if (llvm::is_contained(FeaturesVec, Feature)) {
4985ffd83dbSDimitry Andric       Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx";
4995ffd83dbSDimitry Andric       return true;
5005ffd83dbSDimitry Andric     }
5015ffd83dbSDimitry Andric     return false;
5025ffd83dbSDimitry Andric   };
5035ffd83dbSDimitry Andric 
5045ffd83dbSDimitry Andric   bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector");
5055ffd83dbSDimitry Andric   Found |= FindVSXSubfeature("+direct-move", "-mdirect-move");
5065ffd83dbSDimitry Andric   Found |= FindVSXSubfeature("+float128", "-mfloat128");
5075ffd83dbSDimitry Andric   Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector");
508e8d8bef9SDimitry Andric   Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops");
509e8d8bef9SDimitry Andric   Found |= FindVSXSubfeature("+mma", "-mmma");
5105ffd83dbSDimitry Andric   Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector");
5115ffd83dbSDimitry Andric 
5125ffd83dbSDimitry Andric   // Return false if any vsx subfeatures was found.
5135ffd83dbSDimitry Andric   return !Found;
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric bool PPCTargetInfo::initFeatureMap(
5170b57cec5SDimitry Andric     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
5180b57cec5SDimitry Andric     const std::vector<std::string> &FeaturesVec) const {
5190b57cec5SDimitry Andric   Features["altivec"] = llvm::StringSwitch<bool>(CPU)
5200b57cec5SDimitry Andric                             .Case("7400", true)
5210b57cec5SDimitry Andric                             .Case("g4", true)
5220b57cec5SDimitry Andric                             .Case("7450", true)
5230b57cec5SDimitry Andric                             .Case("g4+", true)
5240b57cec5SDimitry Andric                             .Case("970", true)
5250b57cec5SDimitry Andric                             .Case("g5", true)
5260b57cec5SDimitry Andric                             .Case("pwr6", true)
5270b57cec5SDimitry Andric                             .Case("pwr7", true)
5280b57cec5SDimitry Andric                             .Case("pwr8", true)
5290b57cec5SDimitry Andric                             .Case("pwr9", true)
5300b57cec5SDimitry Andric                             .Case("ppc64", true)
5310b57cec5SDimitry Andric                             .Case("ppc64le", true)
5320b57cec5SDimitry Andric                             .Default(false);
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   Features["power9-vector"] = (CPU == "pwr9");
5350b57cec5SDimitry Andric   Features["crypto"] = llvm::StringSwitch<bool>(CPU)
5360b57cec5SDimitry Andric                            .Case("ppc64le", true)
5370b57cec5SDimitry Andric                            .Case("pwr9", true)
5380b57cec5SDimitry Andric                            .Case("pwr8", true)
5390b57cec5SDimitry Andric                            .Default(false);
5400b57cec5SDimitry Andric   Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
5410b57cec5SDimitry Andric                                   .Case("ppc64le", true)
5420b57cec5SDimitry Andric                                   .Case("pwr9", true)
5430b57cec5SDimitry Andric                                   .Case("pwr8", true)
5440b57cec5SDimitry Andric                                   .Default(false);
5450b57cec5SDimitry Andric   Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
5460b57cec5SDimitry Andric                            .Case("ppc64le", true)
5470b57cec5SDimitry Andric                            .Case("pwr9", true)
5480b57cec5SDimitry Andric                            .Case("pwr8", true)
5490b57cec5SDimitry Andric                            .Case("pwr7", true)
5500b57cec5SDimitry Andric                            .Default(false);
5510b57cec5SDimitry Andric   Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
5520b57cec5SDimitry Andric                            .Case("ppc64le", true)
5530b57cec5SDimitry Andric                            .Case("pwr9", true)
5540b57cec5SDimitry Andric                            .Case("pwr8", true)
5550b57cec5SDimitry Andric                            .Case("pwr7", true)
5560b57cec5SDimitry Andric                            .Default(false);
5570b57cec5SDimitry Andric   Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
5580b57cec5SDimitry Andric                                 .Case("ppc64le", true)
5590b57cec5SDimitry Andric                                 .Case("pwr9", true)
5600b57cec5SDimitry Andric                                 .Case("pwr8", true)
5610b57cec5SDimitry Andric                                 .Default(false);
56281ad6265SDimitry Andric   Features["crbits"] = llvm::StringSwitch<bool>(CPU)
56381ad6265SDimitry Andric                                 .Case("ppc64le", true)
56481ad6265SDimitry Andric                                 .Case("pwr9", true)
56581ad6265SDimitry Andric                                 .Case("pwr8", true)
56681ad6265SDimitry Andric                                 .Default(false);
5670b57cec5SDimitry Andric   Features["vsx"] = llvm::StringSwitch<bool>(CPU)
5680b57cec5SDimitry Andric                         .Case("ppc64le", true)
5690b57cec5SDimitry Andric                         .Case("pwr9", true)
5700b57cec5SDimitry Andric                         .Case("pwr8", true)
5710b57cec5SDimitry Andric                         .Case("pwr7", true)
5720b57cec5SDimitry Andric                         .Default(false);
5730b57cec5SDimitry Andric   Features["htm"] = llvm::StringSwitch<bool>(CPU)
5740b57cec5SDimitry Andric                         .Case("ppc64le", true)
5750b57cec5SDimitry Andric                         .Case("pwr9", true)
5760b57cec5SDimitry Andric                         .Case("pwr8", true)
5770b57cec5SDimitry Andric                         .Default(false);
5780b57cec5SDimitry Andric 
579fe6060f1SDimitry Andric   // ROP Protect is off by default.
580fe6060f1SDimitry Andric   Features["rop-protect"] = false;
581fe6060f1SDimitry Andric   // Privileged instructions are off by default.
582fe6060f1SDimitry Andric   Features["privileged"] = false;
583fe6060f1SDimitry Andric 
5840fca6ea1SDimitry Andric   // The code generated by the -maix-small-local-[exec|dynamic]-tls option is
5850fca6ea1SDimitry Andric   // turned off by default.
5865f757f3fSDimitry Andric   Features["aix-small-local-exec-tls"] = false;
5870fca6ea1SDimitry Andric   Features["aix-small-local-dynamic-tls"] = false;
5880fca6ea1SDimitry Andric 
5890fca6ea1SDimitry Andric   // Turn off TLS model opt by default.
5900fca6ea1SDimitry Andric   Features["aix-shared-lib-tls-model-opt"] = false;
5915f757f3fSDimitry Andric 
592f8e1cfadSDimitry Andric   Features["spe"] = llvm::StringSwitch<bool>(CPU)
593f8e1cfadSDimitry Andric                         .Case("8548", true)
594f8e1cfadSDimitry Andric                         .Case("e500", true)
595f8e1cfadSDimitry Andric                         .Default(false);
596f8e1cfadSDimitry Andric 
597349cc55cSDimitry Andric   Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU)
598349cc55cSDimitry Andric                                           .Case("ppc64le", true)
599349cc55cSDimitry Andric                                           .Case("pwr9", true)
600349cc55cSDimitry Andric                                           .Case("pwr8", true)
601349cc55cSDimitry Andric                                           .Case("pwr7", true)
60281ad6265SDimitry Andric                                           .Case("a2", true)
603349cc55cSDimitry Andric                                           .Default(false);
604349cc55cSDimitry Andric 
605fe6060f1SDimitry Andric   Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU)
606fe6060f1SDimitry Andric                                           .Case("ppc64le", true)
607fe6060f1SDimitry Andric                                           .Case("pwr9", true)
608fe6060f1SDimitry Andric                                           .Case("pwr8", true)
609fe6060f1SDimitry Andric                                           .Default(false);
610fe6060f1SDimitry Andric 
611fe6060f1SDimitry Andric   Features["isa-v30-instructions"] =
612fe6060f1SDimitry Andric       llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false);
613fe6060f1SDimitry Andric 
61481ad6265SDimitry Andric   Features["quadword-atomics"] =
61581ad6265SDimitry Andric       getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU)
61681ad6265SDimitry Andric                                        .Case("pwr9", true)
61781ad6265SDimitry Andric                                        .Case("pwr8", true)
61881ad6265SDimitry Andric                                        .Default(false);
61981ad6265SDimitry Andric 
6205ffd83dbSDimitry Andric   // Power10 includes all the same features as Power9 plus any features specific
6215ffd83dbSDimitry Andric   // to the Power10 core.
6225ffd83dbSDimitry Andric   if (CPU == "pwr10" || CPU == "power10") {
6235ffd83dbSDimitry Andric     initFeatureMap(Features, Diags, "pwr9", FeaturesVec);
6245ffd83dbSDimitry Andric     addP10SpecificFeatures(Features);
6255ffd83dbSDimitry Andric   }
6265ffd83dbSDimitry Andric 
627*36b606aeSDimitry Andric   // Power11 includes all the same features as Power10 plus any features
628*36b606aeSDimitry Andric   // specific to the Power11 core.
629*36b606aeSDimitry Andric   if (CPU == "pwr11" || CPU == "power11") {
630*36b606aeSDimitry Andric     initFeatureMap(Features, Diags, "pwr10", FeaturesVec);
631*36b606aeSDimitry Andric     addP11SpecificFeatures(Features);
632*36b606aeSDimitry Andric   }
633*36b606aeSDimitry Andric 
634*36b606aeSDimitry Andric   // Future CPU should include all of the features of Power 11 as well as any
635480093f4SDimitry Andric   // additional features (yet to be determined) specific to it.
636480093f4SDimitry Andric   if (CPU == "future") {
637*36b606aeSDimitry Andric     initFeatureMap(Features, Diags, "pwr11", FeaturesVec);
638480093f4SDimitry Andric     addFutureSpecificFeatures(Features);
639480093f4SDimitry Andric   }
640480093f4SDimitry Andric 
6410b57cec5SDimitry Andric   if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
6420b57cec5SDimitry Andric     return false;
6430b57cec5SDimitry Andric 
64404eeddc0SDimitry Andric   if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) &&
645349cc55cSDimitry Andric       llvm::is_contained(FeaturesVec, "+float128")) {
64604eeddc0SDimitry Andric     // We have __float128 on PPC but not pre-VSX targets.
6470b57cec5SDimitry Andric     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
6480b57cec5SDimitry Andric     return false;
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric 
651349cc55cSDimitry Andric   if (!(ArchDefs & ArchDefinePwr10)) {
65281ad6265SDimitry Andric     if (llvm::is_contained(FeaturesVec, "+mma")) {
653349cc55cSDimitry Andric       // MMA operations are not available pre-Power10.
654e8d8bef9SDimitry Andric       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;
655e8d8bef9SDimitry Andric       return false;
656e8d8bef9SDimitry Andric     }
65781ad6265SDimitry Andric     if (llvm::is_contained(FeaturesVec, "+pcrel")) {
658349cc55cSDimitry Andric       // PC-Relative instructions are not available pre-Power10,
659349cc55cSDimitry Andric       // and these instructions also require prefixed instructions support.
660349cc55cSDimitry Andric       Diags.Report(diag::err_opt_not_valid_without_opt)
661349cc55cSDimitry Andric           << "-mpcrel"
662349cc55cSDimitry Andric           << "-mcpu=pwr10 -mprefixed";
663349cc55cSDimitry Andric       return false;
664349cc55cSDimitry Andric     }
66581ad6265SDimitry Andric     if (llvm::is_contained(FeaturesVec, "+prefixed")) {
666349cc55cSDimitry Andric       // Prefixed instructions are not available pre-Power10.
667349cc55cSDimitry Andric       Diags.Report(diag::err_opt_not_valid_without_opt) << "-mprefixed"
668349cc55cSDimitry Andric                                                         << "-mcpu=pwr10";
669349cc55cSDimitry Andric       return false;
670349cc55cSDimitry Andric     }
67181ad6265SDimitry Andric     if (llvm::is_contained(FeaturesVec, "+paired-vector-memops")) {
672349cc55cSDimitry Andric       // Paired vector memops are not available pre-Power10.
673349cc55cSDimitry Andric       Diags.Report(diag::err_opt_not_valid_without_opt)
674349cc55cSDimitry Andric           << "-mpaired-vector-memops"
675349cc55cSDimitry Andric           << "-mcpu=pwr10";
676349cc55cSDimitry Andric       return false;
677349cc55cSDimitry Andric     }
678349cc55cSDimitry Andric   }
679e8d8bef9SDimitry Andric 
680fe6060f1SDimitry Andric   if (!(ArchDefs & ArchDefinePwr8) &&
681349cc55cSDimitry Andric       llvm::is_contained(FeaturesVec, "+rop-protect")) {
682fe6060f1SDimitry Andric     // We can turn on ROP Protect on Power 8 and above.
683fe6060f1SDimitry Andric     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU;
684fe6060f1SDimitry Andric     return false;
685fe6060f1SDimitry Andric   }
686fe6060f1SDimitry Andric 
687fe6060f1SDimitry Andric   if (!(ArchDefs & ArchDefinePwr8) &&
688349cc55cSDimitry Andric       llvm::is_contained(FeaturesVec, "+privileged")) {
689fe6060f1SDimitry Andric     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU;
690fe6060f1SDimitry Andric     return false;
691fe6060f1SDimitry Andric   }
692fe6060f1SDimitry Andric 
6930b57cec5SDimitry Andric   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
6940b57cec5SDimitry Andric }
6950b57cec5SDimitry Andric 
6965ffd83dbSDimitry Andric // Add any Power10 specific features.
6975ffd83dbSDimitry Andric void PPCTargetInfo::addP10SpecificFeatures(
6985ffd83dbSDimitry Andric     llvm::StringMap<bool> &Features) const {
6995ffd83dbSDimitry Andric   Features["htm"] = false; // HTM was removed for P10.
700e8d8bef9SDimitry Andric   Features["paired-vector-memops"] = true;
701e8d8bef9SDimitry Andric   Features["mma"] = true;
7025ffd83dbSDimitry Andric   Features["power10-vector"] = true;
7035ffd83dbSDimitry Andric   Features["pcrelative-memops"] = true;
704fe6060f1SDimitry Andric   Features["prefix-instrs"] = true;
705fe6060f1SDimitry Andric   Features["isa-v31-instructions"] = true;
7065ffd83dbSDimitry Andric }
7075ffd83dbSDimitry Andric 
708*36b606aeSDimitry Andric // Add any Power11 specific features.
709*36b606aeSDimitry Andric void PPCTargetInfo::addP11SpecificFeatures(
710*36b606aeSDimitry Andric     llvm::StringMap<bool> &Features) const {}
711*36b606aeSDimitry Andric 
712480093f4SDimitry Andric // Add features specific to the "Future" CPU.
713480093f4SDimitry Andric void PPCTargetInfo::addFutureSpecificFeatures(
7140eae32dcSDimitry Andric     llvm::StringMap<bool> &Features) const {}
715480093f4SDimitry Andric 
7160b57cec5SDimitry Andric bool PPCTargetInfo::hasFeature(StringRef Feature) const {
7170b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
7180b57cec5SDimitry Andric       .Case("powerpc", true)
7190b57cec5SDimitry Andric       .Case("altivec", HasAltivec)
7200b57cec5SDimitry Andric       .Case("vsx", HasVSX)
72181ad6265SDimitry Andric       .Case("crbits", UseCRBits)
7220b57cec5SDimitry Andric       .Case("power8-vector", HasP8Vector)
7230b57cec5SDimitry Andric       .Case("crypto", HasP8Crypto)
7240b57cec5SDimitry Andric       .Case("direct-move", HasDirectMove)
7250b57cec5SDimitry Andric       .Case("htm", HasHTM)
7260b57cec5SDimitry Andric       .Case("bpermd", HasBPERMD)
7270b57cec5SDimitry Andric       .Case("extdiv", HasExtDiv)
7280b57cec5SDimitry Andric       .Case("float128", HasFloat128)
7290b57cec5SDimitry Andric       .Case("power9-vector", HasP9Vector)
730e8d8bef9SDimitry Andric       .Case("paired-vector-memops", PairedVectorMemops)
7315ffd83dbSDimitry Andric       .Case("power10-vector", HasP10Vector)
7325ffd83dbSDimitry Andric       .Case("pcrelative-memops", HasPCRelativeMemops)
733fe6060f1SDimitry Andric       .Case("prefix-instrs", HasPrefixInstrs)
7340b57cec5SDimitry Andric       .Case("spe", HasSPE)
735e8d8bef9SDimitry Andric       .Case("mma", HasMMA)
736fe6060f1SDimitry Andric       .Case("rop-protect", HasROPProtect)
737fe6060f1SDimitry Andric       .Case("privileged", HasPrivileged)
7385f757f3fSDimitry Andric       .Case("aix-small-local-exec-tls", HasAIXSmallLocalExecTLS)
7390fca6ea1SDimitry Andric       .Case("aix-small-local-dynamic-tls", HasAIXSmallLocalDynamicTLS)
740349cc55cSDimitry Andric       .Case("isa-v206-instructions", IsISA2_06)
741fe6060f1SDimitry Andric       .Case("isa-v207-instructions", IsISA2_07)
742fe6060f1SDimitry Andric       .Case("isa-v30-instructions", IsISA3_0)
743fe6060f1SDimitry Andric       .Case("isa-v31-instructions", IsISA3_1)
74481ad6265SDimitry Andric       .Case("quadword-atomics", HasQuadwordAtomics)
7450fca6ea1SDimitry Andric       .Case("aix-shared-lib-tls-model-opt", HasAIXShLibTLSModelOpt)
7460fca6ea1SDimitry Andric       .Case("longcall", UseLongCalls)
7470b57cec5SDimitry Andric       .Default(false);
7480b57cec5SDimitry Andric }
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
7510b57cec5SDimitry Andric                                       StringRef Name, bool Enabled) const {
7520b57cec5SDimitry Andric   if (Enabled) {
753e8d8bef9SDimitry Andric     if (Name == "efpu2")
754e8d8bef9SDimitry Andric       Features["spe"] = true;
7550b57cec5SDimitry Andric     // If we're enabling any of the vsx based features then enable vsx and
7560b57cec5SDimitry Andric     // altivec. We'll diagnose any problems later.
7570b57cec5SDimitry Andric     bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
7580b57cec5SDimitry Andric                              .Case("vsx", true)
7590b57cec5SDimitry Andric                              .Case("direct-move", true)
7600b57cec5SDimitry Andric                              .Case("power8-vector", true)
7610b57cec5SDimitry Andric                              .Case("power9-vector", true)
762e8d8bef9SDimitry Andric                              .Case("paired-vector-memops", true)
7635ffd83dbSDimitry Andric                              .Case("power10-vector", true)
7640b57cec5SDimitry Andric                              .Case("float128", true)
765e8d8bef9SDimitry Andric                              .Case("mma", true)
7660b57cec5SDimitry Andric                              .Default(false);
7670b57cec5SDimitry Andric     if (FeatureHasVSX)
7680b57cec5SDimitry Andric       Features["vsx"] = Features["altivec"] = true;
7690b57cec5SDimitry Andric     if (Name == "power9-vector")
7700b57cec5SDimitry Andric       Features["power8-vector"] = true;
7715ffd83dbSDimitry Andric     else if (Name == "power10-vector")
7725ffd83dbSDimitry Andric       Features["power8-vector"] = Features["power9-vector"] = true;
7735ffd83dbSDimitry Andric     if (Name == "pcrel")
7745ffd83dbSDimitry Andric       Features["pcrelative-memops"] = true;
775fe6060f1SDimitry Andric     else if (Name == "prefixed")
776fe6060f1SDimitry Andric       Features["prefix-instrs"] = true;
7775ffd83dbSDimitry Andric     else
7780b57cec5SDimitry Andric       Features[Name] = true;
7790b57cec5SDimitry Andric   } else {
780e8d8bef9SDimitry Andric     if (Name == "spe")
781e8d8bef9SDimitry Andric       Features["efpu2"] = false;
7820b57cec5SDimitry Andric     // If we're disabling altivec or vsx go ahead and disable all of the vsx
7830b57cec5SDimitry Andric     // features.
7840b57cec5SDimitry Andric     if ((Name == "altivec") || (Name == "vsx"))
7850b57cec5SDimitry Andric       Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
7865ffd83dbSDimitry Andric           Features["float128"] = Features["power9-vector"] =
787e8d8bef9SDimitry Andric               Features["paired-vector-memops"] = Features["mma"] =
7885ffd83dbSDimitry Andric                   Features["power10-vector"] = false;
7890b57cec5SDimitry Andric     if (Name == "power8-vector")
790e8d8bef9SDimitry Andric       Features["power9-vector"] = Features["paired-vector-memops"] =
791e8d8bef9SDimitry Andric           Features["mma"] = Features["power10-vector"] = false;
7925ffd83dbSDimitry Andric     else if (Name == "power9-vector")
793e8d8bef9SDimitry Andric       Features["paired-vector-memops"] = Features["mma"] =
7945ffd83dbSDimitry Andric           Features["power10-vector"] = false;
7955ffd83dbSDimitry Andric     if (Name == "pcrel")
7965ffd83dbSDimitry Andric       Features["pcrelative-memops"] = false;
797fe6060f1SDimitry Andric     else if (Name == "prefixed")
798fe6060f1SDimitry Andric       Features["prefix-instrs"] = false;
7995ffd83dbSDimitry Andric     else
8000b57cec5SDimitry Andric       Features[Name] = false;
8010b57cec5SDimitry Andric   }
8020b57cec5SDimitry Andric }
8030b57cec5SDimitry Andric 
8045f757f3fSDimitry Andric // Make sure that registers are added in the correct array index which should be
8055f757f3fSDimitry Andric // the DWARF number for PPC registers.
8060b57cec5SDimitry Andric const char *const PPCTargetInfo::GCCRegNames[] = {
8070b57cec5SDimitry Andric     "r0",  "r1",     "r2",   "r3",      "r4",      "r5",  "r6",  "r7",  "r8",
8080b57cec5SDimitry Andric     "r9",  "r10",    "r11",  "r12",     "r13",     "r14", "r15", "r16", "r17",
8090b57cec5SDimitry Andric     "r18", "r19",    "r20",  "r21",     "r22",     "r23", "r24", "r25", "r26",
8100b57cec5SDimitry Andric     "r27", "r28",    "r29",  "r30",     "r31",     "f0",  "f1",  "f2",  "f3",
8110b57cec5SDimitry Andric     "f4",  "f5",     "f6",   "f7",      "f8",      "f9",  "f10", "f11", "f12",
8120b57cec5SDimitry Andric     "f13", "f14",    "f15",  "f16",     "f17",     "f18", "f19", "f20", "f21",
8130b57cec5SDimitry Andric     "f22", "f23",    "f24",  "f25",     "f26",     "f27", "f28", "f29", "f30",
8140b57cec5SDimitry Andric     "f31", "mq",     "lr",   "ctr",     "ap",      "cr0", "cr1", "cr2", "cr3",
8150b57cec5SDimitry Andric     "cr4", "cr5",    "cr6",  "cr7",     "xer",     "v0",  "v1",  "v2",  "v3",
8160b57cec5SDimitry Andric     "v4",  "v5",     "v6",   "v7",      "v8",      "v9",  "v10", "v11", "v12",
8170b57cec5SDimitry Andric     "v13", "v14",    "v15",  "v16",     "v17",     "v18", "v19", "v20", "v21",
8180b57cec5SDimitry Andric     "v22", "v23",    "v24",  "v25",     "v26",     "v27", "v28", "v29", "v30",
8190b57cec5SDimitry Andric     "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
8200b57cec5SDimitry Andric };
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
823bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
8240b57cec5SDimitry Andric }
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
8270b57cec5SDimitry Andric     // While some of these aliases do map to different registers
8280b57cec5SDimitry Andric     // they still share the same register name.
82904eeddc0SDimitry Andric     {{"0"}, "r0"},     {{"1", "sp"}, "r1"}, {{"2"}, "r2"},
83004eeddc0SDimitry Andric     {{"3"}, "r3"},     {{"4"}, "r4"},       {{"5"}, "r5"},
83104eeddc0SDimitry Andric     {{"6"}, "r6"},     {{"7"}, "r7"},       {{"8"}, "r8"},
83204eeddc0SDimitry Andric     {{"9"}, "r9"},     {{"10"}, "r10"},     {{"11"}, "r11"},
83304eeddc0SDimitry Andric     {{"12"}, "r12"},   {{"13"}, "r13"},     {{"14"}, "r14"},
83404eeddc0SDimitry Andric     {{"15"}, "r15"},   {{"16"}, "r16"},     {{"17"}, "r17"},
83504eeddc0SDimitry Andric     {{"18"}, "r18"},   {{"19"}, "r19"},     {{"20"}, "r20"},
83604eeddc0SDimitry Andric     {{"21"}, "r21"},   {{"22"}, "r22"},     {{"23"}, "r23"},
83704eeddc0SDimitry Andric     {{"24"}, "r24"},   {{"25"}, "r25"},     {{"26"}, "r26"},
83804eeddc0SDimitry Andric     {{"27"}, "r27"},   {{"28"}, "r28"},     {{"29"}, "r29"},
83904eeddc0SDimitry Andric     {{"30"}, "r30"},   {{"31"}, "r31"},     {{"fr0"}, "f0"},
84004eeddc0SDimitry Andric     {{"fr1"}, "f1"},   {{"fr2"}, "f2"},     {{"fr3"}, "f3"},
84104eeddc0SDimitry Andric     {{"fr4"}, "f4"},   {{"fr5"}, "f5"},     {{"fr6"}, "f6"},
84204eeddc0SDimitry Andric     {{"fr7"}, "f7"},   {{"fr8"}, "f8"},     {{"fr9"}, "f9"},
84304eeddc0SDimitry Andric     {{"fr10"}, "f10"}, {{"fr11"}, "f11"},   {{"fr12"}, "f12"},
84404eeddc0SDimitry Andric     {{"fr13"}, "f13"}, {{"fr14"}, "f14"},   {{"fr15"}, "f15"},
84504eeddc0SDimitry Andric     {{"fr16"}, "f16"}, {{"fr17"}, "f17"},   {{"fr18"}, "f18"},
84604eeddc0SDimitry Andric     {{"fr19"}, "f19"}, {{"fr20"}, "f20"},   {{"fr21"}, "f21"},
84704eeddc0SDimitry Andric     {{"fr22"}, "f22"}, {{"fr23"}, "f23"},   {{"fr24"}, "f24"},
84804eeddc0SDimitry Andric     {{"fr25"}, "f25"}, {{"fr26"}, "f26"},   {{"fr27"}, "f27"},
84904eeddc0SDimitry Andric     {{"fr28"}, "f28"}, {{"fr29"}, "f29"},   {{"fr30"}, "f30"},
85004eeddc0SDimitry Andric     {{"fr31"}, "f31"}, {{"cc"}, "cr0"},
8510b57cec5SDimitry Andric };
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
854bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegAliases);
8550b57cec5SDimitry Andric }
8560b57cec5SDimitry Andric 
8575f757f3fSDimitry Andric // PPC ELFABIv2 DWARF Definition "Table 2.26. Mappings of Common Registers".
8580b57cec5SDimitry Andric // vs0 ~ vs31 is mapping to 32 - 63,
8590b57cec5SDimitry Andric // vs32 ~ vs63 is mapping to 77 - 108.
8605f757f3fSDimitry Andric // And this mapping applies to all OSes which run on powerpc.
8610b57cec5SDimitry Andric const TargetInfo::AddlRegName GCCAddlRegNames[] = {
8620b57cec5SDimitry Andric     // Table of additional register names to use in user input.
8630b57cec5SDimitry Andric     {{"vs0"}, 32},   {{"vs1"}, 33},   {{"vs2"}, 34},   {{"vs3"}, 35},
8640b57cec5SDimitry Andric     {{"vs4"}, 36},   {{"vs5"}, 37},   {{"vs6"}, 38},   {{"vs7"}, 39},
8650b57cec5SDimitry Andric     {{"vs8"}, 40},   {{"vs9"}, 41},   {{"vs10"}, 42},  {{"vs11"}, 43},
8660b57cec5SDimitry Andric     {{"vs12"}, 44},  {{"vs13"}, 45},  {{"vs14"}, 46},  {{"vs15"}, 47},
8670b57cec5SDimitry Andric     {{"vs16"}, 48},  {{"vs17"}, 49},  {{"vs18"}, 50},  {{"vs19"}, 51},
8680b57cec5SDimitry Andric     {{"vs20"}, 52},  {{"vs21"}, 53},  {{"vs22"}, 54},  {{"vs23"}, 55},
8690b57cec5SDimitry Andric     {{"vs24"}, 56},  {{"vs25"}, 57},  {{"vs26"}, 58},  {{"vs27"}, 59},
8700b57cec5SDimitry Andric     {{"vs28"}, 60},  {{"vs29"}, 61},  {{"vs30"}, 62},  {{"vs31"}, 63},
8710b57cec5SDimitry Andric     {{"vs32"}, 77},  {{"vs33"}, 78},  {{"vs34"}, 79},  {{"vs35"}, 80},
8720b57cec5SDimitry Andric     {{"vs36"}, 81},  {{"vs37"}, 82},  {{"vs38"}, 83},  {{"vs39"}, 84},
8730b57cec5SDimitry Andric     {{"vs40"}, 85},  {{"vs41"}, 86},  {{"vs42"}, 87},  {{"vs43"}, 88},
8740b57cec5SDimitry Andric     {{"vs44"}, 89},  {{"vs45"}, 90},  {{"vs46"}, 91},  {{"vs47"}, 92},
8750b57cec5SDimitry Andric     {{"vs48"}, 93},  {{"vs49"}, 94},  {{"vs50"}, 95},  {{"vs51"}, 96},
8760b57cec5SDimitry Andric     {{"vs52"}, 97},  {{"vs53"}, 98},  {{"vs54"}, 99},  {{"vs55"}, 100},
8770b57cec5SDimitry Andric     {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104},
8780b57cec5SDimitry Andric     {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108},
8790b57cec5SDimitry Andric };
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
882bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCAddlRegNames);
8830b57cec5SDimitry Andric }
8840b57cec5SDimitry Andric 
8850b57cec5SDimitry Andric static constexpr llvm::StringLiteral ValidCPUNames[] = {
8860b57cec5SDimitry Andric     {"generic"},   {"440"},     {"450"},         {"601"},     {"602"},
8870b57cec5SDimitry Andric     {"603"},       {"603e"},    {"603ev"},       {"604"},     {"604e"},
8880b57cec5SDimitry Andric     {"620"},       {"630"},     {"g3"},          {"7400"},    {"g4"},
889f8e1cfadSDimitry Andric     {"7450"},      {"g4+"},     {"750"},         {"8548"},    {"970"},
890e8d8bef9SDimitry Andric     {"g5"},        {"a2"},      {"e500"},        {"e500mc"},  {"e5500"},
891e8d8bef9SDimitry Andric     {"power3"},    {"pwr3"},    {"power4"},      {"pwr4"},    {"power5"},
892e8d8bef9SDimitry Andric     {"pwr5"},      {"power5x"}, {"pwr5x"},       {"power6"},  {"pwr6"},
893e8d8bef9SDimitry Andric     {"power6x"},   {"pwr6x"},   {"power7"},      {"pwr7"},    {"power8"},
894e8d8bef9SDimitry Andric     {"pwr8"},      {"power9"},  {"pwr9"},        {"power10"}, {"pwr10"},
895*36b606aeSDimitry Andric     {"power11"},   {"pwr11"},   {"powerpc"},     {"ppc"},     {"ppc32"},
896*36b606aeSDimitry Andric     {"powerpc64"}, {"ppc64"},   {"powerpc64le"}, {"ppc64le"}, {"future"}};
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
899349cc55cSDimitry Andric   return llvm::is_contained(ValidCPUNames, Name);
9000b57cec5SDimitry Andric }
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
9030b57cec5SDimitry Andric   Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
9040b57cec5SDimitry Andric }
9050b57cec5SDimitry Andric 
906fe6060f1SDimitry Andric void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
9070b57cec5SDimitry Andric   if (HasAltivec)
9080b57cec5SDimitry Andric     Opts.AltiVec = 1;
909fe6060f1SDimitry Andric   TargetInfo::adjust(Diags, Opts);
9100b57cec5SDimitry Andric   if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
9110b57cec5SDimitry Andric     LongDoubleFormat = Opts.PPCIEEELongDouble
9120b57cec5SDimitry Andric                            ? &llvm::APFloat::IEEEquad()
9130b57cec5SDimitry Andric                            : &llvm::APFloat::PPCDoubleDouble();
914fe6060f1SDimitry Andric   Opts.IEEE128 = 1;
915972a253aSDimitry Andric   if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI &&
916972a253aSDimitry Andric       HasQuadwordAtomics)
917972a253aSDimitry Andric     MaxAtomicInlineWidth = 128;
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
921bdd1243dSDimitry Andric   return llvm::ArrayRef(BuiltinInfo,
922bdd1243dSDimitry Andric                         clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin);
9230b57cec5SDimitry Andric }
9240fca6ea1SDimitry Andric 
9250fca6ea1SDimitry Andric bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const {
9260fca6ea1SDimitry Andric   llvm::Triple Triple = getTriple();
9270fca6ea1SDimitry Andric   if (Triple.isOSAIX()) {
9280fca6ea1SDimitry Andric #define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP,      \
9290fca6ea1SDimitry Andric                         VALUE)                                                 \
9300fca6ea1SDimitry Andric   .Case(NAME, true)
9310fca6ea1SDimitry Andric     return llvm::StringSwitch<bool>(FeatureStr)
9320fca6ea1SDimitry Andric #include "llvm/TargetParser/PPCTargetParser.def"
9330fca6ea1SDimitry Andric         .Default(false);
9340fca6ea1SDimitry Andric   }
9350fca6ea1SDimitry Andric 
9360fca6ea1SDimitry Andric   assert(Triple.isOSLinux() &&
9370fca6ea1SDimitry Andric          "__builtin_cpu_supports() is only supported for AIX and Linux.");
9380fca6ea1SDimitry Andric 
9390fca6ea1SDimitry Andric #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true)
9400fca6ea1SDimitry Andric   return llvm::StringSwitch<bool>(FeatureStr)
9410fca6ea1SDimitry Andric #include "llvm/TargetParser/PPCTargetParser.def"
9420fca6ea1SDimitry Andric       .Default(false);
9430fca6ea1SDimitry Andric }
9440fca6ea1SDimitry Andric 
9450fca6ea1SDimitry Andric bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const {
9460fca6ea1SDimitry Andric   llvm::Triple Triple = getTriple();
9470fca6ea1SDimitry Andric   assert((Triple.isOSAIX() || Triple.isOSLinux()) &&
9480fca6ea1SDimitry Andric          "__builtin_cpu_is() is only supported for AIX and Linux.");
9490fca6ea1SDimitry Andric 
9500fca6ea1SDimitry Andric #define PPC_CPU(NAME, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD,       \
9510fca6ea1SDimitry Andric                 AIXID)                                                         \
9520fca6ea1SDimitry Andric   .Case(NAME, {Linux_SUPPORT_METHOD, AIX_SUPPORT_METHOD})
9530fca6ea1SDimitry Andric 
9540fca6ea1SDimitry Andric   std::pair<unsigned, unsigned> SuppportMethod =
9550fca6ea1SDimitry Andric       llvm::StringSwitch<std::pair<unsigned, unsigned>>(CPUName)
9560fca6ea1SDimitry Andric #include "llvm/TargetParser/PPCTargetParser.def"
9570fca6ea1SDimitry Andric           .Default({BUILTIN_PPC_UNSUPPORTED, BUILTIN_PPC_UNSUPPORTED});
9580fca6ea1SDimitry Andric   return Triple.isOSLinux()
9590fca6ea1SDimitry Andric              ? (SuppportMethod.first != BUILTIN_PPC_UNSUPPORTED)
9600fca6ea1SDimitry Andric              : (SuppportMethod.second != BUILTIN_PPC_UNSUPPORTED);
9610fca6ea1SDimitry Andric }
962