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