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