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