1321369Sdim//===- Support/TargetRegistry.h - Target Registration -----------*- C++ -*-===//
2226584Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6226584Sdim//
7226584Sdim//===----------------------------------------------------------------------===//
8226584Sdim//
9226584Sdim// This file exposes the TargetRegistry interface, which tools can use to access
10226584Sdim// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
11226584Sdim// which have been registered.
12226584Sdim//
13226584Sdim// Target specific class implementations should register themselves using the
14226584Sdim// appropriate TargetRegistry interfaces.
15226584Sdim//
16226584Sdim//===----------------------------------------------------------------------===//
17226584Sdim
18226584Sdim#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
19226584Sdim#define LLVM_SUPPORT_TARGETREGISTRY_H
20226584Sdim
21341825Sdim#include "llvm-c/DisassemblerTypes.h"
22309124Sdim#include "llvm/ADT/Optional.h"
23321369Sdim#include "llvm/ADT/StringRef.h"
24249423Sdim#include "llvm/ADT/Triple.h"
25321369Sdim#include "llvm/ADT/iterator_range.h"
26226584Sdim#include "llvm/Support/CodeGen.h"
27321369Sdim#include "llvm/Support/ErrorHandling.h"
28288943Sdim#include "llvm/Support/FormattedStream.h"
29321369Sdim#include <algorithm>
30249423Sdim#include <cassert>
31321369Sdim#include <cstddef>
32321369Sdim#include <iterator>
33288943Sdim#include <memory>
34226584Sdim#include <string>
35226584Sdim
36226584Sdimnamespace llvm {
37321369Sdim
38288943Sdimclass AsmPrinter;
39288943Sdimclass MCAsmBackend;
40288943Sdimclass MCAsmInfo;
41288943Sdimclass MCAsmParser;
42288943Sdimclass MCCodeEmitter;
43288943Sdimclass MCContext;
44288943Sdimclass MCDisassembler;
45321369Sdimclass MCInstPrinter;
46288943Sdimclass MCInstrAnalysis;
47288943Sdimclass MCInstrInfo;
48341825Sdimclass MCObjectWriter;
49288943Sdimclass MCRegisterInfo;
50321369Sdimclass MCRelocationInfo;
51288943Sdimclass MCStreamer;
52288943Sdimclass MCSubtargetInfo;
53288943Sdimclass MCSymbolizer;
54288943Sdimclass MCTargetAsmParser;
55288943Sdimclass MCTargetOptions;
56288943Sdimclass MCTargetStreamer;
57321369Sdimclass raw_ostream;
58321369Sdimclass raw_pwrite_stream;
59288943Sdimclass TargetMachine;
60288943Sdimclass TargetOptions;
61226584Sdim
62288943SdimMCStreamer *createNullStreamer(MCContext &Ctx);
63341825Sdim// Takes ownership of \p TAB and \p CE.
64226584Sdim
65341825Sdim/// Create a machine code streamer which will print out assembly for the native
66341825Sdim/// target, suitable for compiling with a native assembler.
67341825Sdim///
68341825Sdim/// \param InstPrint - If given, the instruction printer to use. If not given
69341825Sdim/// the MCInst representation will be printed.  This method takes ownership of
70341825Sdim/// InstPrint.
71341825Sdim///
72341825Sdim/// \param CE - If given, a code emitter to use to show the instruction
73341825Sdim/// encoding inline with the assembly. This method takes ownership of \p CE.
74341825Sdim///
75341825Sdim/// \param TAB - If given, a target asm backend to use to show the fixup
76341825Sdim/// information in conjunction with encoding information. This method takes
77341825Sdim/// ownership of \p TAB.
78341825Sdim///
79341825Sdim/// \param ShowInst - Whether to show the MCInst representation inline with
80341825Sdim/// the assembly.
81341825SdimMCStreamer *
82341825SdimcreateAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS,
83341825Sdim                  bool isVerboseAsm, bool useDwarfDirectory,
84341825Sdim                  MCInstPrinter *InstPrint, std::unique_ptr<MCCodeEmitter> &&CE,
85341825Sdim                  std::unique_ptr<MCAsmBackend> &&TAB, bool ShowInst);
86341825Sdim
87327952SdimMCStreamer *createELFStreamer(MCContext &Ctx,
88327952Sdim                              std::unique_ptr<MCAsmBackend> &&TAB,
89341825Sdim                              std::unique_ptr<MCObjectWriter> &&OW,
90327952Sdim                              std::unique_ptr<MCCodeEmitter> &&CE,
91288943Sdim                              bool RelaxAll);
92327952SdimMCStreamer *createMachOStreamer(MCContext &Ctx,
93327952Sdim                                std::unique_ptr<MCAsmBackend> &&TAB,
94341825Sdim                                std::unique_ptr<MCObjectWriter> &&OW,
95327952Sdim                                std::unique_ptr<MCCodeEmitter> &&CE,
96288943Sdim                                bool RelaxAll, bool DWARFMustBeAtTheEnd,
97288943Sdim                                bool LabelSections = false);
98327952SdimMCStreamer *createWasmStreamer(MCContext &Ctx,
99327952Sdim                               std::unique_ptr<MCAsmBackend> &&TAB,
100341825Sdim                               std::unique_ptr<MCObjectWriter> &&OW,
101327952Sdim                               std::unique_ptr<MCCodeEmitter> &&CE,
102321369Sdim                               bool RelaxAll);
103353358SdimMCStreamer *createXCOFFStreamer(MCContext &Ctx,
104353358Sdim                                std::unique_ptr<MCAsmBackend> &&TAB,
105353358Sdim                                std::unique_ptr<MCObjectWriter> &&OW,
106353358Sdim                                std::unique_ptr<MCCodeEmitter> &&CE,
107353358Sdim                                bool RelaxAll);
108261991Sdim
109288943SdimMCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
110261991Sdim
111288943SdimMCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
112288943Sdim                                 LLVMSymbolLookupCallback SymbolLookUp,
113288943Sdim                                 void *DisInfo, MCContext *Ctx,
114288943Sdim                                 std::unique_ptr<MCRelocationInfo> &&RelInfo);
115226584Sdim
116288943Sdim/// Target - Wrapper for Target specific information.
117288943Sdim///
118288943Sdim/// For registration purposes, this is a POD type so that targets can be
119288943Sdim/// registered without the use of static constructors.
120288943Sdim///
121288943Sdim/// Targets should implement a single global instance of this class (which
122288943Sdim/// will be zero initialized), and pass that instance to the TargetRegistry as
123288943Sdim/// part of their initialization.
124288943Sdimclass Target {
125288943Sdimpublic:
126288943Sdim  friend struct TargetRegistry;
127226584Sdim
128321369Sdim  using ArchMatchFnTy = bool (*)(Triple::ArchType Arch);
129288943Sdim
130321369Sdim  using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI,
131360784Sdim                                           const Triple &TT,
132360784Sdim                                           const MCTargetOptions &Options);
133321369Sdim  using MCInstrInfoCtorFnTy = MCInstrInfo *(*)();
134321369Sdim  using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info);
135321369Sdim  using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT);
136321369Sdim  using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT,
137321369Sdim                                                       StringRef CPU,
138321369Sdim                                                       StringRef Features);
139327952Sdim  using TargetMachineCtorTy = TargetMachine
140327952Sdim      *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
141327952Sdim           const TargetOptions &Options, Optional<Reloc::Model> RM,
142327952Sdim           Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT);
143288943Sdim  // If it weren't for layering issues (this header is in llvm/Support, but
144288943Sdim  // depends on MC?) this should take the Streamer by value rather than rvalue
145288943Sdim  // reference.
146321369Sdim  using AsmPrinterCtorTy = AsmPrinter *(*)(
147288943Sdim      TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
148321369Sdim  using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
149327952Sdim                                               const MCSubtargetInfo &STI,
150321369Sdim                                               const MCRegisterInfo &MRI,
151321369Sdim                                               const MCTargetOptions &Options);
152321369Sdim  using MCAsmParserCtorTy = MCTargetAsmParser *(*)(
153296417Sdim      const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII,
154288943Sdim      const MCTargetOptions &Options);
155321369Sdim  using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T,
156321369Sdim                                                   const MCSubtargetInfo &STI,
157321369Sdim                                                   MCContext &Ctx);
158321369Sdim  using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T,
159321369Sdim                                                 unsigned SyntaxVariant,
160321369Sdim                                                 const MCAsmInfo &MAI,
161321369Sdim                                                 const MCInstrInfo &MII,
162321369Sdim                                                 const MCRegisterInfo &MRI);
163321369Sdim  using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II,
164321369Sdim                                                 const MCRegisterInfo &MRI,
165321369Sdim                                                 MCContext &Ctx);
166327952Sdim  using ELFStreamerCtorTy =
167327952Sdim      MCStreamer *(*)(const Triple &T, MCContext &Ctx,
168327952Sdim                      std::unique_ptr<MCAsmBackend> &&TAB,
169341825Sdim                      std::unique_ptr<MCObjectWriter> &&OW,
170327952Sdim                      std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
171327952Sdim  using MachOStreamerCtorTy =
172327952Sdim      MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
173341825Sdim                      std::unique_ptr<MCObjectWriter> &&OW,
174327952Sdim                      std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
175327952Sdim                      bool DWARFMustBeAtTheEnd);
176327952Sdim  using COFFStreamerCtorTy =
177327952Sdim      MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
178341825Sdim                      std::unique_ptr<MCObjectWriter> &&OW,
179327952Sdim                      std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
180327952Sdim                      bool IncrementalLinkerCompatible);
181327952Sdim  using WasmStreamerCtorTy =
182327952Sdim      MCStreamer *(*)(const Triple &T, MCContext &Ctx,
183327952Sdim                      std::unique_ptr<MCAsmBackend> &&TAB,
184341825Sdim                      std::unique_ptr<MCObjectWriter> &&OW,
185327952Sdim                      std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
186321369Sdim  using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S);
187321369Sdim  using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)(
188288943Sdim      MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
189288943Sdim      bool IsVerboseAsm);
190321369Sdim  using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
191288943Sdim      MCStreamer &S, const MCSubtargetInfo &STI);
192321369Sdim  using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
193321369Sdim                                                       MCContext &Ctx);
194321369Sdim  using MCSymbolizerCtorTy = MCSymbolizer *(*)(
195288943Sdim      const Triple &TT, LLVMOpInfoCallback GetOpInfo,
196288943Sdim      LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
197288943Sdim      std::unique_ptr<MCRelocationInfo> &&RelInfo);
198226584Sdim
199288943Sdimprivate:
200288943Sdim  /// Next - The next registered target in the linked list, maintained by the
201288943Sdim  /// TargetRegistry.
202288943Sdim  Target *Next;
203226584Sdim
204288943Sdim  /// The target function for checking if an architecture is supported.
205288943Sdim  ArchMatchFnTy ArchMatchFn;
206226584Sdim
207288943Sdim  /// Name - The target name.
208288943Sdim  const char *Name;
209226584Sdim
210288943Sdim  /// ShortDesc - A short description of the target.
211288943Sdim  const char *ShortDesc;
212226584Sdim
213327952Sdim  /// BackendName - The name of the backend implementation. This must match the
214327952Sdim  /// name of the 'def X : Target ...' in TableGen.
215327952Sdim  const char *BackendName;
216327952Sdim
217288943Sdim  /// HasJIT - Whether this target supports the JIT.
218288943Sdim  bool HasJIT;
219226584Sdim
220288943Sdim  /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
221288943Sdim  /// registered.
222288943Sdim  MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
223226584Sdim
224288943Sdim  /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
225288943Sdim  /// if registered.
226288943Sdim  MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
227226584Sdim
228288943Sdim  /// MCInstrAnalysisCtorFn - Constructor function for this target's
229288943Sdim  /// MCInstrAnalysis, if registered.
230288943Sdim  MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
231226584Sdim
232288943Sdim  /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
233288943Sdim  /// if registered.
234288943Sdim  MCRegInfoCtorFnTy MCRegInfoCtorFn;
235226584Sdim
236288943Sdim  /// MCSubtargetInfoCtorFn - Constructor function for this target's
237288943Sdim  /// MCSubtargetInfo, if registered.
238288943Sdim  MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
239226584Sdim
240288943Sdim  /// TargetMachineCtorFn - Construction function for this target's
241288943Sdim  /// TargetMachine, if registered.
242288943Sdim  TargetMachineCtorTy TargetMachineCtorFn;
243226584Sdim
244288943Sdim  /// MCAsmBackendCtorFn - Construction function for this target's
245288943Sdim  /// MCAsmBackend, if registered.
246288943Sdim  MCAsmBackendCtorTy MCAsmBackendCtorFn;
247226584Sdim
248288943Sdim  /// MCAsmParserCtorFn - Construction function for this target's
249288943Sdim  /// MCTargetAsmParser, if registered.
250288943Sdim  MCAsmParserCtorTy MCAsmParserCtorFn;
251226584Sdim
252288943Sdim  /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
253288943Sdim  /// if registered.
254288943Sdim  AsmPrinterCtorTy AsmPrinterCtorFn;
255226584Sdim
256288943Sdim  /// MCDisassemblerCtorFn - Construction function for this target's
257288943Sdim  /// MCDisassembler, if registered.
258288943Sdim  MCDisassemblerCtorTy MCDisassemblerCtorFn;
259226584Sdim
260288943Sdim  /// MCInstPrinterCtorFn - Construction function for this target's
261288943Sdim  /// MCInstPrinter, if registered.
262288943Sdim  MCInstPrinterCtorTy MCInstPrinterCtorFn;
263226584Sdim
264288943Sdim  /// MCCodeEmitterCtorFn - Construction function for this target's
265288943Sdim  /// CodeEmitter, if registered.
266288943Sdim  MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
267226584Sdim
268288943Sdim  // Construction functions for the various object formats, if registered.
269321369Sdim  COFFStreamerCtorTy COFFStreamerCtorFn = nullptr;
270321369Sdim  MachOStreamerCtorTy MachOStreamerCtorFn = nullptr;
271321369Sdim  ELFStreamerCtorTy ELFStreamerCtorFn = nullptr;
272321369Sdim  WasmStreamerCtorTy WasmStreamerCtorFn = nullptr;
273226584Sdim
274288943Sdim  /// Construction function for this target's null TargetStreamer, if
275288943Sdim  /// registered (default = nullptr).
276321369Sdim  NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr;
277226584Sdim
278288943Sdim  /// Construction function for this target's asm TargetStreamer, if
279288943Sdim  /// registered (default = nullptr).
280321369Sdim  AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
281276479Sdim
282288943Sdim  /// Construction function for this target's obj TargetStreamer, if
283288943Sdim  /// registered (default = nullptr).
284321369Sdim  ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
285261991Sdim
286288943Sdim  /// MCRelocationInfoCtorFn - Construction function for this target's
287288943Sdim  /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
288321369Sdim  MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr;
289261991Sdim
290288943Sdim  /// MCSymbolizerCtorFn - Construction function for this target's
291288943Sdim  /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
292321369Sdim  MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr;
293226584Sdim
294288943Sdimpublic:
295321369Sdim  Target() = default;
296226584Sdim
297288943Sdim  /// @name Target Information
298288943Sdim  /// @{
299226584Sdim
300288943Sdim  // getNext - Return the next registered target.
301288943Sdim  const Target *getNext() const { return Next; }
302226584Sdim
303288943Sdim  /// getName - Get the target name.
304288943Sdim  const char *getName() const { return Name; }
305226584Sdim
306288943Sdim  /// getShortDescription - Get a short description of the target.
307288943Sdim  const char *getShortDescription() const { return ShortDesc; }
308226584Sdim
309327952Sdim  /// getBackendName - Get the backend name.
310327952Sdim  const char *getBackendName() const { return BackendName; }
311327952Sdim
312288943Sdim  /// @}
313288943Sdim  /// @name Feature Predicates
314288943Sdim  /// @{
315226584Sdim
316288943Sdim  /// hasJIT - Check if this targets supports the just-in-time compilation.
317288943Sdim  bool hasJIT() const { return HasJIT; }
318226584Sdim
319288943Sdim  /// hasTargetMachine - Check if this target supports code generation.
320288943Sdim  bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
321226584Sdim
322288943Sdim  /// hasMCAsmBackend - Check if this target supports .o generation.
323288943Sdim  bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
324226584Sdim
325314564Sdim  /// hasMCAsmParser - Check if this target supports assembly parsing.
326314564Sdim  bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; }
327314564Sdim
328288943Sdim  /// @}
329288943Sdim  /// @name Feature Constructors
330288943Sdim  /// @{
331226584Sdim
332288943Sdim  /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
333288943Sdim  /// target triple.
334288943Sdim  ///
335288943Sdim  /// \param TheTriple This argument is used to determine the target machine
336288943Sdim  /// feature set; it should always be provided. Generally this should be
337288943Sdim  /// either the target triple from the module, or the target triple of the
338288943Sdim  /// host if that does not exist.
339360784Sdim  MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple,
340360784Sdim                             const MCTargetOptions &Options) const {
341288943Sdim    if (!MCAsmInfoCtorFn)
342288943Sdim      return nullptr;
343360784Sdim    return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options);
344288943Sdim  }
345226584Sdim
346288943Sdim  /// createMCInstrInfo - Create a MCInstrInfo implementation.
347288943Sdim  ///
348288943Sdim  MCInstrInfo *createMCInstrInfo() const {
349288943Sdim    if (!MCInstrInfoCtorFn)
350288943Sdim      return nullptr;
351288943Sdim    return MCInstrInfoCtorFn();
352288943Sdim  }
353226584Sdim
354288943Sdim  /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
355288943Sdim  ///
356288943Sdim  MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
357288943Sdim    if (!MCInstrAnalysisCtorFn)
358288943Sdim      return nullptr;
359288943Sdim    return MCInstrAnalysisCtorFn(Info);
360288943Sdim  }
361226584Sdim
362288943Sdim  /// createMCRegInfo - Create a MCRegisterInfo implementation.
363288943Sdim  ///
364288943Sdim  MCRegisterInfo *createMCRegInfo(StringRef TT) const {
365288943Sdim    if (!MCRegInfoCtorFn)
366288943Sdim      return nullptr;
367288943Sdim    return MCRegInfoCtorFn(Triple(TT));
368288943Sdim  }
369226584Sdim
370288943Sdim  /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
371288943Sdim  ///
372288943Sdim  /// \param TheTriple This argument is used to determine the target machine
373288943Sdim  /// feature set; it should always be provided. Generally this should be
374288943Sdim  /// either the target triple from the module, or the target triple of the
375288943Sdim  /// host if that does not exist.
376288943Sdim  /// \param CPU This specifies the name of the target CPU.
377288943Sdim  /// \param Features This specifies the string representation of the
378288943Sdim  /// additional target features.
379288943Sdim  MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU,
380288943Sdim                                         StringRef Features) const {
381288943Sdim    if (!MCSubtargetInfoCtorFn)
382288943Sdim      return nullptr;
383288943Sdim    return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features);
384288943Sdim  }
385226584Sdim
386288943Sdim  /// createTargetMachine - Create a target specific machine implementation
387288943Sdim  /// for the specified \p Triple.
388288943Sdim  ///
389288943Sdim  /// \param TT This argument is used to determine the target machine
390288943Sdim  /// feature set; it should always be provided. Generally this should be
391288943Sdim  /// either the target triple from the module, or the target triple of the
392288943Sdim  /// host if that does not exist.
393327952Sdim  TargetMachine *createTargetMachine(StringRef TT, StringRef CPU,
394327952Sdim                                     StringRef Features,
395327952Sdim                                     const TargetOptions &Options,
396327952Sdim                                     Optional<Reloc::Model> RM,
397327952Sdim                                     Optional<CodeModel::Model> CM = None,
398327952Sdim                                     CodeGenOpt::Level OL = CodeGenOpt::Default,
399327952Sdim                                     bool JIT = false) const {
400288943Sdim    if (!TargetMachineCtorFn)
401288943Sdim      return nullptr;
402288943Sdim    return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM,
403327952Sdim                               CM, OL, JIT);
404288943Sdim  }
405226584Sdim
406288943Sdim  /// createMCAsmBackend - Create a target specific assembly parser.
407327952Sdim  MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI,
408327952Sdim                                   const MCRegisterInfo &MRI,
409327952Sdim                                   const MCTargetOptions &Options) const {
410288943Sdim    if (!MCAsmBackendCtorFn)
411288943Sdim      return nullptr;
412327952Sdim    return MCAsmBackendCtorFn(*this, STI, MRI, Options);
413288943Sdim  }
414226584Sdim
415288943Sdim  /// createMCAsmParser - Create a target specific assembly parser.
416288943Sdim  ///
417288943Sdim  /// \param Parser The target independent parser implementation to use for
418288943Sdim  /// parsing and lexing.
419296417Sdim  MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI,
420288943Sdim                                       MCAsmParser &Parser,
421234353Sdim                                       const MCInstrInfo &MII,
422288943Sdim                                       const MCTargetOptions &Options) const {
423288943Sdim    if (!MCAsmParserCtorFn)
424288943Sdim      return nullptr;
425288943Sdim    return MCAsmParserCtorFn(STI, Parser, MII, Options);
426288943Sdim  }
427226584Sdim
428288943Sdim  /// createAsmPrinter - Create a target specific assembly printer pass.  This
429288943Sdim  /// takes ownership of the MCStreamer object.
430288943Sdim  AsmPrinter *createAsmPrinter(TargetMachine &TM,
431288943Sdim                               std::unique_ptr<MCStreamer> &&Streamer) const {
432288943Sdim    if (!AsmPrinterCtorFn)
433288943Sdim      return nullptr;
434288943Sdim    return AsmPrinterCtorFn(TM, std::move(Streamer));
435288943Sdim  }
436226584Sdim
437288943Sdim  MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
438226584Sdim                                       MCContext &Ctx) const {
439288943Sdim    if (!MCDisassemblerCtorFn)
440288943Sdim      return nullptr;
441288943Sdim    return MCDisassemblerCtorFn(*this, STI, Ctx);
442288943Sdim  }
443226584Sdim
444288943Sdim  MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
445288943Sdim                                     const MCAsmInfo &MAI,
446288943Sdim                                     const MCInstrInfo &MII,
447288943Sdim                                     const MCRegisterInfo &MRI) const {
448288943Sdim    if (!MCInstPrinterCtorFn)
449288943Sdim      return nullptr;
450288943Sdim    return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
451288943Sdim  }
452226584Sdim
453288943Sdim  /// createMCCodeEmitter - Create a target specific code emitter.
454288943Sdim  MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
455288943Sdim                                     const MCRegisterInfo &MRI,
456288943Sdim                                     MCContext &Ctx) const {
457288943Sdim    if (!MCCodeEmitterCtorFn)
458288943Sdim      return nullptr;
459288943Sdim    return MCCodeEmitterCtorFn(II, MRI, Ctx);
460288943Sdim  }
461226584Sdim
462288943Sdim  /// Create a target specific MCStreamer.
463288943Sdim  ///
464288943Sdim  /// \param T The target triple.
465288943Sdim  /// \param Ctx The target context.
466288943Sdim  /// \param TAB The target assembler backend object. Takes ownership.
467341825Sdim  /// \param OW The stream object.
468288943Sdim  /// \param Emitter The target independent assembler object.Takes ownership.
469288943Sdim  /// \param RelaxAll Relax all fixups?
470288943Sdim  MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
471327952Sdim                                     std::unique_ptr<MCAsmBackend> &&TAB,
472341825Sdim                                     std::unique_ptr<MCObjectWriter> &&OW,
473327952Sdim                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
474288943Sdim                                     const MCSubtargetInfo &STI, bool RelaxAll,
475296417Sdim                                     bool IncrementalLinkerCompatible,
476288943Sdim                                     bool DWARFMustBeAtTheEnd) const {
477360784Sdim    MCStreamer *S = nullptr;
478288943Sdim    switch (T.getObjectFormat()) {
479353358Sdim    case Triple::UnknownObjectFormat:
480288943Sdim      llvm_unreachable("Unknown object format");
481288943Sdim    case Triple::COFF:
482288943Sdim      assert(T.isOSWindows() && "only Windows COFF is supported");
483341825Sdim      S = COFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
484341825Sdim                             std::move(Emitter), RelaxAll,
485341825Sdim                             IncrementalLinkerCompatible);
486288943Sdim      break;
487288943Sdim    case Triple::MachO:
488288943Sdim      if (MachOStreamerCtorFn)
489341825Sdim        S = MachOStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
490341825Sdim                                std::move(Emitter), RelaxAll,
491341825Sdim                                DWARFMustBeAtTheEnd);
492288943Sdim      else
493341825Sdim        S = createMachOStreamer(Ctx, std::move(TAB), std::move(OW),
494341825Sdim                                std::move(Emitter), RelaxAll,
495341825Sdim                                DWARFMustBeAtTheEnd);
496288943Sdim      break;
497288943Sdim    case Triple::ELF:
498288943Sdim      if (ELFStreamerCtorFn)
499341825Sdim        S = ELFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
500341825Sdim                              std::move(Emitter), RelaxAll);
501288943Sdim      else
502341825Sdim        S = createELFStreamer(Ctx, std::move(TAB), std::move(OW),
503341825Sdim                              std::move(Emitter), RelaxAll);
504288943Sdim      break;
505321369Sdim    case Triple::Wasm:
506321369Sdim      if (WasmStreamerCtorFn)
507341825Sdim        S = WasmStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
508341825Sdim                               std::move(Emitter), RelaxAll);
509321369Sdim      else
510341825Sdim        S = createWasmStreamer(Ctx, std::move(TAB), std::move(OW),
511341825Sdim                               std::move(Emitter), RelaxAll);
512321369Sdim      break;
513353358Sdim    case Triple::XCOFF:
514360784Sdim      S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
515360784Sdim                              std::move(Emitter), RelaxAll);
516353358Sdim      break;
517276479Sdim    }
518288943Sdim    if (ObjectTargetStreamerCtorFn)
519288943Sdim      ObjectTargetStreamerCtorFn(*S, STI);
520288943Sdim    return S;
521288943Sdim  }
522276479Sdim
523288943Sdim  MCStreamer *createAsmStreamer(MCContext &Ctx,
524288943Sdim                                std::unique_ptr<formatted_raw_ostream> OS,
525288943Sdim                                bool IsVerboseAsm, bool UseDwarfDirectory,
526341825Sdim                                MCInstPrinter *InstPrint,
527341825Sdim                                std::unique_ptr<MCCodeEmitter> &&CE,
528341825Sdim                                std::unique_ptr<MCAsmBackend> &&TAB,
529341825Sdim                                bool ShowInst) const {
530288943Sdim    formatted_raw_ostream &OSRef = *OS;
531341825Sdim    MCStreamer *S = llvm::createAsmStreamer(
532341825Sdim        Ctx, std::move(OS), IsVerboseAsm, UseDwarfDirectory, InstPrint,
533341825Sdim        std::move(CE), std::move(TAB), ShowInst);
534288943Sdim    createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
535288943Sdim    return S;
536288943Sdim  }
537261991Sdim
538288943Sdim  MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
539288943Sdim                                            formatted_raw_ostream &OS,
540288943Sdim                                            MCInstPrinter *InstPrint,
541288943Sdim                                            bool IsVerboseAsm) const {
542288943Sdim    if (AsmTargetStreamerCtorFn)
543288943Sdim      return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm);
544288943Sdim    return nullptr;
545288943Sdim  }
546261991Sdim
547288943Sdim  MCStreamer *createNullStreamer(MCContext &Ctx) const {
548288943Sdim    MCStreamer *S = llvm::createNullStreamer(Ctx);
549288943Sdim    createNullTargetStreamer(*S);
550288943Sdim    return S;
551288943Sdim  }
552226584Sdim
553288943Sdim  MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
554288943Sdim    if (NullTargetStreamerCtorFn)
555288943Sdim      return NullTargetStreamerCtorFn(S);
556288943Sdim    return nullptr;
557288943Sdim  }
558226584Sdim
559288943Sdim  /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
560288943Sdim  ///
561288943Sdim  /// \param TT The target triple.
562288943Sdim  /// \param Ctx The target context.
563288943Sdim  MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
564288943Sdim    MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
565288943Sdim                                    ? MCRelocationInfoCtorFn
566288943Sdim                                    : llvm::createMCRelocationInfo;
567288943Sdim    return Fn(Triple(TT), Ctx);
568288943Sdim  }
569226584Sdim
570288943Sdim  /// createMCSymbolizer - Create a target specific MCSymbolizer.
571288943Sdim  ///
572288943Sdim  /// \param TT The target triple.
573288943Sdim  /// \param GetOpInfo The function to get the symbolic information for
574288943Sdim  /// operands.
575288943Sdim  /// \param SymbolLookUp The function to lookup a symbol name.
576288943Sdim  /// \param DisInfo The pointer to the block of symbolic information for above
577288943Sdim  /// call
578288943Sdim  /// back.
579288943Sdim  /// \param Ctx The target context.
580288943Sdim  /// \param RelInfo The relocation information for this target. Takes
581288943Sdim  /// ownership.
582288943Sdim  MCSymbolizer *
583288943Sdim  createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
584288943Sdim                     LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
585288943Sdim                     MCContext *Ctx,
586288943Sdim                     std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
587288943Sdim    MCSymbolizerCtorTy Fn =
588288943Sdim        MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
589288943Sdim    return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx,
590288943Sdim              std::move(RelInfo));
591288943Sdim  }
592226584Sdim
593288943Sdim  /// @}
594288943Sdim};
595226584Sdim
596288943Sdim/// TargetRegistry - Generic interface to target specific features.
597288943Sdimstruct TargetRegistry {
598288943Sdim  // FIXME: Make this a namespace, probably just move all the Register*
599288943Sdim  // functions into Target (currently they all just set members on the Target
600288943Sdim  // anyway, and Target friends this class so those functions can...
601288943Sdim  // function).
602288943Sdim  TargetRegistry() = delete;
603226584Sdim
604288943Sdim  class iterator
605288943Sdim      : public std::iterator<std::forward_iterator_tag, Target, ptrdiff_t> {
606288943Sdim    friend struct TargetRegistry;
607226584Sdim
608321369Sdim    const Target *Current = nullptr;
609321369Sdim
610321369Sdim    explicit iterator(Target *T) : Current(T) {}
611321369Sdim
612288943Sdim  public:
613321369Sdim    iterator() = default;
614226584Sdim
615288943Sdim    bool operator==(const iterator &x) const { return Current == x.Current; }
616288943Sdim    bool operator!=(const iterator &x) const { return !operator==(x); }
617226584Sdim
618288943Sdim    // Iterator traversal: forward iteration only
619288943Sdim    iterator &operator++() { // Preincrement
620288943Sdim      assert(Current && "Cannot increment end iterator!");
621288943Sdim      Current = Current->getNext();
622288943Sdim      return *this;
623288943Sdim    }
624288943Sdim    iterator operator++(int) { // Postincrement
625288943Sdim      iterator tmp = *this;
626288943Sdim      ++*this;
627288943Sdim      return tmp;
628288943Sdim    }
629226584Sdim
630288943Sdim    const Target &operator*() const {
631288943Sdim      assert(Current && "Cannot dereference end iterator!");
632288943Sdim      return *Current;
633288943Sdim    }
634226584Sdim
635288943Sdim    const Target *operator->() const { return &operator*(); }
636288943Sdim  };
637239462Sdim
638288943Sdim  /// printRegisteredTargetsForVersion - Print the registered targets
639288943Sdim  /// appropriately for inclusion in a tool's version output.
640327952Sdim  static void printRegisteredTargetsForVersion(raw_ostream &OS);
641226584Sdim
642288943Sdim  /// @name Registry Access
643288943Sdim  /// @{
644226584Sdim
645288943Sdim  static iterator_range<iterator> targets();
646226584Sdim
647288943Sdim  /// lookupTarget - Lookup a target based on a target triple.
648288943Sdim  ///
649288943Sdim  /// \param Triple - The triple to use for finding a target.
650288943Sdim  /// \param Error - On failure, an error string describing why no target was
651288943Sdim  /// found.
652288943Sdim  static const Target *lookupTarget(const std::string &Triple,
653288943Sdim                                    std::string &Error);
654226584Sdim
655288943Sdim  /// lookupTarget - Lookup a target based on an architecture name
656288943Sdim  /// and a target triple.  If the architecture name is non-empty,
657288943Sdim  /// then the lookup is done by architecture.  Otherwise, the target
658288943Sdim  /// triple is used.
659288943Sdim  ///
660288943Sdim  /// \param ArchName - The architecture to use for finding a target.
661288943Sdim  /// \param TheTriple - The triple to use for finding a target.  The
662288943Sdim  /// triple is updated with canonical architecture name if a lookup
663288943Sdim  /// by architecture is done.
664288943Sdim  /// \param Error - On failure, an error string describing why no target was
665288943Sdim  /// found.
666288943Sdim  static const Target *lookupTarget(const std::string &ArchName,
667288943Sdim                                    Triple &TheTriple, std::string &Error);
668226584Sdim
669288943Sdim  /// @}
670288943Sdim  /// @name Target Registration
671288943Sdim  /// @{
672226584Sdim
673288943Sdim  /// RegisterTarget - Register the given target. Attempts to register a
674288943Sdim  /// target which has already been registered will be ignored.
675288943Sdim  ///
676288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
677288943Sdim  /// while another thread is attempting to access the registry. Typically
678288943Sdim  /// this is done by initializing all targets at program startup.
679288943Sdim  ///
680288943Sdim  /// @param T - The target being registered.
681288943Sdim  /// @param Name - The target name. This should be a static string.
682288943Sdim  /// @param ShortDesc - A short target description. This should be a static
683288943Sdim  /// string.
684327952Sdim  /// @param BackendName - The name of the backend. This should be a static
685327952Sdim  /// string that is the same for all targets that share a backend
686327952Sdim  /// implementation and must match the name used in the 'def X : Target ...' in
687327952Sdim  /// TableGen.
688288943Sdim  /// @param ArchMatchFn - The arch match checking function for this target.
689288943Sdim  /// @param HasJIT - Whether the target supports JIT code
690288943Sdim  /// generation.
691288943Sdim  static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc,
692327952Sdim                             const char *BackendName,
693288943Sdim                             Target::ArchMatchFnTy ArchMatchFn,
694288943Sdim                             bool HasJIT = false);
695226584Sdim
696288943Sdim  /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
697288943Sdim  /// given target.
698288943Sdim  ///
699288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
700288943Sdim  /// while another thread is attempting to access the registry. Typically
701288943Sdim  /// this is done by initializing all targets at program startup.
702288943Sdim  ///
703288943Sdim  /// @param T - The target being registered.
704288943Sdim  /// @param Fn - A function to construct a MCAsmInfo for the target.
705288943Sdim  static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
706288943Sdim    T.MCAsmInfoCtorFn = Fn;
707288943Sdim  }
708226584Sdim
709288943Sdim  /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
710288943Sdim  /// given target.
711288943Sdim  ///
712288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
713288943Sdim  /// while another thread is attempting to access the registry. Typically
714288943Sdim  /// this is done by initializing all targets at program startup.
715288943Sdim  ///
716288943Sdim  /// @param T - The target being registered.
717288943Sdim  /// @param Fn - A function to construct a MCInstrInfo for the target.
718288943Sdim  static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
719288943Sdim    T.MCInstrInfoCtorFn = Fn;
720288943Sdim  }
721226584Sdim
722288943Sdim  /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
723288943Sdim  /// the given target.
724288943Sdim  static void RegisterMCInstrAnalysis(Target &T,
725288943Sdim                                      Target::MCInstrAnalysisCtorFnTy Fn) {
726288943Sdim    T.MCInstrAnalysisCtorFn = Fn;
727288943Sdim  }
728226584Sdim
729288943Sdim  /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
730288943Sdim  /// given target.
731288943Sdim  ///
732288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
733288943Sdim  /// while another thread is attempting to access the registry. Typically
734288943Sdim  /// this is done by initializing all targets at program startup.
735288943Sdim  ///
736288943Sdim  /// @param T - The target being registered.
737288943Sdim  /// @param Fn - A function to construct a MCRegisterInfo for the target.
738288943Sdim  static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
739288943Sdim    T.MCRegInfoCtorFn = Fn;
740288943Sdim  }
741226584Sdim
742288943Sdim  /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
743288943Sdim  /// the given target.
744288943Sdim  ///
745288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
746288943Sdim  /// while another thread is attempting to access the registry. Typically
747288943Sdim  /// this is done by initializing all targets at program startup.
748288943Sdim  ///
749288943Sdim  /// @param T - The target being registered.
750288943Sdim  /// @param Fn - A function to construct a MCSubtargetInfo for the target.
751288943Sdim  static void RegisterMCSubtargetInfo(Target &T,
752288943Sdim                                      Target::MCSubtargetInfoCtorFnTy Fn) {
753288943Sdim    T.MCSubtargetInfoCtorFn = Fn;
754288943Sdim  }
755226584Sdim
756288943Sdim  /// RegisterTargetMachine - Register a TargetMachine implementation for the
757288943Sdim  /// given target.
758288943Sdim  ///
759288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
760288943Sdim  /// while another thread is attempting to access the registry. Typically
761288943Sdim  /// this is done by initializing all targets at program startup.
762288943Sdim  ///
763288943Sdim  /// @param T - The target being registered.
764288943Sdim  /// @param Fn - A function to construct a TargetMachine for the target.
765288943Sdim  static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) {
766288943Sdim    T.TargetMachineCtorFn = Fn;
767288943Sdim  }
768226584Sdim
769288943Sdim  /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
770288943Sdim  /// given target.
771288943Sdim  ///
772288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
773288943Sdim  /// while another thread is attempting to access the registry. Typically
774288943Sdim  /// this is done by initializing all targets at program startup.
775288943Sdim  ///
776288943Sdim  /// @param T - The target being registered.
777288943Sdim  /// @param Fn - A function to construct an AsmBackend for the target.
778288943Sdim  static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
779288943Sdim    T.MCAsmBackendCtorFn = Fn;
780288943Sdim  }
781226584Sdim
782288943Sdim  /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
783288943Sdim  /// the given target.
784288943Sdim  ///
785288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
786288943Sdim  /// while another thread is attempting to access the registry. Typically
787288943Sdim  /// this is done by initializing all targets at program startup.
788288943Sdim  ///
789288943Sdim  /// @param T - The target being registered.
790288943Sdim  /// @param Fn - A function to construct an MCTargetAsmParser for the target.
791288943Sdim  static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
792288943Sdim    T.MCAsmParserCtorFn = Fn;
793288943Sdim  }
794226584Sdim
795288943Sdim  /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
796288943Sdim  /// target.
797288943Sdim  ///
798288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
799288943Sdim  /// while another thread is attempting to access the registry. Typically
800288943Sdim  /// this is done by initializing all targets at program startup.
801288943Sdim  ///
802288943Sdim  /// @param T - The target being registered.
803288943Sdim  /// @param Fn - A function to construct an AsmPrinter for the target.
804288943Sdim  static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
805288943Sdim    T.AsmPrinterCtorFn = Fn;
806288943Sdim  }
807226584Sdim
808288943Sdim  /// RegisterMCDisassembler - Register a MCDisassembler implementation for
809288943Sdim  /// the given target.
810288943Sdim  ///
811288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
812288943Sdim  /// while another thread is attempting to access the registry. Typically
813288943Sdim  /// this is done by initializing all targets at program startup.
814288943Sdim  ///
815288943Sdim  /// @param T - The target being registered.
816288943Sdim  /// @param Fn - A function to construct an MCDisassembler for the target.
817288943Sdim  static void RegisterMCDisassembler(Target &T,
818288943Sdim                                     Target::MCDisassemblerCtorTy Fn) {
819288943Sdim    T.MCDisassemblerCtorFn = Fn;
820288943Sdim  }
821276479Sdim
822288943Sdim  /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
823288943Sdim  /// given target.
824288943Sdim  ///
825288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
826288943Sdim  /// while another thread is attempting to access the registry. Typically
827288943Sdim  /// this is done by initializing all targets at program startup.
828288943Sdim  ///
829288943Sdim  /// @param T - The target being registered.
830288943Sdim  /// @param Fn - A function to construct an MCInstPrinter for the target.
831288943Sdim  static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) {
832288943Sdim    T.MCInstPrinterCtorFn = Fn;
833288943Sdim  }
834261991Sdim
835288943Sdim  /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
836288943Sdim  /// given target.
837288943Sdim  ///
838288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
839288943Sdim  /// while another thread is attempting to access the registry. Typically
840288943Sdim  /// this is done by initializing all targets at program startup.
841288943Sdim  ///
842288943Sdim  /// @param T - The target being registered.
843288943Sdim  /// @param Fn - A function to construct an MCCodeEmitter for the target.
844288943Sdim  static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) {
845288943Sdim    T.MCCodeEmitterCtorFn = Fn;
846288943Sdim  }
847261991Sdim
848288943Sdim  static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
849288943Sdim    T.COFFStreamerCtorFn = Fn;
850288943Sdim  }
851226584Sdim
852288943Sdim  static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) {
853288943Sdim    T.MachOStreamerCtorFn = Fn;
854288943Sdim  }
855226584Sdim
856288943Sdim  static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
857288943Sdim    T.ELFStreamerCtorFn = Fn;
858288943Sdim  }
859226584Sdim
860321369Sdim  static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) {
861321369Sdim    T.WasmStreamerCtorFn = Fn;
862321369Sdim  }
863321369Sdim
864288943Sdim  static void RegisterNullTargetStreamer(Target &T,
865288943Sdim                                         Target::NullTargetStreamerCtorTy Fn) {
866288943Sdim    T.NullTargetStreamerCtorFn = Fn;
867288943Sdim  }
868288943Sdim
869288943Sdim  static void RegisterAsmTargetStreamer(Target &T,
870288943Sdim                                        Target::AsmTargetStreamerCtorTy Fn) {
871288943Sdim    T.AsmTargetStreamerCtorFn = Fn;
872288943Sdim  }
873288943Sdim
874288943Sdim  static void
875288943Sdim  RegisterObjectTargetStreamer(Target &T,
876288943Sdim                               Target::ObjectTargetStreamerCtorTy Fn) {
877288943Sdim    T.ObjectTargetStreamerCtorFn = Fn;
878288943Sdim  }
879288943Sdim
880288943Sdim  /// RegisterMCRelocationInfo - Register an MCRelocationInfo
881288943Sdim  /// implementation for the given target.
882226584Sdim  ///
883288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
884288943Sdim  /// while another thread is attempting to access the registry. Typically
885288943Sdim  /// this is done by initializing all targets at program startup.
886226584Sdim  ///
887288943Sdim  /// @param T - The target being registered.
888288943Sdim  /// @param Fn - A function to construct an MCRelocationInfo for the target.
889288943Sdim  static void RegisterMCRelocationInfo(Target &T,
890288943Sdim                                       Target::MCRelocationInfoCtorTy Fn) {
891288943Sdim    T.MCRelocationInfoCtorFn = Fn;
892288943Sdim  }
893288943Sdim
894288943Sdim  /// RegisterMCSymbolizer - Register an MCSymbolizer
895288943Sdim  /// implementation for the given target.
896226584Sdim  ///
897288943Sdim  /// Clients are responsible for ensuring that registration doesn't occur
898288943Sdim  /// while another thread is attempting to access the registry. Typically
899288943Sdim  /// this is done by initializing all targets at program startup.
900288943Sdim  ///
901288943Sdim  /// @param T - The target being registered.
902288943Sdim  /// @param Fn - A function to construct an MCSymbolizer for the target.
903288943Sdim  static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) {
904288943Sdim    T.MCSymbolizerCtorFn = Fn;
905288943Sdim  }
906226584Sdim
907288943Sdim  /// @}
908288943Sdim};
909226584Sdim
910288943Sdim//===--------------------------------------------------------------------===//
911226584Sdim
912288943Sdim/// RegisterTarget - Helper template for registering a target, for use in the
913288943Sdim/// target's initialization function. Usage:
914288943Sdim///
915288943Sdim///
916314564Sdim/// Target &getTheFooTarget() { // The global target instance.
917314564Sdim///   static Target TheFooTarget;
918314564Sdim///   return TheFooTarget;
919314564Sdim/// }
920288943Sdim/// extern "C" void LLVMInitializeFooTargetInfo() {
921314564Sdim///   RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo
922327952Sdim///   description", "Foo" /* Backend Name */);
923288943Sdim/// }
924288943Sdimtemplate <Triple::ArchType TargetArchType = Triple::UnknownArch,
925288943Sdim          bool HasJIT = false>
926288943Sdimstruct RegisterTarget {
927327952Sdim  RegisterTarget(Target &T, const char *Name, const char *Desc,
928327952Sdim                 const char *BackendName) {
929327952Sdim    TargetRegistry::RegisterTarget(T, Name, Desc, BackendName, &getArchMatch,
930327952Sdim                                   HasJIT);
931288943Sdim  }
932226584Sdim
933288943Sdim  static bool getArchMatch(Triple::ArchType Arch) {
934288943Sdim    return Arch == TargetArchType;
935288943Sdim  }
936288943Sdim};
937226584Sdim
938288943Sdim/// RegisterMCAsmInfo - Helper template for registering a target assembly info
939288943Sdim/// implementation.  This invokes the static "Create" method on the class to
940288943Sdim/// actually do the construction.  Usage:
941288943Sdim///
942288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
943288943Sdim///   extern Target TheFooTarget;
944288943Sdim///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
945288943Sdim/// }
946288943Sdimtemplate <class MCAsmInfoImpl> struct RegisterMCAsmInfo {
947288943Sdim  RegisterMCAsmInfo(Target &T) {
948288943Sdim    TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
949288943Sdim  }
950226584Sdim
951288943Sdimprivate:
952360784Sdim  static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, const Triple &TT,
953360784Sdim                              const MCTargetOptions &Options) {
954360784Sdim    return new MCAsmInfoImpl(TT, Options);
955288943Sdim  }
956288943Sdim};
957226584Sdim
958288943Sdim/// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
959288943Sdim/// implementation.  This invokes the specified function to do the
960288943Sdim/// construction.  Usage:
961288943Sdim///
962288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
963288943Sdim///   extern Target TheFooTarget;
964288943Sdim///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
965288943Sdim/// }
966288943Sdimstruct RegisterMCAsmInfoFn {
967288943Sdim  RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
968288943Sdim    TargetRegistry::RegisterMCAsmInfo(T, Fn);
969288943Sdim  }
970288943Sdim};
971226584Sdim
972288943Sdim/// RegisterMCInstrInfo - Helper template for registering a target instruction
973288943Sdim/// info implementation.  This invokes the static "Create" method on the class
974288943Sdim/// to actually do the construction.  Usage:
975288943Sdim///
976288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
977288943Sdim///   extern Target TheFooTarget;
978288943Sdim///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
979288943Sdim/// }
980288943Sdimtemplate <class MCInstrInfoImpl> struct RegisterMCInstrInfo {
981288943Sdim  RegisterMCInstrInfo(Target &T) {
982288943Sdim    TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
983288943Sdim  }
984226584Sdim
985288943Sdimprivate:
986288943Sdim  static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); }
987288943Sdim};
988226584Sdim
989288943Sdim/// RegisterMCInstrInfoFn - Helper template for registering a target
990288943Sdim/// instruction info implementation.  This invokes the specified function to
991288943Sdim/// do the construction.  Usage:
992288943Sdim///
993288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
994288943Sdim///   extern Target TheFooTarget;
995288943Sdim///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
996288943Sdim/// }
997288943Sdimstruct RegisterMCInstrInfoFn {
998288943Sdim  RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
999288943Sdim    TargetRegistry::RegisterMCInstrInfo(T, Fn);
1000288943Sdim  }
1001288943Sdim};
1002226584Sdim
1003288943Sdim/// RegisterMCInstrAnalysis - Helper template for registering a target
1004288943Sdim/// instruction analyzer implementation.  This invokes the static "Create"
1005288943Sdim/// method on the class to actually do the construction.  Usage:
1006288943Sdim///
1007288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1008288943Sdim///   extern Target TheFooTarget;
1009288943Sdim///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
1010288943Sdim/// }
1011288943Sdimtemplate <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis {
1012288943Sdim  RegisterMCInstrAnalysis(Target &T) {
1013288943Sdim    TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
1014288943Sdim  }
1015226584Sdim
1016288943Sdimprivate:
1017288943Sdim  static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
1018288943Sdim    return new MCInstrAnalysisImpl(Info);
1019288943Sdim  }
1020288943Sdim};
1021226584Sdim
1022288943Sdim/// RegisterMCInstrAnalysisFn - Helper template for registering a target
1023288943Sdim/// instruction analyzer implementation.  This invokes the specified function
1024288943Sdim/// to do the construction.  Usage:
1025288943Sdim///
1026288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1027288943Sdim///   extern Target TheFooTarget;
1028288943Sdim///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
1029288943Sdim/// }
1030288943Sdimstruct RegisterMCInstrAnalysisFn {
1031288943Sdim  RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
1032288943Sdim    TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
1033288943Sdim  }
1034288943Sdim};
1035226584Sdim
1036288943Sdim/// RegisterMCRegInfo - Helper template for registering a target register info
1037288943Sdim/// implementation.  This invokes the static "Create" method on the class to
1038288943Sdim/// actually do the construction.  Usage:
1039288943Sdim///
1040288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1041288943Sdim///   extern Target TheFooTarget;
1042288943Sdim///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
1043288943Sdim/// }
1044288943Sdimtemplate <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
1045288943Sdim  RegisterMCRegInfo(Target &T) {
1046288943Sdim    TargetRegistry::RegisterMCRegInfo(T, &Allocator);
1047288943Sdim  }
1048226584Sdim
1049288943Sdimprivate:
1050288943Sdim  static MCRegisterInfo *Allocator(const Triple & /*TT*/) {
1051288943Sdim    return new MCRegisterInfoImpl();
1052288943Sdim  }
1053288943Sdim};
1054226584Sdim
1055288943Sdim/// RegisterMCRegInfoFn - Helper template for registering a target register
1056288943Sdim/// info implementation.  This invokes the specified function to do the
1057288943Sdim/// construction.  Usage:
1058288943Sdim///
1059288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1060288943Sdim///   extern Target TheFooTarget;
1061288943Sdim///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
1062288943Sdim/// }
1063288943Sdimstruct RegisterMCRegInfoFn {
1064288943Sdim  RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
1065288943Sdim    TargetRegistry::RegisterMCRegInfo(T, Fn);
1066288943Sdim  }
1067288943Sdim};
1068226584Sdim
1069288943Sdim/// RegisterMCSubtargetInfo - Helper template for registering a target
1070288943Sdim/// subtarget info implementation.  This invokes the static "Create" method
1071288943Sdim/// on the class to actually do the construction.  Usage:
1072288943Sdim///
1073288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1074288943Sdim///   extern Target TheFooTarget;
1075288943Sdim///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
1076288943Sdim/// }
1077288943Sdimtemplate <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo {
1078288943Sdim  RegisterMCSubtargetInfo(Target &T) {
1079288943Sdim    TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
1080288943Sdim  }
1081226584Sdim
1082288943Sdimprivate:
1083288943Sdim  static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/,
1084288943Sdim                                    StringRef /*FS*/) {
1085288943Sdim    return new MCSubtargetInfoImpl();
1086288943Sdim  }
1087288943Sdim};
1088226584Sdim
1089288943Sdim/// RegisterMCSubtargetInfoFn - Helper template for registering a target
1090288943Sdim/// subtarget info implementation.  This invokes the specified function to
1091288943Sdim/// do the construction.  Usage:
1092288943Sdim///
1093288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1094288943Sdim///   extern Target TheFooTarget;
1095288943Sdim///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
1096288943Sdim/// }
1097288943Sdimstruct RegisterMCSubtargetInfoFn {
1098288943Sdim  RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
1099288943Sdim    TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
1100288943Sdim  }
1101288943Sdim};
1102226584Sdim
1103288943Sdim/// RegisterTargetMachine - Helper template for registering a target machine
1104288943Sdim/// implementation, for use in the target machine initialization
1105288943Sdim/// function. Usage:
1106288943Sdim///
1107288943Sdim/// extern "C" void LLVMInitializeFooTarget() {
1108288943Sdim///   extern Target TheFooTarget;
1109288943Sdim///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
1110288943Sdim/// }
1111288943Sdimtemplate <class TargetMachineImpl> struct RegisterTargetMachine {
1112288943Sdim  RegisterTargetMachine(Target &T) {
1113288943Sdim    TargetRegistry::RegisterTargetMachine(T, &Allocator);
1114288943Sdim  }
1115226584Sdim
1116288943Sdimprivate:
1117327952Sdim  static TargetMachine *
1118327952Sdim  Allocator(const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
1119327952Sdim            const TargetOptions &Options, Optional<Reloc::Model> RM,
1120327952Sdim            Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) {
1121327952Sdim    return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT);
1122288943Sdim  }
1123288943Sdim};
1124226584Sdim
1125288943Sdim/// RegisterMCAsmBackend - Helper template for registering a target specific
1126288943Sdim/// assembler backend. Usage:
1127288943Sdim///
1128288943Sdim/// extern "C" void LLVMInitializeFooMCAsmBackend() {
1129288943Sdim///   extern Target TheFooTarget;
1130288943Sdim///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
1131288943Sdim/// }
1132288943Sdimtemplate <class MCAsmBackendImpl> struct RegisterMCAsmBackend {
1133288943Sdim  RegisterMCAsmBackend(Target &T) {
1134288943Sdim    TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
1135288943Sdim  }
1136288943Sdim
1137288943Sdimprivate:
1138327952Sdim  static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI,
1139327952Sdim                                 const MCRegisterInfo &MRI,
1140314564Sdim                                 const MCTargetOptions &Options) {
1141327952Sdim    return new MCAsmBackendImpl(T, STI, MRI);
1142288943Sdim  }
1143288943Sdim};
1144288943Sdim
1145288943Sdim/// RegisterMCAsmParser - Helper template for registering a target specific
1146288943Sdim/// assembly parser, for use in the target machine initialization
1147288943Sdim/// function. Usage:
1148288943Sdim///
1149288943Sdim/// extern "C" void LLVMInitializeFooMCAsmParser() {
1150288943Sdim///   extern Target TheFooTarget;
1151288943Sdim///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
1152288943Sdim/// }
1153288943Sdimtemplate <class MCAsmParserImpl> struct RegisterMCAsmParser {
1154288943Sdim  RegisterMCAsmParser(Target &T) {
1155288943Sdim    TargetRegistry::RegisterMCAsmParser(T, &Allocator);
1156288943Sdim  }
1157288943Sdim
1158288943Sdimprivate:
1159296417Sdim  static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI,
1160296417Sdim                                      MCAsmParser &P, const MCInstrInfo &MII,
1161288943Sdim                                      const MCTargetOptions &Options) {
1162288943Sdim    return new MCAsmParserImpl(STI, P, MII, Options);
1163288943Sdim  }
1164288943Sdim};
1165288943Sdim
1166288943Sdim/// RegisterAsmPrinter - Helper template for registering a target specific
1167288943Sdim/// assembly printer, for use in the target machine initialization
1168288943Sdim/// function. Usage:
1169288943Sdim///
1170288943Sdim/// extern "C" void LLVMInitializeFooAsmPrinter() {
1171288943Sdim///   extern Target TheFooTarget;
1172288943Sdim///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
1173288943Sdim/// }
1174288943Sdimtemplate <class AsmPrinterImpl> struct RegisterAsmPrinter {
1175288943Sdim  RegisterAsmPrinter(Target &T) {
1176288943Sdim    TargetRegistry::RegisterAsmPrinter(T, &Allocator);
1177288943Sdim  }
1178288943Sdim
1179288943Sdimprivate:
1180288943Sdim  static AsmPrinter *Allocator(TargetMachine &TM,
1181288943Sdim                               std::unique_ptr<MCStreamer> &&Streamer) {
1182288943Sdim    return new AsmPrinterImpl(TM, std::move(Streamer));
1183288943Sdim  }
1184288943Sdim};
1185288943Sdim
1186288943Sdim/// RegisterMCCodeEmitter - Helper template for registering a target specific
1187288943Sdim/// machine code emitter, for use in the target initialization
1188288943Sdim/// function. Usage:
1189288943Sdim///
1190288943Sdim/// extern "C" void LLVMInitializeFooMCCodeEmitter() {
1191288943Sdim///   extern Target TheFooTarget;
1192288943Sdim///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
1193288943Sdim/// }
1194288943Sdimtemplate <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter {
1195288943Sdim  RegisterMCCodeEmitter(Target &T) {
1196288943Sdim    TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
1197288943Sdim  }
1198288943Sdim
1199288943Sdimprivate:
1200288943Sdim  static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
1201288943Sdim                                  const MCRegisterInfo & /*MRI*/,
1202288943Sdim                                  MCContext & /*Ctx*/) {
1203288943Sdim    return new MCCodeEmitterImpl();
1204288943Sdim  }
1205288943Sdim};
1206226584Sdim
1207321369Sdim} // end namespace llvm
1208321369Sdim
1209321369Sdim#endif // LLVM_SUPPORT_TARGETREGISTRY_H
1210