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