1 //===- MC/TargetRegistry.h - Target Registration ----------------*- C++ -*-===//
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 exposes the TargetRegistry interface, which tools can use to access
10 // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
11 // which have been registered.
12 //
13 // Target specific class implementations should register themselves using the
14 // appropriate TargetRegistry interfaces.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_MC_TARGETREGISTRY_H
19 #define LLVM_MC_TARGETREGISTRY_H
20 
21 #include "llvm-c/DisassemblerTypes.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/Triple.h"
24 #include "llvm/ADT/iterator_range.h"
25 #include "llvm/MC/MCObjectFileInfo.h"
26 #include "llvm/Support/CodeGen.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/FormattedStream.h"
29 #include <cassert>
30 #include <cstddef>
31 #include <iterator>
32 #include <memory>
33 #include <optional>
34 #include <string>
35 
36 namespace llvm {
37 
38 class AsmPrinter;
39 class MCAsmBackend;
40 class MCAsmInfo;
41 class MCAsmParser;
42 class MCCodeEmitter;
43 class MCContext;
44 class MCDisassembler;
45 class MCInstPrinter;
46 class MCInstrAnalysis;
47 class MCInstrInfo;
48 class MCObjectWriter;
49 class MCRegisterInfo;
50 class MCRelocationInfo;
51 class MCStreamer;
52 class MCSubtargetInfo;
53 class MCSymbolizer;
54 class MCTargetAsmParser;
55 class MCTargetOptions;
56 class MCTargetStreamer;
57 class raw_ostream;
58 class TargetMachine;
59 class TargetOptions;
60 namespace mca {
61 class CustomBehaviour;
62 class InstrPostProcess;
63 class InstrumentManager;
64 struct SourceMgr;
65 } // namespace mca
66 
67 MCStreamer *createNullStreamer(MCContext &Ctx);
68 // Takes ownership of \p TAB and \p CE.
69 
70 /// Create a machine code streamer which will print out assembly for the native
71 /// target, suitable for compiling with a native assembler.
72 ///
73 /// \param InstPrint - If given, the instruction printer to use. If not given
74 /// the MCInst representation will be printed.  This method takes ownership of
75 /// InstPrint.
76 ///
77 /// \param CE - If given, a code emitter to use to show the instruction
78 /// encoding inline with the assembly. This method takes ownership of \p CE.
79 ///
80 /// \param TAB - If given, a target asm backend to use to show the fixup
81 /// information in conjunction with encoding information. This method takes
82 /// ownership of \p TAB.
83 ///
84 /// \param ShowInst - Whether to show the MCInst representation inline with
85 /// the assembly.
86 MCStreamer *
87 createAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS,
88                   bool isVerboseAsm, bool useDwarfDirectory,
89                   MCInstPrinter *InstPrint, std::unique_ptr<MCCodeEmitter> &&CE,
90                   std::unique_ptr<MCAsmBackend> &&TAB, bool ShowInst);
91 
92 MCStreamer *createELFStreamer(MCContext &Ctx,
93                               std::unique_ptr<MCAsmBackend> &&TAB,
94                               std::unique_ptr<MCObjectWriter> &&OW,
95                               std::unique_ptr<MCCodeEmitter> &&CE,
96                               bool RelaxAll);
97 MCStreamer *createMachOStreamer(MCContext &Ctx,
98                                 std::unique_ptr<MCAsmBackend> &&TAB,
99                                 std::unique_ptr<MCObjectWriter> &&OW,
100                                 std::unique_ptr<MCCodeEmitter> &&CE,
101                                 bool RelaxAll, bool DWARFMustBeAtTheEnd,
102                                 bool LabelSections = false);
103 MCStreamer *createWasmStreamer(MCContext &Ctx,
104                                std::unique_ptr<MCAsmBackend> &&TAB,
105                                std::unique_ptr<MCObjectWriter> &&OW,
106                                std::unique_ptr<MCCodeEmitter> &&CE,
107                                bool RelaxAll);
108 MCStreamer *createXCOFFStreamer(MCContext &Ctx,
109                                 std::unique_ptr<MCAsmBackend> &&TAB,
110                                 std::unique_ptr<MCObjectWriter> &&OW,
111                                 std::unique_ptr<MCCodeEmitter> &&CE,
112                                 bool RelaxAll);
113 MCStreamer *createSPIRVStreamer(MCContext &Ctx,
114                                 std::unique_ptr<MCAsmBackend> &&TAB,
115                                 std::unique_ptr<MCObjectWriter> &&OW,
116                                 std::unique_ptr<MCCodeEmitter> &&CE,
117                                 bool RelaxAll);
118 MCStreamer *createDXContainerStreamer(MCContext &Ctx,
119                                       std::unique_ptr<MCAsmBackend> &&TAB,
120                                       std::unique_ptr<MCObjectWriter> &&OW,
121                                       std::unique_ptr<MCCodeEmitter> &&CE,
122                                       bool RelaxAll);
123 
124 MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
125 
126 MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
127                                  LLVMSymbolLookupCallback SymbolLookUp,
128                                  void *DisInfo, MCContext *Ctx,
129                                  std::unique_ptr<MCRelocationInfo> &&RelInfo);
130 
131 mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI,
132                                             const mca::SourceMgr &SrcMgr,
133                                             const MCInstrInfo &MCII);
134 
135 mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI,
136                                               const MCInstrInfo &MCII);
137 
138 mca::InstrumentManager *createInstrumentManager(const MCSubtargetInfo &STI,
139                                                 const MCInstrInfo &MCII);
140 
141 /// Target - Wrapper for Target specific information.
142 ///
143 /// For registration purposes, this is a POD type so that targets can be
144 /// registered without the use of static constructors.
145 ///
146 /// Targets should implement a single global instance of this class (which
147 /// will be zero initialized), and pass that instance to the TargetRegistry as
148 /// part of their initialization.
149 class Target {
150 public:
151   friend struct TargetRegistry;
152 
153   using ArchMatchFnTy = bool (*)(Triple::ArchType Arch);
154 
155   using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI,
156                                            const Triple &TT,
157                                            const MCTargetOptions &Options);
158   using MCObjectFileInfoCtorFnTy = MCObjectFileInfo *(*)(MCContext &Ctx,
159                                                          bool PIC,
160                                                          bool LargeCodeModel);
161   using MCInstrInfoCtorFnTy = MCInstrInfo *(*)();
162   using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info);
163   using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT);
164   using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT,
165                                                        StringRef CPU,
166                                                        StringRef Features);
167   using TargetMachineCtorTy = TargetMachine
168       *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
169            const TargetOptions &Options, std::optional<Reloc::Model> RM,
170            std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT);
171   // If it weren't for layering issues (this header is in llvm/Support, but
172   // depends on MC?) this should take the Streamer by value rather than rvalue
173   // reference.
174   using AsmPrinterCtorTy = AsmPrinter *(*)(
175       TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
176   using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
177                                                const MCSubtargetInfo &STI,
178                                                const MCRegisterInfo &MRI,
179                                                const MCTargetOptions &Options);
180   using MCAsmParserCtorTy = MCTargetAsmParser *(*)(
181       const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII,
182       const MCTargetOptions &Options);
183   using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T,
184                                                    const MCSubtargetInfo &STI,
185                                                    MCContext &Ctx);
186   using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T,
187                                                  unsigned SyntaxVariant,
188                                                  const MCAsmInfo &MAI,
189                                                  const MCInstrInfo &MII,
190                                                  const MCRegisterInfo &MRI);
191   using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II,
192                                                  MCContext &Ctx);
193   using ELFStreamerCtorTy =
194       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
195                       std::unique_ptr<MCAsmBackend> &&TAB,
196                       std::unique_ptr<MCObjectWriter> &&OW,
197                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
198   using MachOStreamerCtorTy =
199       MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
200                       std::unique_ptr<MCObjectWriter> &&OW,
201                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
202                       bool DWARFMustBeAtTheEnd);
203   using COFFStreamerCtorTy =
204       MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
205                       std::unique_ptr<MCObjectWriter> &&OW,
206                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
207                       bool IncrementalLinkerCompatible);
208   using WasmStreamerCtorTy =
209       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
210                       std::unique_ptr<MCAsmBackend> &&TAB,
211                       std::unique_ptr<MCObjectWriter> &&OW,
212                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
213   using XCOFFStreamerCtorTy =
214       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
215                       std::unique_ptr<MCAsmBackend> &&TAB,
216                       std::unique_ptr<MCObjectWriter> &&OW,
217                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
218   using SPIRVStreamerCtorTy =
219       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
220                       std::unique_ptr<MCAsmBackend> &&TAB,
221                       std::unique_ptr<MCObjectWriter> &&OW,
222                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
223 
224   using DXContainerStreamerCtorTy =
225       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
226                       std::unique_ptr<MCAsmBackend> &&TAB,
227                       std::unique_ptr<MCObjectWriter> &&OW,
228                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
229 
230   using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S);
231   using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)(
232       MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
233       bool IsVerboseAsm);
234   using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
235       MCStreamer &S, const MCSubtargetInfo &STI);
236   using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
237                                                        MCContext &Ctx);
238   using MCSymbolizerCtorTy = MCSymbolizer *(*)(
239       const Triple &TT, LLVMOpInfoCallback GetOpInfo,
240       LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
241       std::unique_ptr<MCRelocationInfo> &&RelInfo);
242 
243   using CustomBehaviourCtorTy =
244       mca::CustomBehaviour *(*)(const MCSubtargetInfo &STI,
245                                 const mca::SourceMgr &SrcMgr,
246                                 const MCInstrInfo &MCII);
247 
248   using InstrPostProcessCtorTy =
249       mca::InstrPostProcess *(*)(const MCSubtargetInfo &STI,
250                                  const MCInstrInfo &MCII);
251 
252   using InstrumentManagerCtorTy =
253       mca::InstrumentManager *(*)(const MCSubtargetInfo &STI,
254                                   const MCInstrInfo &MCII);
255 
256 private:
257   /// Next - The next registered target in the linked list, maintained by the
258   /// TargetRegistry.
259   Target *Next;
260 
261   /// The target function for checking if an architecture is supported.
262   ArchMatchFnTy ArchMatchFn;
263 
264   /// Name - The target name.
265   const char *Name;
266 
267   /// ShortDesc - A short description of the target.
268   const char *ShortDesc;
269 
270   /// BackendName - The name of the backend implementation. This must match the
271   /// name of the 'def X : Target ...' in TableGen.
272   const char *BackendName;
273 
274   /// HasJIT - Whether this target supports the JIT.
275   bool HasJIT;
276 
277   /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
278   /// registered.
279   MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
280 
281   /// Constructor function for this target's MCObjectFileInfo, if registered.
282   MCObjectFileInfoCtorFnTy MCObjectFileInfoCtorFn;
283 
284   /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
285   /// if registered.
286   MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
287 
288   /// MCInstrAnalysisCtorFn - Constructor function for this target's
289   /// MCInstrAnalysis, if registered.
290   MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
291 
292   /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
293   /// if registered.
294   MCRegInfoCtorFnTy MCRegInfoCtorFn;
295 
296   /// MCSubtargetInfoCtorFn - Constructor function for this target's
297   /// MCSubtargetInfo, if registered.
298   MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
299 
300   /// TargetMachineCtorFn - Construction function for this target's
301   /// TargetMachine, if registered.
302   TargetMachineCtorTy TargetMachineCtorFn;
303 
304   /// MCAsmBackendCtorFn - Construction function for this target's
305   /// MCAsmBackend, if registered.
306   MCAsmBackendCtorTy MCAsmBackendCtorFn;
307 
308   /// MCAsmParserCtorFn - Construction function for this target's
309   /// MCTargetAsmParser, if registered.
310   MCAsmParserCtorTy MCAsmParserCtorFn;
311 
312   /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
313   /// if registered.
314   AsmPrinterCtorTy AsmPrinterCtorFn;
315 
316   /// MCDisassemblerCtorFn - Construction function for this target's
317   /// MCDisassembler, if registered.
318   MCDisassemblerCtorTy MCDisassemblerCtorFn;
319 
320   /// MCInstPrinterCtorFn - Construction function for this target's
321   /// MCInstPrinter, if registered.
322   MCInstPrinterCtorTy MCInstPrinterCtorFn;
323 
324   /// MCCodeEmitterCtorFn - Construction function for this target's
325   /// CodeEmitter, if registered.
326   MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
327 
328   // Construction functions for the various object formats, if registered.
329   COFFStreamerCtorTy COFFStreamerCtorFn = nullptr;
330   MachOStreamerCtorTy MachOStreamerCtorFn = nullptr;
331   ELFStreamerCtorTy ELFStreamerCtorFn = nullptr;
332   WasmStreamerCtorTy WasmStreamerCtorFn = nullptr;
333   XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr;
334   SPIRVStreamerCtorTy SPIRVStreamerCtorFn = nullptr;
335   DXContainerStreamerCtorTy DXContainerStreamerCtorFn = nullptr;
336 
337   /// Construction function for this target's null TargetStreamer, if
338   /// registered (default = nullptr).
339   NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr;
340 
341   /// Construction function for this target's asm TargetStreamer, if
342   /// registered (default = nullptr).
343   AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
344 
345   /// Construction function for this target's obj TargetStreamer, if
346   /// registered (default = nullptr).
347   ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
348 
349   /// MCRelocationInfoCtorFn - Construction function for this target's
350   /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
351   MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr;
352 
353   /// MCSymbolizerCtorFn - Construction function for this target's
354   /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
355   MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr;
356 
357   /// CustomBehaviourCtorFn - Construction function for this target's
358   /// CustomBehaviour, if registered (default = nullptr).
359   CustomBehaviourCtorTy CustomBehaviourCtorFn = nullptr;
360 
361   /// InstrPostProcessCtorFn - Construction function for this target's
362   /// InstrPostProcess, if registered (default = nullptr).
363   InstrPostProcessCtorTy InstrPostProcessCtorFn = nullptr;
364 
365   /// InstrumentManagerCtorFn - Construction function for this target's
366   /// InstrumentManager, if registered (default = nullptr).
367   InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr;
368 
369 public:
370   Target() = default;
371 
372   /// @name Target Information
373   /// @{
374 
375   // getNext - Return the next registered target.
376   const Target *getNext() const { return Next; }
377 
378   /// getName - Get the target name.
379   const char *getName() const { return Name; }
380 
381   /// getShortDescription - Get a short description of the target.
382   const char *getShortDescription() const { return ShortDesc; }
383 
384   /// getBackendName - Get the backend name.
385   const char *getBackendName() const { return BackendName; }
386 
387   /// @}
388   /// @name Feature Predicates
389   /// @{
390 
391   /// hasJIT - Check if this targets supports the just-in-time compilation.
392   bool hasJIT() const { return HasJIT; }
393 
394   /// hasTargetMachine - Check if this target supports code generation.
395   bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
396 
397   /// hasMCAsmBackend - Check if this target supports .o generation.
398   bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
399 
400   /// hasMCAsmParser - Check if this target supports assembly parsing.
401   bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; }
402 
403   /// @}
404   /// @name Feature Constructors
405   /// @{
406 
407   /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
408   /// target triple.
409   ///
410   /// \param TheTriple This argument is used to determine the target machine
411   /// feature set; it should always be provided. Generally this should be
412   /// either the target triple from the module, or the target triple of the
413   /// host if that does not exist.
414   MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple,
415                              const MCTargetOptions &Options) const {
416     if (!MCAsmInfoCtorFn)
417       return nullptr;
418     return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options);
419   }
420 
421   /// Create a MCObjectFileInfo implementation for the specified target
422   /// triple.
423   ///
424   MCObjectFileInfo *createMCObjectFileInfo(MCContext &Ctx, bool PIC,
425                                            bool LargeCodeModel = false) const {
426     if (!MCObjectFileInfoCtorFn) {
427       MCObjectFileInfo *MOFI = new MCObjectFileInfo();
428       MOFI->initMCObjectFileInfo(Ctx, PIC, LargeCodeModel);
429       return MOFI;
430     }
431     return MCObjectFileInfoCtorFn(Ctx, PIC, LargeCodeModel);
432   }
433 
434   /// createMCInstrInfo - Create a MCInstrInfo implementation.
435   ///
436   MCInstrInfo *createMCInstrInfo() const {
437     if (!MCInstrInfoCtorFn)
438       return nullptr;
439     return MCInstrInfoCtorFn();
440   }
441 
442   /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
443   ///
444   MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
445     if (!MCInstrAnalysisCtorFn)
446       return nullptr;
447     return MCInstrAnalysisCtorFn(Info);
448   }
449 
450   /// createMCRegInfo - Create a MCRegisterInfo implementation.
451   ///
452   MCRegisterInfo *createMCRegInfo(StringRef TT) const {
453     if (!MCRegInfoCtorFn)
454       return nullptr;
455     return MCRegInfoCtorFn(Triple(TT));
456   }
457 
458   /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
459   ///
460   /// \param TheTriple This argument is used to determine the target machine
461   /// feature set; it should always be provided. Generally this should be
462   /// either the target triple from the module, or the target triple of the
463   /// host if that does not exist.
464   /// \param CPU This specifies the name of the target CPU.
465   /// \param Features This specifies the string representation of the
466   /// additional target features.
467   MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU,
468                                          StringRef Features) const {
469     if (!MCSubtargetInfoCtorFn)
470       return nullptr;
471     return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features);
472   }
473 
474   /// createTargetMachine - Create a target specific machine implementation
475   /// for the specified \p Triple.
476   ///
477   /// \param TT This argument is used to determine the target machine
478   /// feature set; it should always be provided. Generally this should be
479   /// either the target triple from the module, or the target triple of the
480   /// host if that does not exist.
481   TargetMachine *createTargetMachine(
482       StringRef TT, StringRef CPU, StringRef Features,
483       const TargetOptions &Options, std::optional<Reloc::Model> RM,
484       std::optional<CodeModel::Model> CM = std::nullopt,
485       CodeGenOpt::Level OL = CodeGenOpt::Default, bool JIT = false) const {
486     if (!TargetMachineCtorFn)
487       return nullptr;
488     return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM,
489                                CM, OL, JIT);
490   }
491 
492   /// createMCAsmBackend - Create a target specific assembly parser.
493   MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI,
494                                    const MCRegisterInfo &MRI,
495                                    const MCTargetOptions &Options) const {
496     if (!MCAsmBackendCtorFn)
497       return nullptr;
498     return MCAsmBackendCtorFn(*this, STI, MRI, Options);
499   }
500 
501   /// createMCAsmParser - Create a target specific assembly parser.
502   ///
503   /// \param Parser The target independent parser implementation to use for
504   /// parsing and lexing.
505   MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI,
506                                        MCAsmParser &Parser,
507                                        const MCInstrInfo &MII,
508                                        const MCTargetOptions &Options) const {
509     if (!MCAsmParserCtorFn)
510       return nullptr;
511     return MCAsmParserCtorFn(STI, Parser, MII, Options);
512   }
513 
514   /// createAsmPrinter - Create a target specific assembly printer pass.  This
515   /// takes ownership of the MCStreamer object.
516   AsmPrinter *createAsmPrinter(TargetMachine &TM,
517                                std::unique_ptr<MCStreamer> &&Streamer) const {
518     if (!AsmPrinterCtorFn)
519       return nullptr;
520     return AsmPrinterCtorFn(TM, std::move(Streamer));
521   }
522 
523   MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
524                                        MCContext &Ctx) const {
525     if (!MCDisassemblerCtorFn)
526       return nullptr;
527     return MCDisassemblerCtorFn(*this, STI, Ctx);
528   }
529 
530   MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
531                                      const MCAsmInfo &MAI,
532                                      const MCInstrInfo &MII,
533                                      const MCRegisterInfo &MRI) const {
534     if (!MCInstPrinterCtorFn)
535       return nullptr;
536     return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
537   }
538 
539   /// createMCCodeEmitter - Create a target specific code emitter.
540   MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
541                                      MCContext &Ctx) const {
542     if (!MCCodeEmitterCtorFn)
543       return nullptr;
544     return MCCodeEmitterCtorFn(II, Ctx);
545   }
546 
547   /// Create a target specific MCStreamer.
548   ///
549   /// \param T The target triple.
550   /// \param Ctx The target context.
551   /// \param TAB The target assembler backend object. Takes ownership.
552   /// \param OW The stream object.
553   /// \param Emitter The target independent assembler object.Takes ownership.
554   /// \param RelaxAll Relax all fixups?
555   MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
556                                      std::unique_ptr<MCAsmBackend> &&TAB,
557                                      std::unique_ptr<MCObjectWriter> &&OW,
558                                      std::unique_ptr<MCCodeEmitter> &&Emitter,
559                                      const MCSubtargetInfo &STI, bool RelaxAll,
560                                      bool IncrementalLinkerCompatible,
561                                      bool DWARFMustBeAtTheEnd) const {
562     MCStreamer *S = nullptr;
563     switch (T.getObjectFormat()) {
564     case Triple::UnknownObjectFormat:
565       llvm_unreachable("Unknown object format");
566     case Triple::COFF:
567       assert(T.isOSWindows() && "only Windows COFF is supported");
568       S = COFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
569                              std::move(Emitter), RelaxAll,
570                              IncrementalLinkerCompatible);
571       break;
572     case Triple::MachO:
573       if (MachOStreamerCtorFn)
574         S = MachOStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
575                                 std::move(Emitter), RelaxAll,
576                                 DWARFMustBeAtTheEnd);
577       else
578         S = createMachOStreamer(Ctx, std::move(TAB), std::move(OW),
579                                 std::move(Emitter), RelaxAll,
580                                 DWARFMustBeAtTheEnd);
581       break;
582     case Triple::ELF:
583       if (ELFStreamerCtorFn)
584         S = ELFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
585                               std::move(Emitter), RelaxAll);
586       else
587         S = createELFStreamer(Ctx, std::move(TAB), std::move(OW),
588                               std::move(Emitter), RelaxAll);
589       break;
590     case Triple::Wasm:
591       if (WasmStreamerCtorFn)
592         S = WasmStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
593                                std::move(Emitter), RelaxAll);
594       else
595         S = createWasmStreamer(Ctx, std::move(TAB), std::move(OW),
596                                std::move(Emitter), RelaxAll);
597       break;
598     case Triple::GOFF:
599       report_fatal_error("GOFF MCObjectStreamer not implemented yet");
600     case Triple::XCOFF:
601       if (XCOFFStreamerCtorFn)
602         S = XCOFFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
603                                 std::move(Emitter), RelaxAll);
604       else
605         S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
606                                 std::move(Emitter), RelaxAll);
607       break;
608     case Triple::SPIRV:
609       if (SPIRVStreamerCtorFn)
610         S = SPIRVStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
611                                 std::move(Emitter), RelaxAll);
612       else
613         S = createSPIRVStreamer(Ctx, std::move(TAB), std::move(OW),
614                                 std::move(Emitter), RelaxAll);
615       break;
616     case Triple::DXContainer:
617       if (DXContainerStreamerCtorFn)
618         S = DXContainerStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
619                               std::move(Emitter), RelaxAll);
620       else
621         S = createDXContainerStreamer(Ctx, std::move(TAB), std::move(OW),
622                                       std::move(Emitter), RelaxAll);
623       break;
624     }
625     if (ObjectTargetStreamerCtorFn)
626       ObjectTargetStreamerCtorFn(*S, STI);
627     return S;
628   }
629 
630   MCStreamer *createAsmStreamer(MCContext &Ctx,
631                                 std::unique_ptr<formatted_raw_ostream> OS,
632                                 bool IsVerboseAsm, bool UseDwarfDirectory,
633                                 MCInstPrinter *InstPrint,
634                                 std::unique_ptr<MCCodeEmitter> &&CE,
635                                 std::unique_ptr<MCAsmBackend> &&TAB,
636                                 bool ShowInst) const {
637     formatted_raw_ostream &OSRef = *OS;
638     MCStreamer *S = llvm::createAsmStreamer(
639         Ctx, std::move(OS), IsVerboseAsm, UseDwarfDirectory, InstPrint,
640         std::move(CE), std::move(TAB), ShowInst);
641     createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
642     return S;
643   }
644 
645   MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
646                                             formatted_raw_ostream &OS,
647                                             MCInstPrinter *InstPrint,
648                                             bool IsVerboseAsm) const {
649     if (AsmTargetStreamerCtorFn)
650       return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm);
651     return nullptr;
652   }
653 
654   MCStreamer *createNullStreamer(MCContext &Ctx) const {
655     MCStreamer *S = llvm::createNullStreamer(Ctx);
656     createNullTargetStreamer(*S);
657     return S;
658   }
659 
660   MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
661     if (NullTargetStreamerCtorFn)
662       return NullTargetStreamerCtorFn(S);
663     return nullptr;
664   }
665 
666   /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
667   ///
668   /// \param TT The target triple.
669   /// \param Ctx The target context.
670   MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
671     MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
672                                     ? MCRelocationInfoCtorFn
673                                     : llvm::createMCRelocationInfo;
674     return Fn(Triple(TT), Ctx);
675   }
676 
677   /// createMCSymbolizer - Create a target specific MCSymbolizer.
678   ///
679   /// \param TT The target triple.
680   /// \param GetOpInfo The function to get the symbolic information for
681   /// operands.
682   /// \param SymbolLookUp The function to lookup a symbol name.
683   /// \param DisInfo The pointer to the block of symbolic information for above
684   /// call
685   /// back.
686   /// \param Ctx The target context.
687   /// \param RelInfo The relocation information for this target. Takes
688   /// ownership.
689   MCSymbolizer *
690   createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
691                      LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
692                      MCContext *Ctx,
693                      std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
694     MCSymbolizerCtorTy Fn =
695         MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
696     return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx,
697               std::move(RelInfo));
698   }
699 
700   /// createCustomBehaviour - Create a target specific CustomBehaviour.
701   /// This class is used by llvm-mca and requires backend functionality.
702   mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI,
703                                               const mca::SourceMgr &SrcMgr,
704                                               const MCInstrInfo &MCII) const {
705     if (CustomBehaviourCtorFn)
706       return CustomBehaviourCtorFn(STI, SrcMgr, MCII);
707     return nullptr;
708   }
709 
710   /// createInstrPostProcess - Create a target specific InstrPostProcess.
711   /// This class is used by llvm-mca and requires backend functionality.
712   mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI,
713                                                 const MCInstrInfo &MCII) const {
714     if (InstrPostProcessCtorFn)
715       return InstrPostProcessCtorFn(STI, MCII);
716     return nullptr;
717   }
718 
719   /// createInstrumentManager - Create a target specific
720   /// InstrumentManager. This class is used by llvm-mca and requires
721   /// backend functionality.
722   mca::InstrumentManager *
723   createInstrumentManager(const MCSubtargetInfo &STI,
724                           const MCInstrInfo &MCII) const {
725     if (InstrumentManagerCtorFn)
726       return InstrumentManagerCtorFn(STI, MCII);
727     return nullptr;
728   }
729 
730   /// @}
731 };
732 
733 /// TargetRegistry - Generic interface to target specific features.
734 struct TargetRegistry {
735   // FIXME: Make this a namespace, probably just move all the Register*
736   // functions into Target (currently they all just set members on the Target
737   // anyway, and Target friends this class so those functions can...
738   // function).
739   TargetRegistry() = delete;
740 
741   class iterator {
742     friend struct TargetRegistry;
743 
744     const Target *Current = nullptr;
745 
746     explicit iterator(Target *T) : Current(T) {}
747 
748   public:
749     using iterator_category = std::forward_iterator_tag;
750     using value_type = Target;
751     using difference_type = std::ptrdiff_t;
752     using pointer = value_type *;
753     using reference = value_type &;
754 
755     iterator() = default;
756 
757     bool operator==(const iterator &x) const { return Current == x.Current; }
758     bool operator!=(const iterator &x) const { return !operator==(x); }
759 
760     // Iterator traversal: forward iteration only
761     iterator &operator++() { // Preincrement
762       assert(Current && "Cannot increment end iterator!");
763       Current = Current->getNext();
764       return *this;
765     }
766     iterator operator++(int) { // Postincrement
767       iterator tmp = *this;
768       ++*this;
769       return tmp;
770     }
771 
772     const Target &operator*() const {
773       assert(Current && "Cannot dereference end iterator!");
774       return *Current;
775     }
776 
777     const Target *operator->() const { return &operator*(); }
778   };
779 
780   /// printRegisteredTargetsForVersion - Print the registered targets
781   /// appropriately for inclusion in a tool's version output.
782   static void printRegisteredTargetsForVersion(raw_ostream &OS);
783 
784   /// @name Registry Access
785   /// @{
786 
787   static iterator_range<iterator> targets();
788 
789   /// lookupTarget - Lookup a target based on a target triple.
790   ///
791   /// \param Triple - The triple to use for finding a target.
792   /// \param Error - On failure, an error string describing why no target was
793   /// found.
794   static const Target *lookupTarget(const std::string &Triple,
795                                     std::string &Error);
796 
797   /// lookupTarget - Lookup a target based on an architecture name
798   /// and a target triple.  If the architecture name is non-empty,
799   /// then the lookup is done by architecture.  Otherwise, the target
800   /// triple is used.
801   ///
802   /// \param ArchName - The architecture to use for finding a target.
803   /// \param TheTriple - The triple to use for finding a target.  The
804   /// triple is updated with canonical architecture name if a lookup
805   /// by architecture is done.
806   /// \param Error - On failure, an error string describing why no target was
807   /// found.
808   static const Target *lookupTarget(const std::string &ArchName,
809                                     Triple &TheTriple, std::string &Error);
810 
811   /// @}
812   /// @name Target Registration
813   /// @{
814 
815   /// RegisterTarget - Register the given target. Attempts to register a
816   /// target which has already been registered will be ignored.
817   ///
818   /// Clients are responsible for ensuring that registration doesn't occur
819   /// while another thread is attempting to access the registry. Typically
820   /// this is done by initializing all targets at program startup.
821   ///
822   /// @param T - The target being registered.
823   /// @param Name - The target name. This should be a static string.
824   /// @param ShortDesc - A short target description. This should be a static
825   /// string.
826   /// @param BackendName - The name of the backend. This should be a static
827   /// string that is the same for all targets that share a backend
828   /// implementation and must match the name used in the 'def X : Target ...' in
829   /// TableGen.
830   /// @param ArchMatchFn - The arch match checking function for this target.
831   /// @param HasJIT - Whether the target supports JIT code
832   /// generation.
833   static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc,
834                              const char *BackendName,
835                              Target::ArchMatchFnTy ArchMatchFn,
836                              bool HasJIT = false);
837 
838   /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
839   /// given target.
840   ///
841   /// Clients are responsible for ensuring that registration doesn't occur
842   /// while another thread is attempting to access the registry. Typically
843   /// this is done by initializing all targets at program startup.
844   ///
845   /// @param T - The target being registered.
846   /// @param Fn - A function to construct a MCAsmInfo for the target.
847   static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
848     T.MCAsmInfoCtorFn = Fn;
849   }
850 
851   /// Register a MCObjectFileInfo implementation for the given target.
852   ///
853   /// Clients are responsible for ensuring that registration doesn't occur
854   /// while another thread is attempting to access the registry. Typically
855   /// this is done by initializing all targets at program startup.
856   ///
857   /// @param T - The target being registered.
858   /// @param Fn - A function to construct a MCObjectFileInfo for the target.
859   static void RegisterMCObjectFileInfo(Target &T,
860                                        Target::MCObjectFileInfoCtorFnTy Fn) {
861     T.MCObjectFileInfoCtorFn = Fn;
862   }
863 
864   /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
865   /// given target.
866   ///
867   /// Clients are responsible for ensuring that registration doesn't occur
868   /// while another thread is attempting to access the registry. Typically
869   /// this is done by initializing all targets at program startup.
870   ///
871   /// @param T - The target being registered.
872   /// @param Fn - A function to construct a MCInstrInfo for the target.
873   static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
874     T.MCInstrInfoCtorFn = Fn;
875   }
876 
877   /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
878   /// the given target.
879   static void RegisterMCInstrAnalysis(Target &T,
880                                       Target::MCInstrAnalysisCtorFnTy Fn) {
881     T.MCInstrAnalysisCtorFn = Fn;
882   }
883 
884   /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
885   /// given target.
886   ///
887   /// Clients are responsible for ensuring that registration doesn't occur
888   /// while another thread is attempting to access the registry. Typically
889   /// this is done by initializing all targets at program startup.
890   ///
891   /// @param T - The target being registered.
892   /// @param Fn - A function to construct a MCRegisterInfo for the target.
893   static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
894     T.MCRegInfoCtorFn = Fn;
895   }
896 
897   /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
898   /// the given target.
899   ///
900   /// Clients are responsible for ensuring that registration doesn't occur
901   /// while another thread is attempting to access the registry. Typically
902   /// this is done by initializing all targets at program startup.
903   ///
904   /// @param T - The target being registered.
905   /// @param Fn - A function to construct a MCSubtargetInfo for the target.
906   static void RegisterMCSubtargetInfo(Target &T,
907                                       Target::MCSubtargetInfoCtorFnTy Fn) {
908     T.MCSubtargetInfoCtorFn = Fn;
909   }
910 
911   /// RegisterTargetMachine - Register a TargetMachine implementation for the
912   /// given target.
913   ///
914   /// Clients are responsible for ensuring that registration doesn't occur
915   /// while another thread is attempting to access the registry. Typically
916   /// this is done by initializing all targets at program startup.
917   ///
918   /// @param T - The target being registered.
919   /// @param Fn - A function to construct a TargetMachine for the target.
920   static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) {
921     T.TargetMachineCtorFn = Fn;
922   }
923 
924   /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
925   /// given target.
926   ///
927   /// Clients are responsible for ensuring that registration doesn't occur
928   /// while another thread is attempting to access the registry. Typically
929   /// this is done by initializing all targets at program startup.
930   ///
931   /// @param T - The target being registered.
932   /// @param Fn - A function to construct an AsmBackend for the target.
933   static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
934     T.MCAsmBackendCtorFn = Fn;
935   }
936 
937   /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
938   /// the given target.
939   ///
940   /// Clients are responsible for ensuring that registration doesn't occur
941   /// while another thread is attempting to access the registry. Typically
942   /// this is done by initializing all targets at program startup.
943   ///
944   /// @param T - The target being registered.
945   /// @param Fn - A function to construct an MCTargetAsmParser for the target.
946   static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
947     T.MCAsmParserCtorFn = Fn;
948   }
949 
950   /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
951   /// target.
952   ///
953   /// Clients are responsible for ensuring that registration doesn't occur
954   /// while another thread is attempting to access the registry. Typically
955   /// this is done by initializing all targets at program startup.
956   ///
957   /// @param T - The target being registered.
958   /// @param Fn - A function to construct an AsmPrinter for the target.
959   static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
960     T.AsmPrinterCtorFn = Fn;
961   }
962 
963   /// RegisterMCDisassembler - Register a MCDisassembler implementation for
964   /// the given target.
965   ///
966   /// Clients are responsible for ensuring that registration doesn't occur
967   /// while another thread is attempting to access the registry. Typically
968   /// this is done by initializing all targets at program startup.
969   ///
970   /// @param T - The target being registered.
971   /// @param Fn - A function to construct an MCDisassembler for the target.
972   static void RegisterMCDisassembler(Target &T,
973                                      Target::MCDisassemblerCtorTy Fn) {
974     T.MCDisassemblerCtorFn = Fn;
975   }
976 
977   /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
978   /// given target.
979   ///
980   /// Clients are responsible for ensuring that registration doesn't occur
981   /// while another thread is attempting to access the registry. Typically
982   /// this is done by initializing all targets at program startup.
983   ///
984   /// @param T - The target being registered.
985   /// @param Fn - A function to construct an MCInstPrinter for the target.
986   static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) {
987     T.MCInstPrinterCtorFn = Fn;
988   }
989 
990   /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
991   /// given target.
992   ///
993   /// Clients are responsible for ensuring that registration doesn't occur
994   /// while another thread is attempting to access the registry. Typically
995   /// this is done by initializing all targets at program startup.
996   ///
997   /// @param T - The target being registered.
998   /// @param Fn - A function to construct an MCCodeEmitter for the target.
999   static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) {
1000     T.MCCodeEmitterCtorFn = Fn;
1001   }
1002 
1003   static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
1004     T.COFFStreamerCtorFn = Fn;
1005   }
1006 
1007   static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) {
1008     T.MachOStreamerCtorFn = Fn;
1009   }
1010 
1011   static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
1012     T.ELFStreamerCtorFn = Fn;
1013   }
1014 
1015   static void RegisterSPIRVStreamer(Target &T, Target::SPIRVStreamerCtorTy Fn) {
1016     T.SPIRVStreamerCtorFn = Fn;
1017   }
1018 
1019   static void RegisterDXContainerStreamer(Target &T, Target::DXContainerStreamerCtorTy Fn) {
1020     T.DXContainerStreamerCtorFn = Fn;
1021   }
1022 
1023   static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) {
1024     T.WasmStreamerCtorFn = Fn;
1025   }
1026 
1027   static void RegisterXCOFFStreamer(Target &T, Target::XCOFFStreamerCtorTy Fn) {
1028     T.XCOFFStreamerCtorFn = Fn;
1029   }
1030 
1031   static void RegisterNullTargetStreamer(Target &T,
1032                                          Target::NullTargetStreamerCtorTy Fn) {
1033     T.NullTargetStreamerCtorFn = Fn;
1034   }
1035 
1036   static void RegisterAsmTargetStreamer(Target &T,
1037                                         Target::AsmTargetStreamerCtorTy Fn) {
1038     T.AsmTargetStreamerCtorFn = Fn;
1039   }
1040 
1041   static void
1042   RegisterObjectTargetStreamer(Target &T,
1043                                Target::ObjectTargetStreamerCtorTy Fn) {
1044     T.ObjectTargetStreamerCtorFn = Fn;
1045   }
1046 
1047   /// RegisterMCRelocationInfo - Register an MCRelocationInfo
1048   /// implementation for the given target.
1049   ///
1050   /// Clients are responsible for ensuring that registration doesn't occur
1051   /// while another thread is attempting to access the registry. Typically
1052   /// this is done by initializing all targets at program startup.
1053   ///
1054   /// @param T - The target being registered.
1055   /// @param Fn - A function to construct an MCRelocationInfo for the target.
1056   static void RegisterMCRelocationInfo(Target &T,
1057                                        Target::MCRelocationInfoCtorTy Fn) {
1058     T.MCRelocationInfoCtorFn = Fn;
1059   }
1060 
1061   /// RegisterMCSymbolizer - Register an MCSymbolizer
1062   /// implementation for the given target.
1063   ///
1064   /// Clients are responsible for ensuring that registration doesn't occur
1065   /// while another thread is attempting to access the registry. Typically
1066   /// this is done by initializing all targets at program startup.
1067   ///
1068   /// @param T - The target being registered.
1069   /// @param Fn - A function to construct an MCSymbolizer for the target.
1070   static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) {
1071     T.MCSymbolizerCtorFn = Fn;
1072   }
1073 
1074   /// RegisterCustomBehaviour - Register a CustomBehaviour
1075   /// implementation for the given target.
1076   ///
1077   /// Clients are responsible for ensuring that registration doesn't occur
1078   /// while another thread is attempting to access the registry. Typically
1079   /// this is done by initializing all targets at program startup.
1080   ///
1081   /// @param T - The target being registered.
1082   /// @param Fn - A function to construct a CustomBehaviour for the target.
1083   static void RegisterCustomBehaviour(Target &T,
1084                                       Target::CustomBehaviourCtorTy Fn) {
1085     T.CustomBehaviourCtorFn = Fn;
1086   }
1087 
1088   /// RegisterInstrPostProcess - Register an InstrPostProcess
1089   /// implementation for the given target.
1090   ///
1091   /// Clients are responsible for ensuring that registration doesn't occur
1092   /// while another thread is attempting to access the registry. Typically
1093   /// this is done by initializing all targets at program startup.
1094   ///
1095   /// @param T - The target being registered.
1096   /// @param Fn - A function to construct an InstrPostProcess for the target.
1097   static void RegisterInstrPostProcess(Target &T,
1098                                        Target::InstrPostProcessCtorTy Fn) {
1099     T.InstrPostProcessCtorFn = Fn;
1100   }
1101 
1102   /// RegisterInstrumentManager - Register an InstrumentManager
1103   /// implementation for the given target.
1104   ///
1105   /// Clients are responsible for ensuring that registration doesn't occur
1106   /// while another thread is attempting to access the registry. Typically
1107   /// this is done by initializing all targets at program startup.
1108   ///
1109   /// @param T - The target being registered.
1110   /// @param Fn - A function to construct an InstrumentManager for the
1111   /// target.
1112   static void RegisterInstrumentManager(Target &T,
1113                                         Target::InstrumentManagerCtorTy Fn) {
1114     T.InstrumentManagerCtorFn = Fn;
1115   }
1116 
1117   /// @}
1118 };
1119 
1120 //===--------------------------------------------------------------------===//
1121 
1122 /// RegisterTarget - Helper template for registering a target, for use in the
1123 /// target's initialization function. Usage:
1124 ///
1125 ///
1126 /// Target &getTheFooTarget() { // The global target instance.
1127 ///   static Target TheFooTarget;
1128 ///   return TheFooTarget;
1129 /// }
1130 /// extern "C" void LLVMInitializeFooTargetInfo() {
1131 ///   RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo
1132 ///   description", "Foo" /* Backend Name */);
1133 /// }
1134 template <Triple::ArchType TargetArchType = Triple::UnknownArch,
1135           bool HasJIT = false>
1136 struct RegisterTarget {
1137   RegisterTarget(Target &T, const char *Name, const char *Desc,
1138                  const char *BackendName) {
1139     TargetRegistry::RegisterTarget(T, Name, Desc, BackendName, &getArchMatch,
1140                                    HasJIT);
1141   }
1142 
1143   static bool getArchMatch(Triple::ArchType Arch) {
1144     return Arch == TargetArchType;
1145   }
1146 };
1147 
1148 /// RegisterMCAsmInfo - Helper template for registering a target assembly info
1149 /// implementation.  This invokes the static "Create" method on the class to
1150 /// actually do the construction.  Usage:
1151 ///
1152 /// extern "C" void LLVMInitializeFooTarget() {
1153 ///   extern Target TheFooTarget;
1154 ///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
1155 /// }
1156 template <class MCAsmInfoImpl> struct RegisterMCAsmInfo {
1157   RegisterMCAsmInfo(Target &T) {
1158     TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
1159   }
1160 
1161 private:
1162   static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, const Triple &TT,
1163                               const MCTargetOptions &Options) {
1164     return new MCAsmInfoImpl(TT, Options);
1165   }
1166 };
1167 
1168 /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
1169 /// implementation.  This invokes the specified function to do the
1170 /// construction.  Usage:
1171 ///
1172 /// extern "C" void LLVMInitializeFooTarget() {
1173 ///   extern Target TheFooTarget;
1174 ///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
1175 /// }
1176 struct RegisterMCAsmInfoFn {
1177   RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
1178     TargetRegistry::RegisterMCAsmInfo(T, Fn);
1179   }
1180 };
1181 
1182 /// Helper template for registering a target object file info implementation.
1183 /// This invokes the static "Create" method on the class to actually do the
1184 /// construction.  Usage:
1185 ///
1186 /// extern "C" void LLVMInitializeFooTarget() {
1187 ///   extern Target TheFooTarget;
1188 ///   RegisterMCObjectFileInfo<FooMCObjectFileInfo> X(TheFooTarget);
1189 /// }
1190 template <class MCObjectFileInfoImpl> struct RegisterMCObjectFileInfo {
1191   RegisterMCObjectFileInfo(Target &T) {
1192     TargetRegistry::RegisterMCObjectFileInfo(T, &Allocator);
1193   }
1194 
1195 private:
1196   static MCObjectFileInfo *Allocator(MCContext &Ctx, bool PIC,
1197                                      bool LargeCodeModel = false) {
1198     return new MCObjectFileInfoImpl(Ctx, PIC, LargeCodeModel);
1199   }
1200 };
1201 
1202 /// Helper template for registering a target object file info implementation.
1203 /// This invokes the specified function to do the construction.  Usage:
1204 ///
1205 /// extern "C" void LLVMInitializeFooTarget() {
1206 ///   extern Target TheFooTarget;
1207 ///   RegisterMCObjectFileInfoFn X(TheFooTarget, TheFunction);
1208 /// }
1209 struct RegisterMCObjectFileInfoFn {
1210   RegisterMCObjectFileInfoFn(Target &T, Target::MCObjectFileInfoCtorFnTy Fn) {
1211     TargetRegistry::RegisterMCObjectFileInfo(T, Fn);
1212   }
1213 };
1214 
1215 /// RegisterMCInstrInfo - Helper template for registering a target instruction
1216 /// info implementation.  This invokes the static "Create" method on the class
1217 /// to actually do the construction.  Usage:
1218 ///
1219 /// extern "C" void LLVMInitializeFooTarget() {
1220 ///   extern Target TheFooTarget;
1221 ///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
1222 /// }
1223 template <class MCInstrInfoImpl> struct RegisterMCInstrInfo {
1224   RegisterMCInstrInfo(Target &T) {
1225     TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
1226   }
1227 
1228 private:
1229   static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); }
1230 };
1231 
1232 /// RegisterMCInstrInfoFn - Helper template for registering a target
1233 /// instruction info implementation.  This invokes the specified function to
1234 /// do the construction.  Usage:
1235 ///
1236 /// extern "C" void LLVMInitializeFooTarget() {
1237 ///   extern Target TheFooTarget;
1238 ///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
1239 /// }
1240 struct RegisterMCInstrInfoFn {
1241   RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
1242     TargetRegistry::RegisterMCInstrInfo(T, Fn);
1243   }
1244 };
1245 
1246 /// RegisterMCInstrAnalysis - Helper template for registering a target
1247 /// instruction analyzer implementation.  This invokes the static "Create"
1248 /// method on the class to actually do the construction.  Usage:
1249 ///
1250 /// extern "C" void LLVMInitializeFooTarget() {
1251 ///   extern Target TheFooTarget;
1252 ///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
1253 /// }
1254 template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis {
1255   RegisterMCInstrAnalysis(Target &T) {
1256     TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
1257   }
1258 
1259 private:
1260   static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
1261     return new MCInstrAnalysisImpl(Info);
1262   }
1263 };
1264 
1265 /// RegisterMCInstrAnalysisFn - Helper template for registering a target
1266 /// instruction analyzer implementation.  This invokes the specified function
1267 /// to do the construction.  Usage:
1268 ///
1269 /// extern "C" void LLVMInitializeFooTarget() {
1270 ///   extern Target TheFooTarget;
1271 ///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
1272 /// }
1273 struct RegisterMCInstrAnalysisFn {
1274   RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
1275     TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
1276   }
1277 };
1278 
1279 /// RegisterMCRegInfo - Helper template for registering a target register info
1280 /// implementation.  This invokes the static "Create" method on the class to
1281 /// actually do the construction.  Usage:
1282 ///
1283 /// extern "C" void LLVMInitializeFooTarget() {
1284 ///   extern Target TheFooTarget;
1285 ///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
1286 /// }
1287 template <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
1288   RegisterMCRegInfo(Target &T) {
1289     TargetRegistry::RegisterMCRegInfo(T, &Allocator);
1290   }
1291 
1292 private:
1293   static MCRegisterInfo *Allocator(const Triple & /*TT*/) {
1294     return new MCRegisterInfoImpl();
1295   }
1296 };
1297 
1298 /// RegisterMCRegInfoFn - Helper template for registering a target register
1299 /// info implementation.  This invokes the specified function to do the
1300 /// construction.  Usage:
1301 ///
1302 /// extern "C" void LLVMInitializeFooTarget() {
1303 ///   extern Target TheFooTarget;
1304 ///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
1305 /// }
1306 struct RegisterMCRegInfoFn {
1307   RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
1308     TargetRegistry::RegisterMCRegInfo(T, Fn);
1309   }
1310 };
1311 
1312 /// RegisterMCSubtargetInfo - Helper template for registering a target
1313 /// subtarget info implementation.  This invokes the static "Create" method
1314 /// on the class to actually do the construction.  Usage:
1315 ///
1316 /// extern "C" void LLVMInitializeFooTarget() {
1317 ///   extern Target TheFooTarget;
1318 ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
1319 /// }
1320 template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo {
1321   RegisterMCSubtargetInfo(Target &T) {
1322     TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
1323   }
1324 
1325 private:
1326   static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/,
1327                                     StringRef /*FS*/) {
1328     return new MCSubtargetInfoImpl();
1329   }
1330 };
1331 
1332 /// RegisterMCSubtargetInfoFn - Helper template for registering a target
1333 /// subtarget info implementation.  This invokes the specified function to
1334 /// do the construction.  Usage:
1335 ///
1336 /// extern "C" void LLVMInitializeFooTarget() {
1337 ///   extern Target TheFooTarget;
1338 ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
1339 /// }
1340 struct RegisterMCSubtargetInfoFn {
1341   RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
1342     TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
1343   }
1344 };
1345 
1346 /// RegisterTargetMachine - Helper template for registering a target machine
1347 /// implementation, for use in the target machine initialization
1348 /// function. Usage:
1349 ///
1350 /// extern "C" void LLVMInitializeFooTarget() {
1351 ///   extern Target TheFooTarget;
1352 ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
1353 /// }
1354 template <class TargetMachineImpl> struct RegisterTargetMachine {
1355   RegisterTargetMachine(Target &T) {
1356     TargetRegistry::RegisterTargetMachine(T, &Allocator);
1357   }
1358 
1359 private:
1360   static TargetMachine *Allocator(const Target &T, const Triple &TT,
1361                                   StringRef CPU, StringRef FS,
1362                                   const TargetOptions &Options,
1363                                   std::optional<Reloc::Model> RM,
1364                                   std::optional<CodeModel::Model> CM,
1365                                   CodeGenOpt::Level OL, bool JIT) {
1366     return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT);
1367   }
1368 };
1369 
1370 /// RegisterMCAsmBackend - Helper template for registering a target specific
1371 /// assembler backend. Usage:
1372 ///
1373 /// extern "C" void LLVMInitializeFooMCAsmBackend() {
1374 ///   extern Target TheFooTarget;
1375 ///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
1376 /// }
1377 template <class MCAsmBackendImpl> struct RegisterMCAsmBackend {
1378   RegisterMCAsmBackend(Target &T) {
1379     TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
1380   }
1381 
1382 private:
1383   static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI,
1384                                  const MCRegisterInfo &MRI,
1385                                  const MCTargetOptions &Options) {
1386     return new MCAsmBackendImpl(T, STI, MRI);
1387   }
1388 };
1389 
1390 /// RegisterMCAsmParser - Helper template for registering a target specific
1391 /// assembly parser, for use in the target machine initialization
1392 /// function. Usage:
1393 ///
1394 /// extern "C" void LLVMInitializeFooMCAsmParser() {
1395 ///   extern Target TheFooTarget;
1396 ///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
1397 /// }
1398 template <class MCAsmParserImpl> struct RegisterMCAsmParser {
1399   RegisterMCAsmParser(Target &T) {
1400     TargetRegistry::RegisterMCAsmParser(T, &Allocator);
1401   }
1402 
1403 private:
1404   static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI,
1405                                       MCAsmParser &P, const MCInstrInfo &MII,
1406                                       const MCTargetOptions &Options) {
1407     return new MCAsmParserImpl(STI, P, MII, Options);
1408   }
1409 };
1410 
1411 /// RegisterAsmPrinter - Helper template for registering a target specific
1412 /// assembly printer, for use in the target machine initialization
1413 /// function. Usage:
1414 ///
1415 /// extern "C" void LLVMInitializeFooAsmPrinter() {
1416 ///   extern Target TheFooTarget;
1417 ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
1418 /// }
1419 template <class AsmPrinterImpl> struct RegisterAsmPrinter {
1420   RegisterAsmPrinter(Target &T) {
1421     TargetRegistry::RegisterAsmPrinter(T, &Allocator);
1422   }
1423 
1424 private:
1425   static AsmPrinter *Allocator(TargetMachine &TM,
1426                                std::unique_ptr<MCStreamer> &&Streamer) {
1427     return new AsmPrinterImpl(TM, std::move(Streamer));
1428   }
1429 };
1430 
1431 /// RegisterMCCodeEmitter - Helper template for registering a target specific
1432 /// machine code emitter, for use in the target initialization
1433 /// function. Usage:
1434 ///
1435 /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
1436 ///   extern Target TheFooTarget;
1437 ///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
1438 /// }
1439 template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter {
1440   RegisterMCCodeEmitter(Target &T) {
1441     TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
1442   }
1443 
1444 private:
1445   static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
1446                                   MCContext & /*Ctx*/) {
1447     return new MCCodeEmitterImpl();
1448   }
1449 };
1450 
1451 } // end namespace llvm
1452 
1453 #endif // LLVM_MC_TARGETREGISTRY_H
1454