1 //===--- Targets.cpp - Implement 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 construction of a TargetInfo object from a
10 // target triple.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Targets.h"
15 
16 #include "Targets/AArch64.h"
17 #include "Targets/AMDGPU.h"
18 #include "Targets/ARC.h"
19 #include "Targets/ARM.h"
20 #include "Targets/AVR.h"
21 #include "Targets/BPF.h"
22 #include "Targets/CSKY.h"
23 #include "Targets/DirectX.h"
24 #include "Targets/Hexagon.h"
25 #include "Targets/Lanai.h"
26 #include "Targets/Le64.h"
27 #include "Targets/LoongArch.h"
28 #include "Targets/M68k.h"
29 #include "Targets/MSP430.h"
30 #include "Targets/Mips.h"
31 #include "Targets/NVPTX.h"
32 #include "Targets/OSTargets.h"
33 #include "Targets/PNaCl.h"
34 #include "Targets/PPC.h"
35 #include "Targets/RISCV.h"
36 #include "Targets/SPIR.h"
37 #include "Targets/Sparc.h"
38 #include "Targets/SystemZ.h"
39 #include "Targets/TCE.h"
40 #include "Targets/VE.h"
41 #include "Targets/WebAssembly.h"
42 #include "Targets/X86.h"
43 #include "Targets/XCore.h"
44 #include "clang/Basic/Diagnostic.h"
45 #include "llvm/ADT/StringExtras.h"
46 #include "llvm/ADT/Triple.h"
47 
48 using namespace clang;
49 
50 namespace clang {
51 namespace targets {
52 //===----------------------------------------------------------------------===//
53 //  Common code shared among targets.
54 //===----------------------------------------------------------------------===//
55 
56 /// DefineStd - Define a macro name and standard variants.  For example if
57 /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
58 /// when in GNU mode.
59 void DefineStd(MacroBuilder &Builder, StringRef MacroName,
60                const LangOptions &Opts) {
61   assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
62 
63   // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
64   // in the user's namespace.
65   if (Opts.GNUMode)
66     Builder.defineMacro(MacroName);
67 
68   // Define __unix.
69   Builder.defineMacro("__" + MacroName);
70 
71   // Define __unix__.
72   Builder.defineMacro("__" + MacroName + "__");
73 }
74 
75 void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, bool Tuning) {
76   Builder.defineMacro("__" + CPUName);
77   Builder.defineMacro("__" + CPUName + "__");
78   if (Tuning)
79     Builder.defineMacro("__tune_" + CPUName + "__");
80 }
81 
82 void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
83   // Mingw and cygwin define __declspec(a) to __attribute__((a)).  Clang
84   // supports __declspec natively under -fdeclspec (also enabled with
85   // -fms-extensions), but we define a no-op __declspec macro anyway for
86   // pre-processor compatibility.
87   if (Opts.DeclSpecKeyword)
88     Builder.defineMacro("__declspec", "__declspec");
89   else
90     Builder.defineMacro("__declspec(a)", "__attribute__((a))");
91 
92   if (!Opts.MicrosoftExt) {
93     // Provide macros for all the calling convention keywords.  Provide both
94     // single and double underscore prefixed variants.  These are available on
95     // x64 as well as x86, even though they have no effect.
96     const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"};
97     for (const char *CC : CCs) {
98       std::string GCCSpelling = "__attribute__((__";
99       GCCSpelling += CC;
100       GCCSpelling += "__))";
101       Builder.defineMacro(Twine("_") + CC, GCCSpelling);
102       Builder.defineMacro(Twine("__") + CC, GCCSpelling);
103     }
104   }
105 }
106 
107 //===----------------------------------------------------------------------===//
108 // Driver code
109 //===----------------------------------------------------------------------===//
110 
111 TargetInfo *AllocateTarget(const llvm::Triple &Triple,
112                            const TargetOptions &Opts) {
113   llvm::Triple::OSType os = Triple.getOS();
114 
115   switch (Triple.getArch()) {
116   default:
117     return nullptr;
118 
119   case llvm::Triple::arc:
120     return new ARCTargetInfo(Triple, Opts);
121 
122   case llvm::Triple::xcore:
123     return new XCoreTargetInfo(Triple, Opts);
124 
125   case llvm::Triple::hexagon:
126     if (os == llvm::Triple::Linux &&
127         Triple.getEnvironment() == llvm::Triple::Musl)
128       return new LinuxTargetInfo<HexagonTargetInfo>(Triple, Opts);
129     return new HexagonTargetInfo(Triple, Opts);
130 
131   case llvm::Triple::lanai:
132     return new LanaiTargetInfo(Triple, Opts);
133 
134   case llvm::Triple::aarch64_32:
135     if (Triple.isOSDarwin())
136       return new DarwinAArch64TargetInfo(Triple, Opts);
137 
138     return nullptr;
139   case llvm::Triple::aarch64:
140     if (Triple.isOSDarwin())
141       return new DarwinAArch64TargetInfo(Triple, Opts);
142 
143     switch (os) {
144     case llvm::Triple::CloudABI:
145       return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts);
146     case llvm::Triple::FreeBSD:
147       return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
148     case llvm::Triple::Fuchsia:
149       return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts);
150     case llvm::Triple::Linux:
151       return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts);
152     case llvm::Triple::NetBSD:
153       return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
154     case llvm::Triple::OpenBSD:
155       return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
156     case llvm::Triple::Win32:
157       switch (Triple.getEnvironment()) {
158       case llvm::Triple::GNU:
159         return new MinGWARM64TargetInfo(Triple, Opts);
160       case llvm::Triple::MSVC:
161       default: // Assume MSVC for unknown environments
162         return new MicrosoftARM64TargetInfo(Triple, Opts);
163       }
164     default:
165       return new AArch64leTargetInfo(Triple, Opts);
166     }
167 
168   case llvm::Triple::aarch64_be:
169     switch (os) {
170     case llvm::Triple::FreeBSD:
171       return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
172     case llvm::Triple::Fuchsia:
173       return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts);
174     case llvm::Triple::Linux:
175       return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts);
176     case llvm::Triple::NetBSD:
177       return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
178     default:
179       return new AArch64beTargetInfo(Triple, Opts);
180     }
181 
182   case llvm::Triple::arm:
183   case llvm::Triple::thumb:
184     if (Triple.isOSBinFormatMachO())
185       return new DarwinARMTargetInfo(Triple, Opts);
186 
187     switch (os) {
188     case llvm::Triple::CloudABI:
189       return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts);
190     case llvm::Triple::Linux:
191       return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts);
192     case llvm::Triple::FreeBSD:
193       return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
194     case llvm::Triple::NetBSD:
195       return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
196     case llvm::Triple::OpenBSD:
197       return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
198     case llvm::Triple::RTEMS:
199       return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts);
200     case llvm::Triple::NaCl:
201       return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts);
202     case llvm::Triple::Win32:
203       switch (Triple.getEnvironment()) {
204       case llvm::Triple::Cygnus:
205         return new CygwinARMTargetInfo(Triple, Opts);
206       case llvm::Triple::GNU:
207         return new MinGWARMTargetInfo(Triple, Opts);
208       case llvm::Triple::Itanium:
209         return new ItaniumWindowsARMleTargetInfo(Triple, Opts);
210       case llvm::Triple::MSVC:
211       default: // Assume MSVC for unknown environments
212         return new MicrosoftARMleTargetInfo(Triple, Opts);
213       }
214     default:
215       return new ARMleTargetInfo(Triple, Opts);
216     }
217 
218   case llvm::Triple::armeb:
219   case llvm::Triple::thumbeb:
220     if (Triple.isOSDarwin())
221       return new DarwinARMTargetInfo(Triple, Opts);
222 
223     switch (os) {
224     case llvm::Triple::Linux:
225       return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts);
226     case llvm::Triple::FreeBSD:
227       return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
228     case llvm::Triple::NetBSD:
229       return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
230     case llvm::Triple::OpenBSD:
231       return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
232     case llvm::Triple::RTEMS:
233       return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts);
234     case llvm::Triple::NaCl:
235       return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts);
236     default:
237       return new ARMbeTargetInfo(Triple, Opts);
238     }
239 
240   case llvm::Triple::avr:
241     return new AVRTargetInfo(Triple, Opts);
242   case llvm::Triple::bpfeb:
243   case llvm::Triple::bpfel:
244     return new BPFTargetInfo(Triple, Opts);
245 
246   case llvm::Triple::msp430:
247     return new MSP430TargetInfo(Triple, Opts);
248 
249   case llvm::Triple::mips:
250     switch (os) {
251     case llvm::Triple::Linux:
252       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
253     case llvm::Triple::RTEMS:
254       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
255     case llvm::Triple::FreeBSD:
256       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
257     case llvm::Triple::NetBSD:
258       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
259     default:
260       return new MipsTargetInfo(Triple, Opts);
261     }
262 
263   case llvm::Triple::mipsel:
264     switch (os) {
265     case llvm::Triple::Linux:
266       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
267     case llvm::Triple::RTEMS:
268       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
269     case llvm::Triple::FreeBSD:
270       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
271     case llvm::Triple::NetBSD:
272       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
273     case llvm::Triple::NaCl:
274       return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts);
275     default:
276       return new MipsTargetInfo(Triple, Opts);
277     }
278 
279   case llvm::Triple::mips64:
280     switch (os) {
281     case llvm::Triple::Linux:
282       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
283     case llvm::Triple::RTEMS:
284       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
285     case llvm::Triple::FreeBSD:
286       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
287     case llvm::Triple::NetBSD:
288       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
289     case llvm::Triple::OpenBSD:
290       return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
291     default:
292       return new MipsTargetInfo(Triple, Opts);
293     }
294 
295   case llvm::Triple::mips64el:
296     switch (os) {
297     case llvm::Triple::Linux:
298       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
299     case llvm::Triple::RTEMS:
300       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
301     case llvm::Triple::FreeBSD:
302       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
303     case llvm::Triple::NetBSD:
304       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
305     case llvm::Triple::OpenBSD:
306       return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
307     default:
308       return new MipsTargetInfo(Triple, Opts);
309     }
310 
311   case llvm::Triple::m68k:
312     switch (os) {
313     case llvm::Triple::Linux:
314       return new LinuxTargetInfo<M68kTargetInfo>(Triple, Opts);
315     case llvm::Triple::NetBSD:
316       return new NetBSDTargetInfo<M68kTargetInfo>(Triple, Opts);
317     default:
318       return new M68kTargetInfo(Triple, Opts);
319     }
320 
321   case llvm::Triple::le32:
322     switch (os) {
323     case llvm::Triple::NaCl:
324       return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts);
325     default:
326       return nullptr;
327     }
328 
329   case llvm::Triple::le64:
330     return new Le64TargetInfo(Triple, Opts);
331 
332   case llvm::Triple::ppc:
333     if (Triple.isOSDarwin())
334       return new DarwinPPC32TargetInfo(Triple, Opts);
335     switch (os) {
336     case llvm::Triple::Linux:
337       return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
338     case llvm::Triple::FreeBSD:
339       return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
340     case llvm::Triple::NetBSD:
341       return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
342     case llvm::Triple::OpenBSD:
343       return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
344     case llvm::Triple::RTEMS:
345       return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts);
346     case llvm::Triple::AIX:
347       return new AIXPPC32TargetInfo(Triple, Opts);
348     default:
349       return new PPC32TargetInfo(Triple, Opts);
350     }
351 
352   case llvm::Triple::ppcle:
353     switch (os) {
354     case llvm::Triple::Linux:
355       return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
356     case llvm::Triple::FreeBSD:
357       return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
358     default:
359       return new PPC32TargetInfo(Triple, Opts);
360     }
361 
362   case llvm::Triple::ppc64:
363     if (Triple.isOSDarwin())
364       return new DarwinPPC64TargetInfo(Triple, Opts);
365     switch (os) {
366     case llvm::Triple::Linux:
367       return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
368     case llvm::Triple::Lv2:
369       return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts);
370     case llvm::Triple::FreeBSD:
371       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
372     case llvm::Triple::NetBSD:
373       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
374     case llvm::Triple::OpenBSD:
375       return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
376     case llvm::Triple::AIX:
377       return new AIXPPC64TargetInfo(Triple, Opts);
378     default:
379       return new PPC64TargetInfo(Triple, Opts);
380     }
381 
382   case llvm::Triple::ppc64le:
383     switch (os) {
384     case llvm::Triple::Linux:
385       return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
386     case llvm::Triple::FreeBSD:
387       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
388     case llvm::Triple::NetBSD:
389       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
390     case llvm::Triple::OpenBSD:
391       return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
392     default:
393       return new PPC64TargetInfo(Triple, Opts);
394     }
395 
396   case llvm::Triple::nvptx:
397     return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32);
398   case llvm::Triple::nvptx64:
399     return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64);
400 
401   case llvm::Triple::amdgcn:
402   case llvm::Triple::r600:
403     return new AMDGPUTargetInfo(Triple, Opts);
404 
405   case llvm::Triple::riscv32:
406     // TODO: add cases for NetBSD, RTEMS once tested.
407     switch (os) {
408     case llvm::Triple::FreeBSD:
409       return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts);
410     case llvm::Triple::Linux:
411       return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts);
412     default:
413       return new RISCV32TargetInfo(Triple, Opts);
414     }
415 
416   case llvm::Triple::riscv64:
417     // TODO: add cases for NetBSD, RTEMS once tested.
418     switch (os) {
419     case llvm::Triple::FreeBSD:
420       return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
421     case llvm::Triple::OpenBSD:
422       return new OpenBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
423     case llvm::Triple::Fuchsia:
424       return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts);
425     case llvm::Triple::Linux:
426       return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
427     default:
428       return new RISCV64TargetInfo(Triple, Opts);
429     }
430 
431   case llvm::Triple::sparc:
432     switch (os) {
433     case llvm::Triple::Linux:
434       return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts);
435     case llvm::Triple::Solaris:
436       return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts);
437     case llvm::Triple::NetBSD:
438       return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
439     case llvm::Triple::RTEMS:
440       return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts);
441     default:
442       return new SparcV8TargetInfo(Triple, Opts);
443     }
444 
445   // The 'sparcel' architecture copies all the above cases except for Solaris.
446   case llvm::Triple::sparcel:
447     switch (os) {
448     case llvm::Triple::Linux:
449       return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
450     case llvm::Triple::NetBSD:
451       return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
452     case llvm::Triple::RTEMS:
453       return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
454     default:
455       return new SparcV8elTargetInfo(Triple, Opts);
456     }
457 
458   case llvm::Triple::sparcv9:
459     switch (os) {
460     case llvm::Triple::Linux:
461       return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts);
462     case llvm::Triple::Solaris:
463       return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts);
464     case llvm::Triple::NetBSD:
465       return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
466     case llvm::Triple::OpenBSD:
467       return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
468     case llvm::Triple::FreeBSD:
469       return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
470     default:
471       return new SparcV9TargetInfo(Triple, Opts);
472     }
473 
474   case llvm::Triple::systemz:
475     switch (os) {
476     case llvm::Triple::Linux:
477       return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts);
478     case llvm::Triple::ZOS:
479       return new ZOSTargetInfo<SystemZTargetInfo>(Triple, Opts);
480     default:
481       return new SystemZTargetInfo(Triple, Opts);
482     }
483 
484   case llvm::Triple::tce:
485     return new TCETargetInfo(Triple, Opts);
486 
487   case llvm::Triple::tcele:
488     return new TCELETargetInfo(Triple, Opts);
489 
490   case llvm::Triple::x86:
491     if (Triple.isOSDarwin())
492       return new DarwinI386TargetInfo(Triple, Opts);
493 
494     switch (os) {
495     case llvm::Triple::Ananas:
496       return new AnanasTargetInfo<X86_32TargetInfo>(Triple, Opts);
497     case llvm::Triple::CloudABI:
498       return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts);
499     case llvm::Triple::Linux: {
500       switch (Triple.getEnvironment()) {
501       default:
502         return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts);
503       case llvm::Triple::Android:
504         return new AndroidX86_32TargetInfo(Triple, Opts);
505       }
506     }
507     case llvm::Triple::DragonFly:
508       return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
509     case llvm::Triple::NetBSD:
510       return new NetBSDI386TargetInfo(Triple, Opts);
511     case llvm::Triple::OpenBSD:
512       return new OpenBSDI386TargetInfo(Triple, Opts);
513     case llvm::Triple::FreeBSD:
514       return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
515     case llvm::Triple::Fuchsia:
516       return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts);
517     case llvm::Triple::KFreeBSD:
518       return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
519     case llvm::Triple::Minix:
520       return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts);
521     case llvm::Triple::Solaris:
522       return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts);
523     case llvm::Triple::Win32: {
524       switch (Triple.getEnvironment()) {
525       case llvm::Triple::Cygnus:
526         return new CygwinX86_32TargetInfo(Triple, Opts);
527       case llvm::Triple::GNU:
528         return new MinGWX86_32TargetInfo(Triple, Opts);
529       case llvm::Triple::Itanium:
530       case llvm::Triple::MSVC:
531       default: // Assume MSVC for unknown environments
532         return new MicrosoftX86_32TargetInfo(Triple, Opts);
533       }
534     }
535     case llvm::Triple::Haiku:
536       return new HaikuX86_32TargetInfo(Triple, Opts);
537     case llvm::Triple::RTEMS:
538       return new RTEMSX86_32TargetInfo(Triple, Opts);
539     case llvm::Triple::NaCl:
540       return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts);
541     case llvm::Triple::ELFIAMCU:
542       return new MCUX86_32TargetInfo(Triple, Opts);
543     case llvm::Triple::Hurd:
544       return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts);
545     default:
546       return new X86_32TargetInfo(Triple, Opts);
547     }
548 
549   case llvm::Triple::x86_64:
550     if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
551       return new DarwinX86_64TargetInfo(Triple, Opts);
552 
553     switch (os) {
554     case llvm::Triple::Ananas:
555       return new AnanasTargetInfo<X86_64TargetInfo>(Triple, Opts);
556     case llvm::Triple::CloudABI:
557       return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts);
558     case llvm::Triple::Linux: {
559       switch (Triple.getEnvironment()) {
560       default:
561         return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts);
562       case llvm::Triple::Android:
563         return new AndroidX86_64TargetInfo(Triple, Opts);
564       }
565     }
566     case llvm::Triple::DragonFly:
567       return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
568     case llvm::Triple::NetBSD:
569       return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
570     case llvm::Triple::OpenBSD:
571       return new OpenBSDX86_64TargetInfo(Triple, Opts);
572     case llvm::Triple::FreeBSD:
573       return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
574     case llvm::Triple::Fuchsia:
575       return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts);
576     case llvm::Triple::KFreeBSD:
577       return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
578     case llvm::Triple::Solaris:
579       return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts);
580     case llvm::Triple::Win32: {
581       switch (Triple.getEnvironment()) {
582       case llvm::Triple::Cygnus:
583         return new CygwinX86_64TargetInfo(Triple, Opts);
584       case llvm::Triple::GNU:
585         return new MinGWX86_64TargetInfo(Triple, Opts);
586       case llvm::Triple::MSVC:
587       default: // Assume MSVC for unknown environments
588         return new MicrosoftX86_64TargetInfo(Triple, Opts);
589       }
590     }
591     case llvm::Triple::Haiku:
592       return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts);
593     case llvm::Triple::NaCl:
594       return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts);
595     case llvm::Triple::PS4:
596       return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
597     case llvm::Triple::PS5:
598       return new PS5OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
599     default:
600       return new X86_64TargetInfo(Triple, Opts);
601     }
602 
603   case llvm::Triple::spir: {
604     if (os != llvm::Triple::UnknownOS ||
605         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
606       return nullptr;
607     return new SPIR32TargetInfo(Triple, Opts);
608   }
609   case llvm::Triple::spir64: {
610     if (os != llvm::Triple::UnknownOS ||
611         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
612       return nullptr;
613     return new SPIR64TargetInfo(Triple, Opts);
614   }
615   case llvm::Triple::spirv32: {
616     if (os != llvm::Triple::UnknownOS ||
617         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
618       return nullptr;
619     return new SPIRV32TargetInfo(Triple, Opts);
620   }
621   case llvm::Triple::spirv64: {
622     if (os != llvm::Triple::UnknownOS ||
623         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
624       return nullptr;
625     return new SPIRV64TargetInfo(Triple, Opts);
626   }
627   case llvm::Triple::wasm32:
628     if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
629         Triple.getVendor() != llvm::Triple::UnknownVendor ||
630         !Triple.isOSBinFormatWasm())
631       return nullptr;
632     switch (os) {
633       case llvm::Triple::WASI:
634         return new WASITargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
635       case llvm::Triple::Emscripten:
636         return new EmscriptenTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
637       case llvm::Triple::UnknownOS:
638         return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
639       default:
640         return nullptr;
641     }
642   case llvm::Triple::wasm64:
643     if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
644         Triple.getVendor() != llvm::Triple::UnknownVendor ||
645         !Triple.isOSBinFormatWasm())
646       return nullptr;
647     switch (os) {
648       case llvm::Triple::WASI:
649         return new WASITargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
650       case llvm::Triple::Emscripten:
651         return new EmscriptenTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
652       case llvm::Triple::UnknownOS:
653         return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
654       default:
655         return nullptr;
656     }
657 
658   case llvm::Triple::dxil:
659     return new DirectXTargetInfo(Triple,Opts);
660   case llvm::Triple::renderscript32:
661     return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
662   case llvm::Triple::renderscript64:
663     return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts);
664 
665   case llvm::Triple::ve:
666     return new LinuxTargetInfo<VETargetInfo>(Triple, Opts);
667 
668   case llvm::Triple::csky:
669     switch (os) {
670     case llvm::Triple::Linux:
671       return new LinuxTargetInfo<CSKYTargetInfo>(Triple, Opts);
672     default:
673       return new CSKYTargetInfo(Triple, Opts);
674     }
675   case llvm::Triple::loongarch32:
676     switch (os) {
677     case llvm::Triple::Linux:
678       return new LinuxTargetInfo<LoongArch32TargetInfo>(Triple, Opts);
679     default:
680       return new LoongArch32TargetInfo(Triple, Opts);
681     }
682   case llvm::Triple::loongarch64:
683     switch (os) {
684     case llvm::Triple::Linux:
685       return new LinuxTargetInfo<LoongArch64TargetInfo>(Triple, Opts);
686     default:
687       return new LoongArch64TargetInfo(Triple, Opts);
688     }
689   }
690 }
691 } // namespace targets
692 } // namespace clang
693 
694 using namespace clang::targets;
695 /// CreateTargetInfo - Return the target info object for the specified target
696 /// options.
697 TargetInfo *
698 TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
699                              const std::shared_ptr<TargetOptions> &Opts) {
700   llvm::Triple Triple(Opts->Triple);
701 
702   // Construct the target
703   std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts));
704   if (!Target) {
705     Diags.Report(diag::err_target_unknown_triple) << Triple.str();
706     return nullptr;
707   }
708   Target->TargetOpts = Opts;
709 
710   // Set the target CPU if specified.
711   if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
712     Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
713     SmallVector<StringRef, 32> ValidList;
714     Target->fillValidCPUList(ValidList);
715     if (!ValidList.empty())
716       Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", ");
717     return nullptr;
718   }
719 
720   // Check the TuneCPU name if specified.
721   if (!Opts->TuneCPU.empty() &&
722       !Target->isValidTuneCPUName(Opts->TuneCPU)) {
723     Diags.Report(diag::err_target_unknown_cpu) << Opts->TuneCPU;
724     SmallVector<StringRef, 32> ValidList;
725     Target->fillValidTuneCPUList(ValidList);
726     if (!ValidList.empty())
727       Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", ");
728     return nullptr;
729   }
730 
731   // Set the target ABI if specified.
732   if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
733     Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
734     return nullptr;
735   }
736 
737   // Set the fp math unit.
738   if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
739     Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
740     return nullptr;
741   }
742 
743   // Compute the default target features, we need the target to handle this
744   // because features may have dependencies on one another.
745   if (!Target->initFeatureMap(Opts->FeatureMap, Diags, Opts->CPU,
746                               Opts->FeaturesAsWritten))
747     return nullptr;
748 
749   // Add the features to the compile options.
750   Opts->Features.clear();
751   for (const auto &F : Opts->FeatureMap)
752     Opts->Features.push_back((F.getValue() ? "+" : "-") + F.getKey().str());
753   // Sort here, so we handle the features in a predictable order. (This matters
754   // when we're dealing with features that overlap.)
755   llvm::sort(Opts->Features);
756 
757   if (!Target->handleTargetFeatures(Opts->Features, Diags))
758     return nullptr;
759 
760   Target->setSupportedOpenCLOpts();
761   Target->setCommandLineOpenCLOpts();
762   Target->setMaxAtomicWidth();
763 
764   if (!Opts->DarwinTargetVariantTriple.empty())
765     Target->DarwinTargetVariantTriple =
766         llvm::Triple(Opts->DarwinTargetVariantTriple);
767 
768   if (!Target->validateTarget(Diags))
769     return nullptr;
770 
771   Target->CheckFixedPointBits();
772 
773   return Target.release();
774 }
775 /// validateOpenCLTarget  - Check that OpenCL target has valid
776 /// options setting based on OpenCL version.
777 bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
778                                       DiagnosticsEngine &Diags) const {
779   const llvm::StringMap<bool> &OpenCLFeaturesMap = getSupportedOpenCLOpts();
780 
781   auto diagnoseNotSupportedCore = [&](llvm::StringRef Name, auto... OptArgs) {
782     if (OpenCLOptions::isOpenCLOptionCoreIn(Opts, OptArgs...) &&
783         !hasFeatureEnabled(OpenCLFeaturesMap, Name))
784       Diags.Report(diag::warn_opencl_unsupported_core_feature)
785           << Name << Opts.OpenCLCPlusPlus
786           << Opts.getOpenCLVersionTuple().getAsString();
787   };
788 #define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
789   diagnoseNotSupportedCore(#Ext, __VA_ARGS__);
790 #include "clang/Basic/OpenCLExtensions.def"
791 
792   // Validate that feature macros are set properly for OpenCL C 3.0.
793   // In other cases assume that target is always valid.
794   if (Opts.getOpenCLCompatibleVersion() < 300)
795     return true;
796 
797   return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) &&
798          OpenCLOptions::diagnoseFeatureExtensionDifferences(*this, Diags);
799 }
800