xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/MC/TargetRegistry.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1349cc55cSDimitry Andric //===- MC/TargetRegistry.h - Target Registration ----------------*- C++ -*-===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric // This file exposes the TargetRegistry interface, which tools can use to access
10349cc55cSDimitry Andric // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
11349cc55cSDimitry Andric // which have been registered.
12349cc55cSDimitry Andric //
13349cc55cSDimitry Andric // Target specific class implementations should register themselves using the
14349cc55cSDimitry Andric // appropriate TargetRegistry interfaces.
15349cc55cSDimitry Andric //
16349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
17349cc55cSDimitry Andric 
18349cc55cSDimitry Andric #ifndef LLVM_MC_TARGETREGISTRY_H
19349cc55cSDimitry Andric #define LLVM_MC_TARGETREGISTRY_H
20349cc55cSDimitry Andric 
21349cc55cSDimitry Andric #include "llvm-c/DisassemblerTypes.h"
22349cc55cSDimitry Andric #include "llvm/ADT/StringRef.h"
23349cc55cSDimitry Andric #include "llvm/ADT/Triple.h"
24349cc55cSDimitry Andric #include "llvm/ADT/iterator_range.h"
25349cc55cSDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
26349cc55cSDimitry Andric #include "llvm/Support/CodeGen.h"
27349cc55cSDimitry Andric #include "llvm/Support/ErrorHandling.h"
28349cc55cSDimitry Andric #include "llvm/Support/FormattedStream.h"
29349cc55cSDimitry Andric #include <cassert>
30349cc55cSDimitry Andric #include <cstddef>
31349cc55cSDimitry Andric #include <iterator>
32349cc55cSDimitry Andric #include <memory>
33*bdd1243dSDimitry Andric #include <optional>
34349cc55cSDimitry Andric #include <string>
35349cc55cSDimitry Andric 
36349cc55cSDimitry Andric namespace llvm {
37349cc55cSDimitry Andric 
38349cc55cSDimitry Andric class AsmPrinter;
39349cc55cSDimitry Andric class MCAsmBackend;
40349cc55cSDimitry Andric class MCAsmInfo;
41349cc55cSDimitry Andric class MCAsmParser;
42349cc55cSDimitry Andric class MCCodeEmitter;
43349cc55cSDimitry Andric class MCContext;
44349cc55cSDimitry Andric class MCDisassembler;
45349cc55cSDimitry Andric class MCInstPrinter;
46349cc55cSDimitry Andric class MCInstrAnalysis;
47349cc55cSDimitry Andric class MCInstrInfo;
48349cc55cSDimitry Andric class MCObjectWriter;
49349cc55cSDimitry Andric class MCRegisterInfo;
50349cc55cSDimitry Andric class MCRelocationInfo;
51349cc55cSDimitry Andric class MCStreamer;
52349cc55cSDimitry Andric class MCSubtargetInfo;
53349cc55cSDimitry Andric class MCSymbolizer;
54349cc55cSDimitry Andric class MCTargetAsmParser;
55349cc55cSDimitry Andric class MCTargetOptions;
56349cc55cSDimitry Andric class MCTargetStreamer;
57349cc55cSDimitry Andric class raw_ostream;
58349cc55cSDimitry Andric class TargetMachine;
59349cc55cSDimitry Andric class TargetOptions;
60349cc55cSDimitry Andric namespace mca {
61349cc55cSDimitry Andric class CustomBehaviour;
62349cc55cSDimitry Andric class InstrPostProcess;
63*bdd1243dSDimitry Andric class InstrumentManager;
6481ad6265SDimitry Andric struct SourceMgr;
65349cc55cSDimitry Andric } // namespace mca
66349cc55cSDimitry Andric 
67349cc55cSDimitry Andric MCStreamer *createNullStreamer(MCContext &Ctx);
68349cc55cSDimitry Andric // Takes ownership of \p TAB and \p CE.
69349cc55cSDimitry Andric 
70349cc55cSDimitry Andric /// Create a machine code streamer which will print out assembly for the native
71349cc55cSDimitry Andric /// target, suitable for compiling with a native assembler.
72349cc55cSDimitry Andric ///
73349cc55cSDimitry Andric /// \param InstPrint - If given, the instruction printer to use. If not given
74349cc55cSDimitry Andric /// the MCInst representation will be printed.  This method takes ownership of
75349cc55cSDimitry Andric /// InstPrint.
76349cc55cSDimitry Andric ///
77349cc55cSDimitry Andric /// \param CE - If given, a code emitter to use to show the instruction
78349cc55cSDimitry Andric /// encoding inline with the assembly. This method takes ownership of \p CE.
79349cc55cSDimitry Andric ///
80349cc55cSDimitry Andric /// \param TAB - If given, a target asm backend to use to show the fixup
81349cc55cSDimitry Andric /// information in conjunction with encoding information. This method takes
82349cc55cSDimitry Andric /// ownership of \p TAB.
83349cc55cSDimitry Andric ///
84349cc55cSDimitry Andric /// \param ShowInst - Whether to show the MCInst representation inline with
85349cc55cSDimitry Andric /// the assembly.
86349cc55cSDimitry Andric MCStreamer *
87349cc55cSDimitry Andric createAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS,
88349cc55cSDimitry Andric                   bool isVerboseAsm, bool useDwarfDirectory,
89349cc55cSDimitry Andric                   MCInstPrinter *InstPrint, std::unique_ptr<MCCodeEmitter> &&CE,
90349cc55cSDimitry Andric                   std::unique_ptr<MCAsmBackend> &&TAB, bool ShowInst);
91349cc55cSDimitry Andric 
92349cc55cSDimitry Andric MCStreamer *createELFStreamer(MCContext &Ctx,
93349cc55cSDimitry Andric                               std::unique_ptr<MCAsmBackend> &&TAB,
94349cc55cSDimitry Andric                               std::unique_ptr<MCObjectWriter> &&OW,
95349cc55cSDimitry Andric                               std::unique_ptr<MCCodeEmitter> &&CE,
96349cc55cSDimitry Andric                               bool RelaxAll);
97349cc55cSDimitry Andric MCStreamer *createMachOStreamer(MCContext &Ctx,
98349cc55cSDimitry Andric                                 std::unique_ptr<MCAsmBackend> &&TAB,
99349cc55cSDimitry Andric                                 std::unique_ptr<MCObjectWriter> &&OW,
100349cc55cSDimitry Andric                                 std::unique_ptr<MCCodeEmitter> &&CE,
101349cc55cSDimitry Andric                                 bool RelaxAll, bool DWARFMustBeAtTheEnd,
102349cc55cSDimitry Andric                                 bool LabelSections = false);
103349cc55cSDimitry Andric MCStreamer *createWasmStreamer(MCContext &Ctx,
104349cc55cSDimitry Andric                                std::unique_ptr<MCAsmBackend> &&TAB,
105349cc55cSDimitry Andric                                std::unique_ptr<MCObjectWriter> &&OW,
106349cc55cSDimitry Andric                                std::unique_ptr<MCCodeEmitter> &&CE,
107349cc55cSDimitry Andric                                bool RelaxAll);
108349cc55cSDimitry Andric MCStreamer *createXCOFFStreamer(MCContext &Ctx,
109349cc55cSDimitry Andric                                 std::unique_ptr<MCAsmBackend> &&TAB,
110349cc55cSDimitry Andric                                 std::unique_ptr<MCObjectWriter> &&OW,
111349cc55cSDimitry Andric                                 std::unique_ptr<MCCodeEmitter> &&CE,
112349cc55cSDimitry Andric                                 bool RelaxAll);
11381ad6265SDimitry Andric MCStreamer *createSPIRVStreamer(MCContext &Ctx,
11481ad6265SDimitry Andric                                 std::unique_ptr<MCAsmBackend> &&TAB,
11581ad6265SDimitry Andric                                 std::unique_ptr<MCObjectWriter> &&OW,
11681ad6265SDimitry Andric                                 std::unique_ptr<MCCodeEmitter> &&CE,
11781ad6265SDimitry Andric                                 bool RelaxAll);
11881ad6265SDimitry Andric MCStreamer *createDXContainerStreamer(MCContext &Ctx,
11981ad6265SDimitry Andric                                       std::unique_ptr<MCAsmBackend> &&TAB,
12081ad6265SDimitry Andric                                       std::unique_ptr<MCObjectWriter> &&OW,
12181ad6265SDimitry Andric                                       std::unique_ptr<MCCodeEmitter> &&CE,
12281ad6265SDimitry Andric                                       bool RelaxAll);
123349cc55cSDimitry Andric 
124349cc55cSDimitry Andric MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
125349cc55cSDimitry Andric 
126349cc55cSDimitry Andric MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
127349cc55cSDimitry Andric                                  LLVMSymbolLookupCallback SymbolLookUp,
128349cc55cSDimitry Andric                                  void *DisInfo, MCContext *Ctx,
129349cc55cSDimitry Andric                                  std::unique_ptr<MCRelocationInfo> &&RelInfo);
130349cc55cSDimitry Andric 
131349cc55cSDimitry Andric mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI,
132349cc55cSDimitry Andric                                             const mca::SourceMgr &SrcMgr,
133349cc55cSDimitry Andric                                             const MCInstrInfo &MCII);
134349cc55cSDimitry Andric 
135349cc55cSDimitry Andric mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI,
136349cc55cSDimitry Andric                                               const MCInstrInfo &MCII);
137349cc55cSDimitry Andric 
138*bdd1243dSDimitry Andric mca::InstrumentManager *createInstrumentManager(const MCSubtargetInfo &STI,
139*bdd1243dSDimitry Andric                                                 const MCInstrInfo &MCII);
140*bdd1243dSDimitry Andric 
141349cc55cSDimitry Andric /// Target - Wrapper for Target specific information.
142349cc55cSDimitry Andric ///
143349cc55cSDimitry Andric /// For registration purposes, this is a POD type so that targets can be
144349cc55cSDimitry Andric /// registered without the use of static constructors.
145349cc55cSDimitry Andric ///
146349cc55cSDimitry Andric /// Targets should implement a single global instance of this class (which
147349cc55cSDimitry Andric /// will be zero initialized), and pass that instance to the TargetRegistry as
148349cc55cSDimitry Andric /// part of their initialization.
149349cc55cSDimitry Andric class Target {
150349cc55cSDimitry Andric public:
151349cc55cSDimitry Andric   friend struct TargetRegistry;
152349cc55cSDimitry Andric 
153349cc55cSDimitry Andric   using ArchMatchFnTy = bool (*)(Triple::ArchType Arch);
154349cc55cSDimitry Andric 
155349cc55cSDimitry Andric   using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI,
156349cc55cSDimitry Andric                                            const Triple &TT,
157349cc55cSDimitry Andric                                            const MCTargetOptions &Options);
158349cc55cSDimitry Andric   using MCObjectFileInfoCtorFnTy = MCObjectFileInfo *(*)(MCContext &Ctx,
159349cc55cSDimitry Andric                                                          bool PIC,
160349cc55cSDimitry Andric                                                          bool LargeCodeModel);
161349cc55cSDimitry Andric   using MCInstrInfoCtorFnTy = MCInstrInfo *(*)();
162349cc55cSDimitry Andric   using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info);
163349cc55cSDimitry Andric   using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT);
164349cc55cSDimitry Andric   using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT,
165349cc55cSDimitry Andric                                                        StringRef CPU,
166349cc55cSDimitry Andric                                                        StringRef Features);
167349cc55cSDimitry Andric   using TargetMachineCtorTy = TargetMachine
168349cc55cSDimitry Andric       *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
169*bdd1243dSDimitry Andric            const TargetOptions &Options, std::optional<Reloc::Model> RM,
170*bdd1243dSDimitry Andric            std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT);
171349cc55cSDimitry Andric   // If it weren't for layering issues (this header is in llvm/Support, but
172349cc55cSDimitry Andric   // depends on MC?) this should take the Streamer by value rather than rvalue
173349cc55cSDimitry Andric   // reference.
174349cc55cSDimitry Andric   using AsmPrinterCtorTy = AsmPrinter *(*)(
175349cc55cSDimitry Andric       TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
176349cc55cSDimitry Andric   using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
177349cc55cSDimitry Andric                                                const MCSubtargetInfo &STI,
178349cc55cSDimitry Andric                                                const MCRegisterInfo &MRI,
179349cc55cSDimitry Andric                                                const MCTargetOptions &Options);
180349cc55cSDimitry Andric   using MCAsmParserCtorTy = MCTargetAsmParser *(*)(
181349cc55cSDimitry Andric       const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII,
182349cc55cSDimitry Andric       const MCTargetOptions &Options);
183349cc55cSDimitry Andric   using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T,
184349cc55cSDimitry Andric                                                    const MCSubtargetInfo &STI,
185349cc55cSDimitry Andric                                                    MCContext &Ctx);
186349cc55cSDimitry Andric   using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T,
187349cc55cSDimitry Andric                                                  unsigned SyntaxVariant,
188349cc55cSDimitry Andric                                                  const MCAsmInfo &MAI,
189349cc55cSDimitry Andric                                                  const MCInstrInfo &MII,
190349cc55cSDimitry Andric                                                  const MCRegisterInfo &MRI);
191349cc55cSDimitry Andric   using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II,
192349cc55cSDimitry Andric                                                  MCContext &Ctx);
193349cc55cSDimitry Andric   using ELFStreamerCtorTy =
194349cc55cSDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
195349cc55cSDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
196349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
197349cc55cSDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
198349cc55cSDimitry Andric   using MachOStreamerCtorTy =
199349cc55cSDimitry Andric       MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
200349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
201349cc55cSDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
202349cc55cSDimitry Andric                       bool DWARFMustBeAtTheEnd);
203349cc55cSDimitry Andric   using COFFStreamerCtorTy =
204349cc55cSDimitry Andric       MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
205349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
206349cc55cSDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
207349cc55cSDimitry Andric                       bool IncrementalLinkerCompatible);
208349cc55cSDimitry Andric   using WasmStreamerCtorTy =
209349cc55cSDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
210349cc55cSDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
211349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
212349cc55cSDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
213349cc55cSDimitry Andric   using XCOFFStreamerCtorTy =
214349cc55cSDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
215349cc55cSDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
216349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
217349cc55cSDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
21881ad6265SDimitry Andric   using SPIRVStreamerCtorTy =
21981ad6265SDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
22081ad6265SDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
22181ad6265SDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
22281ad6265SDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
22381ad6265SDimitry Andric 
22481ad6265SDimitry Andric   using DXContainerStreamerCtorTy =
22581ad6265SDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
22681ad6265SDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
22781ad6265SDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
22881ad6265SDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
229349cc55cSDimitry Andric 
230349cc55cSDimitry Andric   using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S);
231349cc55cSDimitry Andric   using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)(
232349cc55cSDimitry Andric       MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
233349cc55cSDimitry Andric       bool IsVerboseAsm);
234349cc55cSDimitry Andric   using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
235349cc55cSDimitry Andric       MCStreamer &S, const MCSubtargetInfo &STI);
236349cc55cSDimitry Andric   using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
237349cc55cSDimitry Andric                                                        MCContext &Ctx);
238349cc55cSDimitry Andric   using MCSymbolizerCtorTy = MCSymbolizer *(*)(
239349cc55cSDimitry Andric       const Triple &TT, LLVMOpInfoCallback GetOpInfo,
240349cc55cSDimitry Andric       LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
241349cc55cSDimitry Andric       std::unique_ptr<MCRelocationInfo> &&RelInfo);
242349cc55cSDimitry Andric 
243349cc55cSDimitry Andric   using CustomBehaviourCtorTy =
244349cc55cSDimitry Andric       mca::CustomBehaviour *(*)(const MCSubtargetInfo &STI,
245349cc55cSDimitry Andric                                 const mca::SourceMgr &SrcMgr,
246349cc55cSDimitry Andric                                 const MCInstrInfo &MCII);
247349cc55cSDimitry Andric 
248349cc55cSDimitry Andric   using InstrPostProcessCtorTy =
249349cc55cSDimitry Andric       mca::InstrPostProcess *(*)(const MCSubtargetInfo &STI,
250349cc55cSDimitry Andric                                  const MCInstrInfo &MCII);
251349cc55cSDimitry Andric 
252*bdd1243dSDimitry Andric   using InstrumentManagerCtorTy =
253*bdd1243dSDimitry Andric       mca::InstrumentManager *(*)(const MCSubtargetInfo &STI,
254*bdd1243dSDimitry Andric                                   const MCInstrInfo &MCII);
255*bdd1243dSDimitry Andric 
256349cc55cSDimitry Andric private:
257349cc55cSDimitry Andric   /// Next - The next registered target in the linked list, maintained by the
258349cc55cSDimitry Andric   /// TargetRegistry.
259349cc55cSDimitry Andric   Target *Next;
260349cc55cSDimitry Andric 
261349cc55cSDimitry Andric   /// The target function for checking if an architecture is supported.
262349cc55cSDimitry Andric   ArchMatchFnTy ArchMatchFn;
263349cc55cSDimitry Andric 
264349cc55cSDimitry Andric   /// Name - The target name.
265349cc55cSDimitry Andric   const char *Name;
266349cc55cSDimitry Andric 
267349cc55cSDimitry Andric   /// ShortDesc - A short description of the target.
268349cc55cSDimitry Andric   const char *ShortDesc;
269349cc55cSDimitry Andric 
270349cc55cSDimitry Andric   /// BackendName - The name of the backend implementation. This must match the
271349cc55cSDimitry Andric   /// name of the 'def X : Target ...' in TableGen.
272349cc55cSDimitry Andric   const char *BackendName;
273349cc55cSDimitry Andric 
274349cc55cSDimitry Andric   /// HasJIT - Whether this target supports the JIT.
275349cc55cSDimitry Andric   bool HasJIT;
276349cc55cSDimitry Andric 
277349cc55cSDimitry Andric   /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
278349cc55cSDimitry Andric   /// registered.
279349cc55cSDimitry Andric   MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
280349cc55cSDimitry Andric 
281349cc55cSDimitry Andric   /// Constructor function for this target's MCObjectFileInfo, if registered.
282349cc55cSDimitry Andric   MCObjectFileInfoCtorFnTy MCObjectFileInfoCtorFn;
283349cc55cSDimitry Andric 
284349cc55cSDimitry Andric   /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
285349cc55cSDimitry Andric   /// if registered.
286349cc55cSDimitry Andric   MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
287349cc55cSDimitry Andric 
288349cc55cSDimitry Andric   /// MCInstrAnalysisCtorFn - Constructor function for this target's
289349cc55cSDimitry Andric   /// MCInstrAnalysis, if registered.
290349cc55cSDimitry Andric   MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
291349cc55cSDimitry Andric 
292349cc55cSDimitry Andric   /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
293349cc55cSDimitry Andric   /// if registered.
294349cc55cSDimitry Andric   MCRegInfoCtorFnTy MCRegInfoCtorFn;
295349cc55cSDimitry Andric 
296349cc55cSDimitry Andric   /// MCSubtargetInfoCtorFn - Constructor function for this target's
297349cc55cSDimitry Andric   /// MCSubtargetInfo, if registered.
298349cc55cSDimitry Andric   MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
299349cc55cSDimitry Andric 
300349cc55cSDimitry Andric   /// TargetMachineCtorFn - Construction function for this target's
301349cc55cSDimitry Andric   /// TargetMachine, if registered.
302349cc55cSDimitry Andric   TargetMachineCtorTy TargetMachineCtorFn;
303349cc55cSDimitry Andric 
304349cc55cSDimitry Andric   /// MCAsmBackendCtorFn - Construction function for this target's
305349cc55cSDimitry Andric   /// MCAsmBackend, if registered.
306349cc55cSDimitry Andric   MCAsmBackendCtorTy MCAsmBackendCtorFn;
307349cc55cSDimitry Andric 
308349cc55cSDimitry Andric   /// MCAsmParserCtorFn - Construction function for this target's
309349cc55cSDimitry Andric   /// MCTargetAsmParser, if registered.
310349cc55cSDimitry Andric   MCAsmParserCtorTy MCAsmParserCtorFn;
311349cc55cSDimitry Andric 
312349cc55cSDimitry Andric   /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
313349cc55cSDimitry Andric   /// if registered.
314349cc55cSDimitry Andric   AsmPrinterCtorTy AsmPrinterCtorFn;
315349cc55cSDimitry Andric 
316349cc55cSDimitry Andric   /// MCDisassemblerCtorFn - Construction function for this target's
317349cc55cSDimitry Andric   /// MCDisassembler, if registered.
318349cc55cSDimitry Andric   MCDisassemblerCtorTy MCDisassemblerCtorFn;
319349cc55cSDimitry Andric 
320349cc55cSDimitry Andric   /// MCInstPrinterCtorFn - Construction function for this target's
321349cc55cSDimitry Andric   /// MCInstPrinter, if registered.
322349cc55cSDimitry Andric   MCInstPrinterCtorTy MCInstPrinterCtorFn;
323349cc55cSDimitry Andric 
324349cc55cSDimitry Andric   /// MCCodeEmitterCtorFn - Construction function for this target's
325349cc55cSDimitry Andric   /// CodeEmitter, if registered.
326349cc55cSDimitry Andric   MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
327349cc55cSDimitry Andric 
328349cc55cSDimitry Andric   // Construction functions for the various object formats, if registered.
329349cc55cSDimitry Andric   COFFStreamerCtorTy COFFStreamerCtorFn = nullptr;
330349cc55cSDimitry Andric   MachOStreamerCtorTy MachOStreamerCtorFn = nullptr;
331349cc55cSDimitry Andric   ELFStreamerCtorTy ELFStreamerCtorFn = nullptr;
332349cc55cSDimitry Andric   WasmStreamerCtorTy WasmStreamerCtorFn = nullptr;
333349cc55cSDimitry Andric   XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr;
33481ad6265SDimitry Andric   SPIRVStreamerCtorTy SPIRVStreamerCtorFn = nullptr;
33581ad6265SDimitry Andric   DXContainerStreamerCtorTy DXContainerStreamerCtorFn = nullptr;
336349cc55cSDimitry Andric 
337349cc55cSDimitry Andric   /// Construction function for this target's null TargetStreamer, if
338349cc55cSDimitry Andric   /// registered (default = nullptr).
339349cc55cSDimitry Andric   NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr;
340349cc55cSDimitry Andric 
341349cc55cSDimitry Andric   /// Construction function for this target's asm TargetStreamer, if
342349cc55cSDimitry Andric   /// registered (default = nullptr).
343349cc55cSDimitry Andric   AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
344349cc55cSDimitry Andric 
345349cc55cSDimitry Andric   /// Construction function for this target's obj TargetStreamer, if
346349cc55cSDimitry Andric   /// registered (default = nullptr).
347349cc55cSDimitry Andric   ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
348349cc55cSDimitry Andric 
349349cc55cSDimitry Andric   /// MCRelocationInfoCtorFn - Construction function for this target's
350349cc55cSDimitry Andric   /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
351349cc55cSDimitry Andric   MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr;
352349cc55cSDimitry Andric 
353349cc55cSDimitry Andric   /// MCSymbolizerCtorFn - Construction function for this target's
354349cc55cSDimitry Andric   /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
355349cc55cSDimitry Andric   MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr;
356349cc55cSDimitry Andric 
357349cc55cSDimitry Andric   /// CustomBehaviourCtorFn - Construction function for this target's
358349cc55cSDimitry Andric   /// CustomBehaviour, if registered (default = nullptr).
359349cc55cSDimitry Andric   CustomBehaviourCtorTy CustomBehaviourCtorFn = nullptr;
360349cc55cSDimitry Andric 
361349cc55cSDimitry Andric   /// InstrPostProcessCtorFn - Construction function for this target's
362349cc55cSDimitry Andric   /// InstrPostProcess, if registered (default = nullptr).
363349cc55cSDimitry Andric   InstrPostProcessCtorTy InstrPostProcessCtorFn = nullptr;
364349cc55cSDimitry Andric 
365*bdd1243dSDimitry Andric   /// InstrumentManagerCtorFn - Construction function for this target's
366*bdd1243dSDimitry Andric   /// InstrumentManager, if registered (default = nullptr).
367*bdd1243dSDimitry Andric   InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr;
368*bdd1243dSDimitry Andric 
369349cc55cSDimitry Andric public:
370349cc55cSDimitry Andric   Target() = default;
371349cc55cSDimitry Andric 
372349cc55cSDimitry Andric   /// @name Target Information
373349cc55cSDimitry Andric   /// @{
374349cc55cSDimitry Andric 
375349cc55cSDimitry Andric   // getNext - Return the next registered target.
376349cc55cSDimitry Andric   const Target *getNext() const { return Next; }
377349cc55cSDimitry Andric 
378349cc55cSDimitry Andric   /// getName - Get the target name.
379349cc55cSDimitry Andric   const char *getName() const { return Name; }
380349cc55cSDimitry Andric 
381349cc55cSDimitry Andric   /// getShortDescription - Get a short description of the target.
382349cc55cSDimitry Andric   const char *getShortDescription() const { return ShortDesc; }
383349cc55cSDimitry Andric 
384349cc55cSDimitry Andric   /// getBackendName - Get the backend name.
385349cc55cSDimitry Andric   const char *getBackendName() const { return BackendName; }
386349cc55cSDimitry Andric 
387349cc55cSDimitry Andric   /// @}
388349cc55cSDimitry Andric   /// @name Feature Predicates
389349cc55cSDimitry Andric   /// @{
390349cc55cSDimitry Andric 
391349cc55cSDimitry Andric   /// hasJIT - Check if this targets supports the just-in-time compilation.
392349cc55cSDimitry Andric   bool hasJIT() const { return HasJIT; }
393349cc55cSDimitry Andric 
394349cc55cSDimitry Andric   /// hasTargetMachine - Check if this target supports code generation.
395349cc55cSDimitry Andric   bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
396349cc55cSDimitry Andric 
397349cc55cSDimitry Andric   /// hasMCAsmBackend - Check if this target supports .o generation.
398349cc55cSDimitry Andric   bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
399349cc55cSDimitry Andric 
400349cc55cSDimitry Andric   /// hasMCAsmParser - Check if this target supports assembly parsing.
401349cc55cSDimitry Andric   bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; }
402349cc55cSDimitry Andric 
403349cc55cSDimitry Andric   /// @}
404349cc55cSDimitry Andric   /// @name Feature Constructors
405349cc55cSDimitry Andric   /// @{
406349cc55cSDimitry Andric 
407349cc55cSDimitry Andric   /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
408349cc55cSDimitry Andric   /// target triple.
409349cc55cSDimitry Andric   ///
410349cc55cSDimitry Andric   /// \param TheTriple This argument is used to determine the target machine
411349cc55cSDimitry Andric   /// feature set; it should always be provided. Generally this should be
412349cc55cSDimitry Andric   /// either the target triple from the module, or the target triple of the
413349cc55cSDimitry Andric   /// host if that does not exist.
414349cc55cSDimitry Andric   MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple,
415349cc55cSDimitry Andric                              const MCTargetOptions &Options) const {
416349cc55cSDimitry Andric     if (!MCAsmInfoCtorFn)
417349cc55cSDimitry Andric       return nullptr;
418349cc55cSDimitry Andric     return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options);
419349cc55cSDimitry Andric   }
420349cc55cSDimitry Andric 
421349cc55cSDimitry Andric   /// Create a MCObjectFileInfo implementation for the specified target
422349cc55cSDimitry Andric   /// triple.
423349cc55cSDimitry Andric   ///
424349cc55cSDimitry Andric   MCObjectFileInfo *createMCObjectFileInfo(MCContext &Ctx, bool PIC,
425349cc55cSDimitry Andric                                            bool LargeCodeModel = false) const {
426349cc55cSDimitry Andric     if (!MCObjectFileInfoCtorFn) {
427349cc55cSDimitry Andric       MCObjectFileInfo *MOFI = new MCObjectFileInfo();
428349cc55cSDimitry Andric       MOFI->initMCObjectFileInfo(Ctx, PIC, LargeCodeModel);
429349cc55cSDimitry Andric       return MOFI;
430349cc55cSDimitry Andric     }
431349cc55cSDimitry Andric     return MCObjectFileInfoCtorFn(Ctx, PIC, LargeCodeModel);
432349cc55cSDimitry Andric   }
433349cc55cSDimitry Andric 
434349cc55cSDimitry Andric   /// createMCInstrInfo - Create a MCInstrInfo implementation.
435349cc55cSDimitry Andric   ///
436349cc55cSDimitry Andric   MCInstrInfo *createMCInstrInfo() const {
437349cc55cSDimitry Andric     if (!MCInstrInfoCtorFn)
438349cc55cSDimitry Andric       return nullptr;
439349cc55cSDimitry Andric     return MCInstrInfoCtorFn();
440349cc55cSDimitry Andric   }
441349cc55cSDimitry Andric 
442349cc55cSDimitry Andric   /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
443349cc55cSDimitry Andric   ///
444349cc55cSDimitry Andric   MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
445349cc55cSDimitry Andric     if (!MCInstrAnalysisCtorFn)
446349cc55cSDimitry Andric       return nullptr;
447349cc55cSDimitry Andric     return MCInstrAnalysisCtorFn(Info);
448349cc55cSDimitry Andric   }
449349cc55cSDimitry Andric 
450349cc55cSDimitry Andric   /// createMCRegInfo - Create a MCRegisterInfo implementation.
451349cc55cSDimitry Andric   ///
452349cc55cSDimitry Andric   MCRegisterInfo *createMCRegInfo(StringRef TT) const {
453349cc55cSDimitry Andric     if (!MCRegInfoCtorFn)
454349cc55cSDimitry Andric       return nullptr;
455349cc55cSDimitry Andric     return MCRegInfoCtorFn(Triple(TT));
456349cc55cSDimitry Andric   }
457349cc55cSDimitry Andric 
458349cc55cSDimitry Andric   /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
459349cc55cSDimitry Andric   ///
460349cc55cSDimitry Andric   /// \param TheTriple This argument is used to determine the target machine
461349cc55cSDimitry Andric   /// feature set; it should always be provided. Generally this should be
462349cc55cSDimitry Andric   /// either the target triple from the module, or the target triple of the
463349cc55cSDimitry Andric   /// host if that does not exist.
464349cc55cSDimitry Andric   /// \param CPU This specifies the name of the target CPU.
465349cc55cSDimitry Andric   /// \param Features This specifies the string representation of the
466349cc55cSDimitry Andric   /// additional target features.
467349cc55cSDimitry Andric   MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU,
468349cc55cSDimitry Andric                                          StringRef Features) const {
469349cc55cSDimitry Andric     if (!MCSubtargetInfoCtorFn)
470349cc55cSDimitry Andric       return nullptr;
471349cc55cSDimitry Andric     return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features);
472349cc55cSDimitry Andric   }
473349cc55cSDimitry Andric 
474349cc55cSDimitry Andric   /// createTargetMachine - Create a target specific machine implementation
475349cc55cSDimitry Andric   /// for the specified \p Triple.
476349cc55cSDimitry Andric   ///
477349cc55cSDimitry Andric   /// \param TT This argument is used to determine the target machine
478349cc55cSDimitry Andric   /// feature set; it should always be provided. Generally this should be
479349cc55cSDimitry Andric   /// either the target triple from the module, or the target triple of the
480349cc55cSDimitry Andric   /// host if that does not exist.
481*bdd1243dSDimitry Andric   TargetMachine *createTargetMachine(
482*bdd1243dSDimitry Andric       StringRef TT, StringRef CPU, StringRef Features,
483*bdd1243dSDimitry Andric       const TargetOptions &Options, std::optional<Reloc::Model> RM,
484*bdd1243dSDimitry Andric       std::optional<CodeModel::Model> CM = std::nullopt,
485*bdd1243dSDimitry Andric       CodeGenOpt::Level OL = CodeGenOpt::Default, bool JIT = false) const {
486349cc55cSDimitry Andric     if (!TargetMachineCtorFn)
487349cc55cSDimitry Andric       return nullptr;
488349cc55cSDimitry Andric     return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM,
489349cc55cSDimitry Andric                                CM, OL, JIT);
490349cc55cSDimitry Andric   }
491349cc55cSDimitry Andric 
492349cc55cSDimitry Andric   /// createMCAsmBackend - Create a target specific assembly parser.
493349cc55cSDimitry Andric   MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI,
494349cc55cSDimitry Andric                                    const MCRegisterInfo &MRI,
495349cc55cSDimitry Andric                                    const MCTargetOptions &Options) const {
496349cc55cSDimitry Andric     if (!MCAsmBackendCtorFn)
497349cc55cSDimitry Andric       return nullptr;
498349cc55cSDimitry Andric     return MCAsmBackendCtorFn(*this, STI, MRI, Options);
499349cc55cSDimitry Andric   }
500349cc55cSDimitry Andric 
501349cc55cSDimitry Andric   /// createMCAsmParser - Create a target specific assembly parser.
502349cc55cSDimitry Andric   ///
503349cc55cSDimitry Andric   /// \param Parser The target independent parser implementation to use for
504349cc55cSDimitry Andric   /// parsing and lexing.
505349cc55cSDimitry Andric   MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI,
506349cc55cSDimitry Andric                                        MCAsmParser &Parser,
507349cc55cSDimitry Andric                                        const MCInstrInfo &MII,
508349cc55cSDimitry Andric                                        const MCTargetOptions &Options) const {
509349cc55cSDimitry Andric     if (!MCAsmParserCtorFn)
510349cc55cSDimitry Andric       return nullptr;
511349cc55cSDimitry Andric     return MCAsmParserCtorFn(STI, Parser, MII, Options);
512349cc55cSDimitry Andric   }
513349cc55cSDimitry Andric 
514349cc55cSDimitry Andric   /// createAsmPrinter - Create a target specific assembly printer pass.  This
515349cc55cSDimitry Andric   /// takes ownership of the MCStreamer object.
516349cc55cSDimitry Andric   AsmPrinter *createAsmPrinter(TargetMachine &TM,
517349cc55cSDimitry Andric                                std::unique_ptr<MCStreamer> &&Streamer) const {
518349cc55cSDimitry Andric     if (!AsmPrinterCtorFn)
519349cc55cSDimitry Andric       return nullptr;
520349cc55cSDimitry Andric     return AsmPrinterCtorFn(TM, std::move(Streamer));
521349cc55cSDimitry Andric   }
522349cc55cSDimitry Andric 
523349cc55cSDimitry Andric   MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
524349cc55cSDimitry Andric                                        MCContext &Ctx) const {
525349cc55cSDimitry Andric     if (!MCDisassemblerCtorFn)
526349cc55cSDimitry Andric       return nullptr;
527349cc55cSDimitry Andric     return MCDisassemblerCtorFn(*this, STI, Ctx);
528349cc55cSDimitry Andric   }
529349cc55cSDimitry Andric 
530349cc55cSDimitry Andric   MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
531349cc55cSDimitry Andric                                      const MCAsmInfo &MAI,
532349cc55cSDimitry Andric                                      const MCInstrInfo &MII,
533349cc55cSDimitry Andric                                      const MCRegisterInfo &MRI) const {
534349cc55cSDimitry Andric     if (!MCInstPrinterCtorFn)
535349cc55cSDimitry Andric       return nullptr;
536349cc55cSDimitry Andric     return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
537349cc55cSDimitry Andric   }
538349cc55cSDimitry Andric 
539349cc55cSDimitry Andric   /// createMCCodeEmitter - Create a target specific code emitter.
540349cc55cSDimitry Andric   MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
541349cc55cSDimitry Andric                                      MCContext &Ctx) const {
542349cc55cSDimitry Andric     if (!MCCodeEmitterCtorFn)
543349cc55cSDimitry Andric       return nullptr;
54481ad6265SDimitry Andric     return MCCodeEmitterCtorFn(II, Ctx);
545349cc55cSDimitry Andric   }
546349cc55cSDimitry Andric 
547349cc55cSDimitry Andric   /// Create a target specific MCStreamer.
548349cc55cSDimitry Andric   ///
549349cc55cSDimitry Andric   /// \param T The target triple.
550349cc55cSDimitry Andric   /// \param Ctx The target context.
551349cc55cSDimitry Andric   /// \param TAB The target assembler backend object. Takes ownership.
552349cc55cSDimitry Andric   /// \param OW The stream object.
553349cc55cSDimitry Andric   /// \param Emitter The target independent assembler object.Takes ownership.
554349cc55cSDimitry Andric   /// \param RelaxAll Relax all fixups?
555349cc55cSDimitry Andric   MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
556349cc55cSDimitry Andric                                      std::unique_ptr<MCAsmBackend> &&TAB,
557349cc55cSDimitry Andric                                      std::unique_ptr<MCObjectWriter> &&OW,
558349cc55cSDimitry Andric                                      std::unique_ptr<MCCodeEmitter> &&Emitter,
559349cc55cSDimitry Andric                                      const MCSubtargetInfo &STI, bool RelaxAll,
560349cc55cSDimitry Andric                                      bool IncrementalLinkerCompatible,
561349cc55cSDimitry Andric                                      bool DWARFMustBeAtTheEnd) const {
562349cc55cSDimitry Andric     MCStreamer *S = nullptr;
563349cc55cSDimitry Andric     switch (T.getObjectFormat()) {
564349cc55cSDimitry Andric     case Triple::UnknownObjectFormat:
565349cc55cSDimitry Andric       llvm_unreachable("Unknown object format");
566349cc55cSDimitry Andric     case Triple::COFF:
567349cc55cSDimitry Andric       assert(T.isOSWindows() && "only Windows COFF is supported");
568349cc55cSDimitry Andric       S = COFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
569349cc55cSDimitry Andric                              std::move(Emitter), RelaxAll,
570349cc55cSDimitry Andric                              IncrementalLinkerCompatible);
571349cc55cSDimitry Andric       break;
572349cc55cSDimitry Andric     case Triple::MachO:
573349cc55cSDimitry Andric       if (MachOStreamerCtorFn)
574349cc55cSDimitry Andric         S = MachOStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
575349cc55cSDimitry Andric                                 std::move(Emitter), RelaxAll,
576349cc55cSDimitry Andric                                 DWARFMustBeAtTheEnd);
577349cc55cSDimitry Andric       else
578349cc55cSDimitry Andric         S = createMachOStreamer(Ctx, std::move(TAB), std::move(OW),
579349cc55cSDimitry Andric                                 std::move(Emitter), RelaxAll,
580349cc55cSDimitry Andric                                 DWARFMustBeAtTheEnd);
581349cc55cSDimitry Andric       break;
582349cc55cSDimitry Andric     case Triple::ELF:
583349cc55cSDimitry Andric       if (ELFStreamerCtorFn)
584349cc55cSDimitry Andric         S = ELFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
585349cc55cSDimitry Andric                               std::move(Emitter), RelaxAll);
586349cc55cSDimitry Andric       else
587349cc55cSDimitry Andric         S = createELFStreamer(Ctx, std::move(TAB), std::move(OW),
588349cc55cSDimitry Andric                               std::move(Emitter), RelaxAll);
589349cc55cSDimitry Andric       break;
590349cc55cSDimitry Andric     case Triple::Wasm:
591349cc55cSDimitry Andric       if (WasmStreamerCtorFn)
592349cc55cSDimitry Andric         S = WasmStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
593349cc55cSDimitry Andric                                std::move(Emitter), RelaxAll);
594349cc55cSDimitry Andric       else
595349cc55cSDimitry Andric         S = createWasmStreamer(Ctx, std::move(TAB), std::move(OW),
596349cc55cSDimitry Andric                                std::move(Emitter), RelaxAll);
597349cc55cSDimitry Andric       break;
598349cc55cSDimitry Andric     case Triple::GOFF:
599349cc55cSDimitry Andric       report_fatal_error("GOFF MCObjectStreamer not implemented yet");
600349cc55cSDimitry Andric     case Triple::XCOFF:
601349cc55cSDimitry Andric       if (XCOFFStreamerCtorFn)
602349cc55cSDimitry Andric         S = XCOFFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
603349cc55cSDimitry Andric                                 std::move(Emitter), RelaxAll);
604349cc55cSDimitry Andric       else
605349cc55cSDimitry Andric         S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
606349cc55cSDimitry Andric                                 std::move(Emitter), RelaxAll);
607349cc55cSDimitry Andric       break;
60881ad6265SDimitry Andric     case Triple::SPIRV:
60981ad6265SDimitry Andric       if (SPIRVStreamerCtorFn)
61081ad6265SDimitry Andric         S = SPIRVStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
61181ad6265SDimitry Andric                                 std::move(Emitter), RelaxAll);
61281ad6265SDimitry Andric       else
61381ad6265SDimitry Andric         S = createSPIRVStreamer(Ctx, std::move(TAB), std::move(OW),
61481ad6265SDimitry Andric                                 std::move(Emitter), RelaxAll);
61581ad6265SDimitry Andric       break;
61681ad6265SDimitry Andric     case Triple::DXContainer:
61781ad6265SDimitry Andric       if (DXContainerStreamerCtorFn)
61881ad6265SDimitry Andric         S = DXContainerStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
61981ad6265SDimitry Andric                               std::move(Emitter), RelaxAll);
62081ad6265SDimitry Andric       else
62181ad6265SDimitry Andric         S = createDXContainerStreamer(Ctx, std::move(TAB), std::move(OW),
62281ad6265SDimitry Andric                                       std::move(Emitter), RelaxAll);
62381ad6265SDimitry Andric       break;
624349cc55cSDimitry Andric     }
625349cc55cSDimitry Andric     if (ObjectTargetStreamerCtorFn)
626349cc55cSDimitry Andric       ObjectTargetStreamerCtorFn(*S, STI);
627349cc55cSDimitry Andric     return S;
628349cc55cSDimitry Andric   }
629349cc55cSDimitry Andric 
630349cc55cSDimitry Andric   MCStreamer *createAsmStreamer(MCContext &Ctx,
631349cc55cSDimitry Andric                                 std::unique_ptr<formatted_raw_ostream> OS,
632349cc55cSDimitry Andric                                 bool IsVerboseAsm, bool UseDwarfDirectory,
633349cc55cSDimitry Andric                                 MCInstPrinter *InstPrint,
634349cc55cSDimitry Andric                                 std::unique_ptr<MCCodeEmitter> &&CE,
635349cc55cSDimitry Andric                                 std::unique_ptr<MCAsmBackend> &&TAB,
636349cc55cSDimitry Andric                                 bool ShowInst) const {
637349cc55cSDimitry Andric     formatted_raw_ostream &OSRef = *OS;
638349cc55cSDimitry Andric     MCStreamer *S = llvm::createAsmStreamer(
639349cc55cSDimitry Andric         Ctx, std::move(OS), IsVerboseAsm, UseDwarfDirectory, InstPrint,
640349cc55cSDimitry Andric         std::move(CE), std::move(TAB), ShowInst);
641349cc55cSDimitry Andric     createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
642349cc55cSDimitry Andric     return S;
643349cc55cSDimitry Andric   }
644349cc55cSDimitry Andric 
645349cc55cSDimitry Andric   MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
646349cc55cSDimitry Andric                                             formatted_raw_ostream &OS,
647349cc55cSDimitry Andric                                             MCInstPrinter *InstPrint,
648349cc55cSDimitry Andric                                             bool IsVerboseAsm) const {
649349cc55cSDimitry Andric     if (AsmTargetStreamerCtorFn)
650349cc55cSDimitry Andric       return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm);
651349cc55cSDimitry Andric     return nullptr;
652349cc55cSDimitry Andric   }
653349cc55cSDimitry Andric 
654349cc55cSDimitry Andric   MCStreamer *createNullStreamer(MCContext &Ctx) const {
655349cc55cSDimitry Andric     MCStreamer *S = llvm::createNullStreamer(Ctx);
656349cc55cSDimitry Andric     createNullTargetStreamer(*S);
657349cc55cSDimitry Andric     return S;
658349cc55cSDimitry Andric   }
659349cc55cSDimitry Andric 
660349cc55cSDimitry Andric   MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
661349cc55cSDimitry Andric     if (NullTargetStreamerCtorFn)
662349cc55cSDimitry Andric       return NullTargetStreamerCtorFn(S);
663349cc55cSDimitry Andric     return nullptr;
664349cc55cSDimitry Andric   }
665349cc55cSDimitry Andric 
666349cc55cSDimitry Andric   /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
667349cc55cSDimitry Andric   ///
668349cc55cSDimitry Andric   /// \param TT The target triple.
669349cc55cSDimitry Andric   /// \param Ctx The target context.
670349cc55cSDimitry Andric   MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
671349cc55cSDimitry Andric     MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
672349cc55cSDimitry Andric                                     ? MCRelocationInfoCtorFn
673349cc55cSDimitry Andric                                     : llvm::createMCRelocationInfo;
674349cc55cSDimitry Andric     return Fn(Triple(TT), Ctx);
675349cc55cSDimitry Andric   }
676349cc55cSDimitry Andric 
677349cc55cSDimitry Andric   /// createMCSymbolizer - Create a target specific MCSymbolizer.
678349cc55cSDimitry Andric   ///
679349cc55cSDimitry Andric   /// \param TT The target triple.
680349cc55cSDimitry Andric   /// \param GetOpInfo The function to get the symbolic information for
681349cc55cSDimitry Andric   /// operands.
682349cc55cSDimitry Andric   /// \param SymbolLookUp The function to lookup a symbol name.
683349cc55cSDimitry Andric   /// \param DisInfo The pointer to the block of symbolic information for above
684349cc55cSDimitry Andric   /// call
685349cc55cSDimitry Andric   /// back.
686349cc55cSDimitry Andric   /// \param Ctx The target context.
687349cc55cSDimitry Andric   /// \param RelInfo The relocation information for this target. Takes
688349cc55cSDimitry Andric   /// ownership.
689349cc55cSDimitry Andric   MCSymbolizer *
690349cc55cSDimitry Andric   createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
691349cc55cSDimitry Andric                      LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
692349cc55cSDimitry Andric                      MCContext *Ctx,
693349cc55cSDimitry Andric                      std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
694349cc55cSDimitry Andric     MCSymbolizerCtorTy Fn =
695349cc55cSDimitry Andric         MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
696349cc55cSDimitry Andric     return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx,
697349cc55cSDimitry Andric               std::move(RelInfo));
698349cc55cSDimitry Andric   }
699349cc55cSDimitry Andric 
700349cc55cSDimitry Andric   /// createCustomBehaviour - Create a target specific CustomBehaviour.
701349cc55cSDimitry Andric   /// This class is used by llvm-mca and requires backend functionality.
702349cc55cSDimitry Andric   mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI,
703349cc55cSDimitry Andric                                               const mca::SourceMgr &SrcMgr,
704349cc55cSDimitry Andric                                               const MCInstrInfo &MCII) const {
705349cc55cSDimitry Andric     if (CustomBehaviourCtorFn)
706349cc55cSDimitry Andric       return CustomBehaviourCtorFn(STI, SrcMgr, MCII);
707349cc55cSDimitry Andric     return nullptr;
708349cc55cSDimitry Andric   }
709349cc55cSDimitry Andric 
710349cc55cSDimitry Andric   /// createInstrPostProcess - Create a target specific InstrPostProcess.
711349cc55cSDimitry Andric   /// This class is used by llvm-mca and requires backend functionality.
712349cc55cSDimitry Andric   mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI,
713349cc55cSDimitry Andric                                                 const MCInstrInfo &MCII) const {
714349cc55cSDimitry Andric     if (InstrPostProcessCtorFn)
715349cc55cSDimitry Andric       return InstrPostProcessCtorFn(STI, MCII);
716349cc55cSDimitry Andric     return nullptr;
717349cc55cSDimitry Andric   }
718349cc55cSDimitry Andric 
719*bdd1243dSDimitry Andric   /// createInstrumentManager - Create a target specific
720*bdd1243dSDimitry Andric   /// InstrumentManager. This class is used by llvm-mca and requires
721*bdd1243dSDimitry Andric   /// backend functionality.
722*bdd1243dSDimitry Andric   mca::InstrumentManager *
723*bdd1243dSDimitry Andric   createInstrumentManager(const MCSubtargetInfo &STI,
724*bdd1243dSDimitry Andric                           const MCInstrInfo &MCII) const {
725*bdd1243dSDimitry Andric     if (InstrumentManagerCtorFn)
726*bdd1243dSDimitry Andric       return InstrumentManagerCtorFn(STI, MCII);
727*bdd1243dSDimitry Andric     return nullptr;
728*bdd1243dSDimitry Andric   }
729*bdd1243dSDimitry Andric 
730349cc55cSDimitry Andric   /// @}
731349cc55cSDimitry Andric };
732349cc55cSDimitry Andric 
733349cc55cSDimitry Andric /// TargetRegistry - Generic interface to target specific features.
734349cc55cSDimitry Andric struct TargetRegistry {
735349cc55cSDimitry Andric   // FIXME: Make this a namespace, probably just move all the Register*
736349cc55cSDimitry Andric   // functions into Target (currently they all just set members on the Target
737349cc55cSDimitry Andric   // anyway, and Target friends this class so those functions can...
738349cc55cSDimitry Andric   // function).
739349cc55cSDimitry Andric   TargetRegistry() = delete;
740349cc55cSDimitry Andric 
741349cc55cSDimitry Andric   class iterator {
742349cc55cSDimitry Andric     friend struct TargetRegistry;
743349cc55cSDimitry Andric 
744349cc55cSDimitry Andric     const Target *Current = nullptr;
745349cc55cSDimitry Andric 
746349cc55cSDimitry Andric     explicit iterator(Target *T) : Current(T) {}
747349cc55cSDimitry Andric 
748349cc55cSDimitry Andric   public:
749349cc55cSDimitry Andric     using iterator_category = std::forward_iterator_tag;
750349cc55cSDimitry Andric     using value_type = Target;
751349cc55cSDimitry Andric     using difference_type = std::ptrdiff_t;
752349cc55cSDimitry Andric     using pointer = value_type *;
753349cc55cSDimitry Andric     using reference = value_type &;
754349cc55cSDimitry Andric 
755349cc55cSDimitry Andric     iterator() = default;
756349cc55cSDimitry Andric 
757349cc55cSDimitry Andric     bool operator==(const iterator &x) const { return Current == x.Current; }
758349cc55cSDimitry Andric     bool operator!=(const iterator &x) const { return !operator==(x); }
759349cc55cSDimitry Andric 
760349cc55cSDimitry Andric     // Iterator traversal: forward iteration only
761349cc55cSDimitry Andric     iterator &operator++() { // Preincrement
762349cc55cSDimitry Andric       assert(Current && "Cannot increment end iterator!");
763349cc55cSDimitry Andric       Current = Current->getNext();
764349cc55cSDimitry Andric       return *this;
765349cc55cSDimitry Andric     }
766349cc55cSDimitry Andric     iterator operator++(int) { // Postincrement
767349cc55cSDimitry Andric       iterator tmp = *this;
768349cc55cSDimitry Andric       ++*this;
769349cc55cSDimitry Andric       return tmp;
770349cc55cSDimitry Andric     }
771349cc55cSDimitry Andric 
772349cc55cSDimitry Andric     const Target &operator*() const {
773349cc55cSDimitry Andric       assert(Current && "Cannot dereference end iterator!");
774349cc55cSDimitry Andric       return *Current;
775349cc55cSDimitry Andric     }
776349cc55cSDimitry Andric 
777349cc55cSDimitry Andric     const Target *operator->() const { return &operator*(); }
778349cc55cSDimitry Andric   };
779349cc55cSDimitry Andric 
780349cc55cSDimitry Andric   /// printRegisteredTargetsForVersion - Print the registered targets
781349cc55cSDimitry Andric   /// appropriately for inclusion in a tool's version output.
782349cc55cSDimitry Andric   static void printRegisteredTargetsForVersion(raw_ostream &OS);
783349cc55cSDimitry Andric 
784349cc55cSDimitry Andric   /// @name Registry Access
785349cc55cSDimitry Andric   /// @{
786349cc55cSDimitry Andric 
787349cc55cSDimitry Andric   static iterator_range<iterator> targets();
788349cc55cSDimitry Andric 
789349cc55cSDimitry Andric   /// lookupTarget - Lookup a target based on a target triple.
790349cc55cSDimitry Andric   ///
791349cc55cSDimitry Andric   /// \param Triple - The triple to use for finding a target.
792349cc55cSDimitry Andric   /// \param Error - On failure, an error string describing why no target was
793349cc55cSDimitry Andric   /// found.
794349cc55cSDimitry Andric   static const Target *lookupTarget(const std::string &Triple,
795349cc55cSDimitry Andric                                     std::string &Error);
796349cc55cSDimitry Andric 
797349cc55cSDimitry Andric   /// lookupTarget - Lookup a target based on an architecture name
798349cc55cSDimitry Andric   /// and a target triple.  If the architecture name is non-empty,
799349cc55cSDimitry Andric   /// then the lookup is done by architecture.  Otherwise, the target
800349cc55cSDimitry Andric   /// triple is used.
801349cc55cSDimitry Andric   ///
802349cc55cSDimitry Andric   /// \param ArchName - The architecture to use for finding a target.
803349cc55cSDimitry Andric   /// \param TheTriple - The triple to use for finding a target.  The
804349cc55cSDimitry Andric   /// triple is updated with canonical architecture name if a lookup
805349cc55cSDimitry Andric   /// by architecture is done.
806349cc55cSDimitry Andric   /// \param Error - On failure, an error string describing why no target was
807349cc55cSDimitry Andric   /// found.
808349cc55cSDimitry Andric   static const Target *lookupTarget(const std::string &ArchName,
809349cc55cSDimitry Andric                                     Triple &TheTriple, std::string &Error);
810349cc55cSDimitry Andric 
811349cc55cSDimitry Andric   /// @}
812349cc55cSDimitry Andric   /// @name Target Registration
813349cc55cSDimitry Andric   /// @{
814349cc55cSDimitry Andric 
815349cc55cSDimitry Andric   /// RegisterTarget - Register the given target. Attempts to register a
816349cc55cSDimitry Andric   /// target which has already been registered will be ignored.
817349cc55cSDimitry Andric   ///
818349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
819349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
820349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
821349cc55cSDimitry Andric   ///
822349cc55cSDimitry Andric   /// @param T - The target being registered.
823349cc55cSDimitry Andric   /// @param Name - The target name. This should be a static string.
824349cc55cSDimitry Andric   /// @param ShortDesc - A short target description. This should be a static
825349cc55cSDimitry Andric   /// string.
826349cc55cSDimitry Andric   /// @param BackendName - The name of the backend. This should be a static
827349cc55cSDimitry Andric   /// string that is the same for all targets that share a backend
828349cc55cSDimitry Andric   /// implementation and must match the name used in the 'def X : Target ...' in
829349cc55cSDimitry Andric   /// TableGen.
830349cc55cSDimitry Andric   /// @param ArchMatchFn - The arch match checking function for this target.
831349cc55cSDimitry Andric   /// @param HasJIT - Whether the target supports JIT code
832349cc55cSDimitry Andric   /// generation.
833349cc55cSDimitry Andric   static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc,
834349cc55cSDimitry Andric                              const char *BackendName,
835349cc55cSDimitry Andric                              Target::ArchMatchFnTy ArchMatchFn,
836349cc55cSDimitry Andric                              bool HasJIT = false);
837349cc55cSDimitry Andric 
838349cc55cSDimitry Andric   /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
839349cc55cSDimitry Andric   /// given target.
840349cc55cSDimitry Andric   ///
841349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
842349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
843349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
844349cc55cSDimitry Andric   ///
845349cc55cSDimitry Andric   /// @param T - The target being registered.
846349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCAsmInfo for the target.
847349cc55cSDimitry Andric   static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
848349cc55cSDimitry Andric     T.MCAsmInfoCtorFn = Fn;
849349cc55cSDimitry Andric   }
850349cc55cSDimitry Andric 
851349cc55cSDimitry Andric   /// Register a MCObjectFileInfo implementation for the given target.
852349cc55cSDimitry Andric   ///
853349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
854349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
855349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
856349cc55cSDimitry Andric   ///
857349cc55cSDimitry Andric   /// @param T - The target being registered.
858349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCObjectFileInfo for the target.
859349cc55cSDimitry Andric   static void RegisterMCObjectFileInfo(Target &T,
860349cc55cSDimitry Andric                                        Target::MCObjectFileInfoCtorFnTy Fn) {
861349cc55cSDimitry Andric     T.MCObjectFileInfoCtorFn = Fn;
862349cc55cSDimitry Andric   }
863349cc55cSDimitry Andric 
864349cc55cSDimitry Andric   /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
865349cc55cSDimitry Andric   /// given target.
866349cc55cSDimitry Andric   ///
867349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
868349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
869349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
870349cc55cSDimitry Andric   ///
871349cc55cSDimitry Andric   /// @param T - The target being registered.
872349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCInstrInfo for the target.
873349cc55cSDimitry Andric   static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
874349cc55cSDimitry Andric     T.MCInstrInfoCtorFn = Fn;
875349cc55cSDimitry Andric   }
876349cc55cSDimitry Andric 
877349cc55cSDimitry Andric   /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
878349cc55cSDimitry Andric   /// the given target.
879349cc55cSDimitry Andric   static void RegisterMCInstrAnalysis(Target &T,
880349cc55cSDimitry Andric                                       Target::MCInstrAnalysisCtorFnTy Fn) {
881349cc55cSDimitry Andric     T.MCInstrAnalysisCtorFn = Fn;
882349cc55cSDimitry Andric   }
883349cc55cSDimitry Andric 
884349cc55cSDimitry Andric   /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
885349cc55cSDimitry Andric   /// given target.
886349cc55cSDimitry Andric   ///
887349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
888349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
889349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
890349cc55cSDimitry Andric   ///
891349cc55cSDimitry Andric   /// @param T - The target being registered.
892349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCRegisterInfo for the target.
893349cc55cSDimitry Andric   static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
894349cc55cSDimitry Andric     T.MCRegInfoCtorFn = Fn;
895349cc55cSDimitry Andric   }
896349cc55cSDimitry Andric 
897349cc55cSDimitry Andric   /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
898349cc55cSDimitry Andric   /// the given target.
899349cc55cSDimitry Andric   ///
900349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
901349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
902349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
903349cc55cSDimitry Andric   ///
904349cc55cSDimitry Andric   /// @param T - The target being registered.
905349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCSubtargetInfo for the target.
906349cc55cSDimitry Andric   static void RegisterMCSubtargetInfo(Target &T,
907349cc55cSDimitry Andric                                       Target::MCSubtargetInfoCtorFnTy Fn) {
908349cc55cSDimitry Andric     T.MCSubtargetInfoCtorFn = Fn;
909349cc55cSDimitry Andric   }
910349cc55cSDimitry Andric 
911349cc55cSDimitry Andric   /// RegisterTargetMachine - Register a TargetMachine implementation for the
912349cc55cSDimitry Andric   /// given target.
913349cc55cSDimitry Andric   ///
914349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
915349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
916349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
917349cc55cSDimitry Andric   ///
918349cc55cSDimitry Andric   /// @param T - The target being registered.
919349cc55cSDimitry Andric   /// @param Fn - A function to construct a TargetMachine for the target.
920349cc55cSDimitry Andric   static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) {
921349cc55cSDimitry Andric     T.TargetMachineCtorFn = Fn;
922349cc55cSDimitry Andric   }
923349cc55cSDimitry Andric 
924349cc55cSDimitry Andric   /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
925349cc55cSDimitry Andric   /// given target.
926349cc55cSDimitry Andric   ///
927349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
928349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
929349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
930349cc55cSDimitry Andric   ///
931349cc55cSDimitry Andric   /// @param T - The target being registered.
932349cc55cSDimitry Andric   /// @param Fn - A function to construct an AsmBackend for the target.
933349cc55cSDimitry Andric   static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
934349cc55cSDimitry Andric     T.MCAsmBackendCtorFn = Fn;
935349cc55cSDimitry Andric   }
936349cc55cSDimitry Andric 
937349cc55cSDimitry Andric   /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
938349cc55cSDimitry Andric   /// the given target.
939349cc55cSDimitry Andric   ///
940349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
941349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
942349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
943349cc55cSDimitry Andric   ///
944349cc55cSDimitry Andric   /// @param T - The target being registered.
945349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCTargetAsmParser for the target.
946349cc55cSDimitry Andric   static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
947349cc55cSDimitry Andric     T.MCAsmParserCtorFn = Fn;
948349cc55cSDimitry Andric   }
949349cc55cSDimitry Andric 
950349cc55cSDimitry Andric   /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
951349cc55cSDimitry Andric   /// target.
952349cc55cSDimitry Andric   ///
953349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
954349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
955349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
956349cc55cSDimitry Andric   ///
957349cc55cSDimitry Andric   /// @param T - The target being registered.
958349cc55cSDimitry Andric   /// @param Fn - A function to construct an AsmPrinter for the target.
959349cc55cSDimitry Andric   static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
960349cc55cSDimitry Andric     T.AsmPrinterCtorFn = Fn;
961349cc55cSDimitry Andric   }
962349cc55cSDimitry Andric 
963349cc55cSDimitry Andric   /// RegisterMCDisassembler - Register a MCDisassembler implementation for
964349cc55cSDimitry Andric   /// the given target.
965349cc55cSDimitry Andric   ///
966349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
967349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
968349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
969349cc55cSDimitry Andric   ///
970349cc55cSDimitry Andric   /// @param T - The target being registered.
971349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCDisassembler for the target.
972349cc55cSDimitry Andric   static void RegisterMCDisassembler(Target &T,
973349cc55cSDimitry Andric                                      Target::MCDisassemblerCtorTy Fn) {
974349cc55cSDimitry Andric     T.MCDisassemblerCtorFn = Fn;
975349cc55cSDimitry Andric   }
976349cc55cSDimitry Andric 
977349cc55cSDimitry Andric   /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
978349cc55cSDimitry Andric   /// given target.
979349cc55cSDimitry Andric   ///
980349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
981349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
982349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
983349cc55cSDimitry Andric   ///
984349cc55cSDimitry Andric   /// @param T - The target being registered.
985349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCInstPrinter for the target.
986349cc55cSDimitry Andric   static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) {
987349cc55cSDimitry Andric     T.MCInstPrinterCtorFn = Fn;
988349cc55cSDimitry Andric   }
989349cc55cSDimitry Andric 
990349cc55cSDimitry Andric   /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
991349cc55cSDimitry Andric   /// given target.
992349cc55cSDimitry Andric   ///
993349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
994349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
995349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
996349cc55cSDimitry Andric   ///
997349cc55cSDimitry Andric   /// @param T - The target being registered.
998349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCCodeEmitter for the target.
999349cc55cSDimitry Andric   static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) {
1000349cc55cSDimitry Andric     T.MCCodeEmitterCtorFn = Fn;
1001349cc55cSDimitry Andric   }
1002349cc55cSDimitry Andric 
1003349cc55cSDimitry Andric   static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
1004349cc55cSDimitry Andric     T.COFFStreamerCtorFn = Fn;
1005349cc55cSDimitry Andric   }
1006349cc55cSDimitry Andric 
1007349cc55cSDimitry Andric   static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) {
1008349cc55cSDimitry Andric     T.MachOStreamerCtorFn = Fn;
1009349cc55cSDimitry Andric   }
1010349cc55cSDimitry Andric 
1011349cc55cSDimitry Andric   static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
1012349cc55cSDimitry Andric     T.ELFStreamerCtorFn = Fn;
1013349cc55cSDimitry Andric   }
1014349cc55cSDimitry Andric 
101581ad6265SDimitry Andric   static void RegisterSPIRVStreamer(Target &T, Target::SPIRVStreamerCtorTy Fn) {
101681ad6265SDimitry Andric     T.SPIRVStreamerCtorFn = Fn;
101781ad6265SDimitry Andric   }
101881ad6265SDimitry Andric 
101981ad6265SDimitry Andric   static void RegisterDXContainerStreamer(Target &T, Target::DXContainerStreamerCtorTy Fn) {
102081ad6265SDimitry Andric     T.DXContainerStreamerCtorFn = Fn;
102181ad6265SDimitry Andric   }
102281ad6265SDimitry Andric 
1023349cc55cSDimitry Andric   static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) {
1024349cc55cSDimitry Andric     T.WasmStreamerCtorFn = Fn;
1025349cc55cSDimitry Andric   }
1026349cc55cSDimitry Andric 
1027349cc55cSDimitry Andric   static void RegisterXCOFFStreamer(Target &T, Target::XCOFFStreamerCtorTy Fn) {
1028349cc55cSDimitry Andric     T.XCOFFStreamerCtorFn = Fn;
1029349cc55cSDimitry Andric   }
1030349cc55cSDimitry Andric 
1031349cc55cSDimitry Andric   static void RegisterNullTargetStreamer(Target &T,
1032349cc55cSDimitry Andric                                          Target::NullTargetStreamerCtorTy Fn) {
1033349cc55cSDimitry Andric     T.NullTargetStreamerCtorFn = Fn;
1034349cc55cSDimitry Andric   }
1035349cc55cSDimitry Andric 
1036349cc55cSDimitry Andric   static void RegisterAsmTargetStreamer(Target &T,
1037349cc55cSDimitry Andric                                         Target::AsmTargetStreamerCtorTy Fn) {
1038349cc55cSDimitry Andric     T.AsmTargetStreamerCtorFn = Fn;
1039349cc55cSDimitry Andric   }
1040349cc55cSDimitry Andric 
1041349cc55cSDimitry Andric   static void
1042349cc55cSDimitry Andric   RegisterObjectTargetStreamer(Target &T,
1043349cc55cSDimitry Andric                                Target::ObjectTargetStreamerCtorTy Fn) {
1044349cc55cSDimitry Andric     T.ObjectTargetStreamerCtorFn = Fn;
1045349cc55cSDimitry Andric   }
1046349cc55cSDimitry Andric 
1047349cc55cSDimitry Andric   /// RegisterMCRelocationInfo - Register an MCRelocationInfo
1048349cc55cSDimitry Andric   /// implementation for the given target.
1049349cc55cSDimitry Andric   ///
1050349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
1051349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
1052349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
1053349cc55cSDimitry Andric   ///
1054349cc55cSDimitry Andric   /// @param T - The target being registered.
1055349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCRelocationInfo for the target.
1056349cc55cSDimitry Andric   static void RegisterMCRelocationInfo(Target &T,
1057349cc55cSDimitry Andric                                        Target::MCRelocationInfoCtorTy Fn) {
1058349cc55cSDimitry Andric     T.MCRelocationInfoCtorFn = Fn;
1059349cc55cSDimitry Andric   }
1060349cc55cSDimitry Andric 
1061349cc55cSDimitry Andric   /// RegisterMCSymbolizer - Register an MCSymbolizer
1062349cc55cSDimitry Andric   /// implementation for the given target.
1063349cc55cSDimitry Andric   ///
1064349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
1065349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
1066349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
1067349cc55cSDimitry Andric   ///
1068349cc55cSDimitry Andric   /// @param T - The target being registered.
1069349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCSymbolizer for the target.
1070349cc55cSDimitry Andric   static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) {
1071349cc55cSDimitry Andric     T.MCSymbolizerCtorFn = Fn;
1072349cc55cSDimitry Andric   }
1073349cc55cSDimitry Andric 
1074349cc55cSDimitry Andric   /// RegisterCustomBehaviour - Register a CustomBehaviour
1075349cc55cSDimitry Andric   /// implementation for the given target.
1076349cc55cSDimitry Andric   ///
1077349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
1078349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
1079349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
1080349cc55cSDimitry Andric   ///
1081349cc55cSDimitry Andric   /// @param T - The target being registered.
1082349cc55cSDimitry Andric   /// @param Fn - A function to construct a CustomBehaviour for the target.
1083349cc55cSDimitry Andric   static void RegisterCustomBehaviour(Target &T,
1084349cc55cSDimitry Andric                                       Target::CustomBehaviourCtorTy Fn) {
1085349cc55cSDimitry Andric     T.CustomBehaviourCtorFn = Fn;
1086349cc55cSDimitry Andric   }
1087349cc55cSDimitry Andric 
1088349cc55cSDimitry Andric   /// RegisterInstrPostProcess - Register an InstrPostProcess
1089349cc55cSDimitry Andric   /// implementation for the given target.
1090349cc55cSDimitry Andric   ///
1091349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
1092349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
1093349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
1094349cc55cSDimitry Andric   ///
1095349cc55cSDimitry Andric   /// @param T - The target being registered.
1096349cc55cSDimitry Andric   /// @param Fn - A function to construct an InstrPostProcess for the target.
1097349cc55cSDimitry Andric   static void RegisterInstrPostProcess(Target &T,
1098349cc55cSDimitry Andric                                        Target::InstrPostProcessCtorTy Fn) {
1099349cc55cSDimitry Andric     T.InstrPostProcessCtorFn = Fn;
1100349cc55cSDimitry Andric   }
1101349cc55cSDimitry Andric 
1102*bdd1243dSDimitry Andric   /// RegisterInstrumentManager - Register an InstrumentManager
1103*bdd1243dSDimitry Andric   /// implementation for the given target.
1104*bdd1243dSDimitry Andric   ///
1105*bdd1243dSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
1106*bdd1243dSDimitry Andric   /// while another thread is attempting to access the registry. Typically
1107*bdd1243dSDimitry Andric   /// this is done by initializing all targets at program startup.
1108*bdd1243dSDimitry Andric   ///
1109*bdd1243dSDimitry Andric   /// @param T - The target being registered.
1110*bdd1243dSDimitry Andric   /// @param Fn - A function to construct an InstrumentManager for the
1111*bdd1243dSDimitry Andric   /// target.
1112*bdd1243dSDimitry Andric   static void RegisterInstrumentManager(Target &T,
1113*bdd1243dSDimitry Andric                                         Target::InstrumentManagerCtorTy Fn) {
1114*bdd1243dSDimitry Andric     T.InstrumentManagerCtorFn = Fn;
1115*bdd1243dSDimitry Andric   }
1116*bdd1243dSDimitry Andric 
1117349cc55cSDimitry Andric   /// @}
1118349cc55cSDimitry Andric };
1119349cc55cSDimitry Andric 
1120349cc55cSDimitry Andric //===--------------------------------------------------------------------===//
1121349cc55cSDimitry Andric 
1122349cc55cSDimitry Andric /// RegisterTarget - Helper template for registering a target, for use in the
1123349cc55cSDimitry Andric /// target's initialization function. Usage:
1124349cc55cSDimitry Andric ///
1125349cc55cSDimitry Andric ///
1126349cc55cSDimitry Andric /// Target &getTheFooTarget() { // The global target instance.
1127349cc55cSDimitry Andric ///   static Target TheFooTarget;
1128349cc55cSDimitry Andric ///   return TheFooTarget;
1129349cc55cSDimitry Andric /// }
1130349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTargetInfo() {
1131349cc55cSDimitry Andric ///   RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo
1132349cc55cSDimitry Andric ///   description", "Foo" /* Backend Name */);
1133349cc55cSDimitry Andric /// }
1134349cc55cSDimitry Andric template <Triple::ArchType TargetArchType = Triple::UnknownArch,
1135349cc55cSDimitry Andric           bool HasJIT = false>
1136349cc55cSDimitry Andric struct RegisterTarget {
1137349cc55cSDimitry Andric   RegisterTarget(Target &T, const char *Name, const char *Desc,
1138349cc55cSDimitry Andric                  const char *BackendName) {
1139349cc55cSDimitry Andric     TargetRegistry::RegisterTarget(T, Name, Desc, BackendName, &getArchMatch,
1140349cc55cSDimitry Andric                                    HasJIT);
1141349cc55cSDimitry Andric   }
1142349cc55cSDimitry Andric 
1143349cc55cSDimitry Andric   static bool getArchMatch(Triple::ArchType Arch) {
1144349cc55cSDimitry Andric     return Arch == TargetArchType;
1145349cc55cSDimitry Andric   }
1146349cc55cSDimitry Andric };
1147349cc55cSDimitry Andric 
1148349cc55cSDimitry Andric /// RegisterMCAsmInfo - Helper template for registering a target assembly info
1149349cc55cSDimitry Andric /// implementation.  This invokes the static "Create" method on the class to
1150349cc55cSDimitry Andric /// actually do the construction.  Usage:
1151349cc55cSDimitry Andric ///
1152349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1153349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1154349cc55cSDimitry Andric ///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
1155349cc55cSDimitry Andric /// }
1156349cc55cSDimitry Andric template <class MCAsmInfoImpl> struct RegisterMCAsmInfo {
1157349cc55cSDimitry Andric   RegisterMCAsmInfo(Target &T) {
1158349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
1159349cc55cSDimitry Andric   }
1160349cc55cSDimitry Andric 
1161349cc55cSDimitry Andric private:
1162349cc55cSDimitry Andric   static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, const Triple &TT,
1163349cc55cSDimitry Andric                               const MCTargetOptions &Options) {
1164349cc55cSDimitry Andric     return new MCAsmInfoImpl(TT, Options);
1165349cc55cSDimitry Andric   }
1166349cc55cSDimitry Andric };
1167349cc55cSDimitry Andric 
1168349cc55cSDimitry Andric /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
1169349cc55cSDimitry Andric /// implementation.  This invokes the specified function to do the
1170349cc55cSDimitry Andric /// construction.  Usage:
1171349cc55cSDimitry Andric ///
1172349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1173349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1174349cc55cSDimitry Andric ///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
1175349cc55cSDimitry Andric /// }
1176349cc55cSDimitry Andric struct RegisterMCAsmInfoFn {
1177349cc55cSDimitry Andric   RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
1178349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmInfo(T, Fn);
1179349cc55cSDimitry Andric   }
1180349cc55cSDimitry Andric };
1181349cc55cSDimitry Andric 
1182349cc55cSDimitry Andric /// Helper template for registering a target object file info implementation.
1183349cc55cSDimitry Andric /// This invokes the static "Create" method on the class to actually do the
1184349cc55cSDimitry Andric /// construction.  Usage:
1185349cc55cSDimitry Andric ///
1186349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1187349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1188349cc55cSDimitry Andric ///   RegisterMCObjectFileInfo<FooMCObjectFileInfo> X(TheFooTarget);
1189349cc55cSDimitry Andric /// }
1190349cc55cSDimitry Andric template <class MCObjectFileInfoImpl> struct RegisterMCObjectFileInfo {
1191349cc55cSDimitry Andric   RegisterMCObjectFileInfo(Target &T) {
1192349cc55cSDimitry Andric     TargetRegistry::RegisterMCObjectFileInfo(T, &Allocator);
1193349cc55cSDimitry Andric   }
1194349cc55cSDimitry Andric 
1195349cc55cSDimitry Andric private:
1196349cc55cSDimitry Andric   static MCObjectFileInfo *Allocator(MCContext &Ctx, bool PIC,
1197349cc55cSDimitry Andric                                      bool LargeCodeModel = false) {
1198349cc55cSDimitry Andric     return new MCObjectFileInfoImpl(Ctx, PIC, LargeCodeModel);
1199349cc55cSDimitry Andric   }
1200349cc55cSDimitry Andric };
1201349cc55cSDimitry Andric 
1202349cc55cSDimitry Andric /// Helper template for registering a target object file info implementation.
1203349cc55cSDimitry Andric /// This invokes the specified function to do the construction.  Usage:
1204349cc55cSDimitry Andric ///
1205349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1206349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1207349cc55cSDimitry Andric ///   RegisterMCObjectFileInfoFn X(TheFooTarget, TheFunction);
1208349cc55cSDimitry Andric /// }
1209349cc55cSDimitry Andric struct RegisterMCObjectFileInfoFn {
1210349cc55cSDimitry Andric   RegisterMCObjectFileInfoFn(Target &T, Target::MCObjectFileInfoCtorFnTy Fn) {
1211349cc55cSDimitry Andric     TargetRegistry::RegisterMCObjectFileInfo(T, Fn);
1212349cc55cSDimitry Andric   }
1213349cc55cSDimitry Andric };
1214349cc55cSDimitry Andric 
1215349cc55cSDimitry Andric /// RegisterMCInstrInfo - Helper template for registering a target instruction
1216349cc55cSDimitry Andric /// info implementation.  This invokes the static "Create" method on the class
1217349cc55cSDimitry Andric /// to actually do the construction.  Usage:
1218349cc55cSDimitry Andric ///
1219349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1220349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1221349cc55cSDimitry Andric ///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
1222349cc55cSDimitry Andric /// }
1223349cc55cSDimitry Andric template <class MCInstrInfoImpl> struct RegisterMCInstrInfo {
1224349cc55cSDimitry Andric   RegisterMCInstrInfo(Target &T) {
1225349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
1226349cc55cSDimitry Andric   }
1227349cc55cSDimitry Andric 
1228349cc55cSDimitry Andric private:
1229349cc55cSDimitry Andric   static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); }
1230349cc55cSDimitry Andric };
1231349cc55cSDimitry Andric 
1232349cc55cSDimitry Andric /// RegisterMCInstrInfoFn - Helper template for registering a target
1233349cc55cSDimitry Andric /// instruction info implementation.  This invokes the specified function to
1234349cc55cSDimitry Andric /// do the construction.  Usage:
1235349cc55cSDimitry Andric ///
1236349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1237349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1238349cc55cSDimitry Andric ///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
1239349cc55cSDimitry Andric /// }
1240349cc55cSDimitry Andric struct RegisterMCInstrInfoFn {
1241349cc55cSDimitry Andric   RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
1242349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrInfo(T, Fn);
1243349cc55cSDimitry Andric   }
1244349cc55cSDimitry Andric };
1245349cc55cSDimitry Andric 
1246349cc55cSDimitry Andric /// RegisterMCInstrAnalysis - Helper template for registering a target
1247349cc55cSDimitry Andric /// instruction analyzer implementation.  This invokes the static "Create"
1248349cc55cSDimitry Andric /// method on the class to actually do the construction.  Usage:
1249349cc55cSDimitry Andric ///
1250349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1251349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1252349cc55cSDimitry Andric ///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
1253349cc55cSDimitry Andric /// }
1254349cc55cSDimitry Andric template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis {
1255349cc55cSDimitry Andric   RegisterMCInstrAnalysis(Target &T) {
1256349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
1257349cc55cSDimitry Andric   }
1258349cc55cSDimitry Andric 
1259349cc55cSDimitry Andric private:
1260349cc55cSDimitry Andric   static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
1261349cc55cSDimitry Andric     return new MCInstrAnalysisImpl(Info);
1262349cc55cSDimitry Andric   }
1263349cc55cSDimitry Andric };
1264349cc55cSDimitry Andric 
1265349cc55cSDimitry Andric /// RegisterMCInstrAnalysisFn - Helper template for registering a target
1266349cc55cSDimitry Andric /// instruction analyzer implementation.  This invokes the specified function
1267349cc55cSDimitry Andric /// to do the construction.  Usage:
1268349cc55cSDimitry Andric ///
1269349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1270349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1271349cc55cSDimitry Andric ///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
1272349cc55cSDimitry Andric /// }
1273349cc55cSDimitry Andric struct RegisterMCInstrAnalysisFn {
1274349cc55cSDimitry Andric   RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
1275349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
1276349cc55cSDimitry Andric   }
1277349cc55cSDimitry Andric };
1278349cc55cSDimitry Andric 
1279349cc55cSDimitry Andric /// RegisterMCRegInfo - Helper template for registering a target register info
1280349cc55cSDimitry Andric /// implementation.  This invokes the static "Create" method on the class to
1281349cc55cSDimitry Andric /// actually do the construction.  Usage:
1282349cc55cSDimitry Andric ///
1283349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1284349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1285349cc55cSDimitry Andric ///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
1286349cc55cSDimitry Andric /// }
1287349cc55cSDimitry Andric template <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
1288349cc55cSDimitry Andric   RegisterMCRegInfo(Target &T) {
1289349cc55cSDimitry Andric     TargetRegistry::RegisterMCRegInfo(T, &Allocator);
1290349cc55cSDimitry Andric   }
1291349cc55cSDimitry Andric 
1292349cc55cSDimitry Andric private:
1293349cc55cSDimitry Andric   static MCRegisterInfo *Allocator(const Triple & /*TT*/) {
1294349cc55cSDimitry Andric     return new MCRegisterInfoImpl();
1295349cc55cSDimitry Andric   }
1296349cc55cSDimitry Andric };
1297349cc55cSDimitry Andric 
1298349cc55cSDimitry Andric /// RegisterMCRegInfoFn - Helper template for registering a target register
1299349cc55cSDimitry Andric /// info implementation.  This invokes the specified function to do the
1300349cc55cSDimitry Andric /// construction.  Usage:
1301349cc55cSDimitry Andric ///
1302349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1303349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1304349cc55cSDimitry Andric ///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
1305349cc55cSDimitry Andric /// }
1306349cc55cSDimitry Andric struct RegisterMCRegInfoFn {
1307349cc55cSDimitry Andric   RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
1308349cc55cSDimitry Andric     TargetRegistry::RegisterMCRegInfo(T, Fn);
1309349cc55cSDimitry Andric   }
1310349cc55cSDimitry Andric };
1311349cc55cSDimitry Andric 
1312349cc55cSDimitry Andric /// RegisterMCSubtargetInfo - Helper template for registering a target
1313349cc55cSDimitry Andric /// subtarget info implementation.  This invokes the static "Create" method
1314349cc55cSDimitry Andric /// on the class to actually do the construction.  Usage:
1315349cc55cSDimitry Andric ///
1316349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1317349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1318349cc55cSDimitry Andric ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
1319349cc55cSDimitry Andric /// }
1320349cc55cSDimitry Andric template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo {
1321349cc55cSDimitry Andric   RegisterMCSubtargetInfo(Target &T) {
1322349cc55cSDimitry Andric     TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
1323349cc55cSDimitry Andric   }
1324349cc55cSDimitry Andric 
1325349cc55cSDimitry Andric private:
1326349cc55cSDimitry Andric   static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/,
1327349cc55cSDimitry Andric                                     StringRef /*FS*/) {
1328349cc55cSDimitry Andric     return new MCSubtargetInfoImpl();
1329349cc55cSDimitry Andric   }
1330349cc55cSDimitry Andric };
1331349cc55cSDimitry Andric 
1332349cc55cSDimitry Andric /// RegisterMCSubtargetInfoFn - Helper template for registering a target
1333349cc55cSDimitry Andric /// subtarget info implementation.  This invokes the specified function to
1334349cc55cSDimitry Andric /// do the construction.  Usage:
1335349cc55cSDimitry Andric ///
1336349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1337349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1338349cc55cSDimitry Andric ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
1339349cc55cSDimitry Andric /// }
1340349cc55cSDimitry Andric struct RegisterMCSubtargetInfoFn {
1341349cc55cSDimitry Andric   RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
1342349cc55cSDimitry Andric     TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
1343349cc55cSDimitry Andric   }
1344349cc55cSDimitry Andric };
1345349cc55cSDimitry Andric 
1346349cc55cSDimitry Andric /// RegisterTargetMachine - Helper template for registering a target machine
1347349cc55cSDimitry Andric /// implementation, for use in the target machine initialization
1348349cc55cSDimitry Andric /// function. Usage:
1349349cc55cSDimitry Andric ///
1350349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1351349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1352349cc55cSDimitry Andric ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
1353349cc55cSDimitry Andric /// }
1354349cc55cSDimitry Andric template <class TargetMachineImpl> struct RegisterTargetMachine {
1355349cc55cSDimitry Andric   RegisterTargetMachine(Target &T) {
1356349cc55cSDimitry Andric     TargetRegistry::RegisterTargetMachine(T, &Allocator);
1357349cc55cSDimitry Andric   }
1358349cc55cSDimitry Andric 
1359349cc55cSDimitry Andric private:
1360*bdd1243dSDimitry Andric   static TargetMachine *Allocator(const Target &T, const Triple &TT,
1361*bdd1243dSDimitry Andric                                   StringRef CPU, StringRef FS,
1362*bdd1243dSDimitry Andric                                   const TargetOptions &Options,
1363*bdd1243dSDimitry Andric                                   std::optional<Reloc::Model> RM,
1364*bdd1243dSDimitry Andric                                   std::optional<CodeModel::Model> CM,
1365*bdd1243dSDimitry Andric                                   CodeGenOpt::Level OL, bool JIT) {
1366349cc55cSDimitry Andric     return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT);
1367349cc55cSDimitry Andric   }
1368349cc55cSDimitry Andric };
1369349cc55cSDimitry Andric 
1370349cc55cSDimitry Andric /// RegisterMCAsmBackend - Helper template for registering a target specific
1371349cc55cSDimitry Andric /// assembler backend. Usage:
1372349cc55cSDimitry Andric ///
1373349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCAsmBackend() {
1374349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1375349cc55cSDimitry Andric ///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
1376349cc55cSDimitry Andric /// }
1377349cc55cSDimitry Andric template <class MCAsmBackendImpl> struct RegisterMCAsmBackend {
1378349cc55cSDimitry Andric   RegisterMCAsmBackend(Target &T) {
1379349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
1380349cc55cSDimitry Andric   }
1381349cc55cSDimitry Andric 
1382349cc55cSDimitry Andric private:
1383349cc55cSDimitry Andric   static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI,
1384349cc55cSDimitry Andric                                  const MCRegisterInfo &MRI,
1385349cc55cSDimitry Andric                                  const MCTargetOptions &Options) {
1386349cc55cSDimitry Andric     return new MCAsmBackendImpl(T, STI, MRI);
1387349cc55cSDimitry Andric   }
1388349cc55cSDimitry Andric };
1389349cc55cSDimitry Andric 
1390349cc55cSDimitry Andric /// RegisterMCAsmParser - Helper template for registering a target specific
1391349cc55cSDimitry Andric /// assembly parser, for use in the target machine initialization
1392349cc55cSDimitry Andric /// function. Usage:
1393349cc55cSDimitry Andric ///
1394349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCAsmParser() {
1395349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1396349cc55cSDimitry Andric ///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
1397349cc55cSDimitry Andric /// }
1398349cc55cSDimitry Andric template <class MCAsmParserImpl> struct RegisterMCAsmParser {
1399349cc55cSDimitry Andric   RegisterMCAsmParser(Target &T) {
1400349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmParser(T, &Allocator);
1401349cc55cSDimitry Andric   }
1402349cc55cSDimitry Andric 
1403349cc55cSDimitry Andric private:
1404349cc55cSDimitry Andric   static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI,
1405349cc55cSDimitry Andric                                       MCAsmParser &P, const MCInstrInfo &MII,
1406349cc55cSDimitry Andric                                       const MCTargetOptions &Options) {
1407349cc55cSDimitry Andric     return new MCAsmParserImpl(STI, P, MII, Options);
1408349cc55cSDimitry Andric   }
1409349cc55cSDimitry Andric };
1410349cc55cSDimitry Andric 
1411349cc55cSDimitry Andric /// RegisterAsmPrinter - Helper template for registering a target specific
1412349cc55cSDimitry Andric /// assembly printer, for use in the target machine initialization
1413349cc55cSDimitry Andric /// function. Usage:
1414349cc55cSDimitry Andric ///
1415349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooAsmPrinter() {
1416349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1417349cc55cSDimitry Andric ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
1418349cc55cSDimitry Andric /// }
1419349cc55cSDimitry Andric template <class AsmPrinterImpl> struct RegisterAsmPrinter {
1420349cc55cSDimitry Andric   RegisterAsmPrinter(Target &T) {
1421349cc55cSDimitry Andric     TargetRegistry::RegisterAsmPrinter(T, &Allocator);
1422349cc55cSDimitry Andric   }
1423349cc55cSDimitry Andric 
1424349cc55cSDimitry Andric private:
1425349cc55cSDimitry Andric   static AsmPrinter *Allocator(TargetMachine &TM,
1426349cc55cSDimitry Andric                                std::unique_ptr<MCStreamer> &&Streamer) {
1427349cc55cSDimitry Andric     return new AsmPrinterImpl(TM, std::move(Streamer));
1428349cc55cSDimitry Andric   }
1429349cc55cSDimitry Andric };
1430349cc55cSDimitry Andric 
1431349cc55cSDimitry Andric /// RegisterMCCodeEmitter - Helper template for registering a target specific
1432349cc55cSDimitry Andric /// machine code emitter, for use in the target initialization
1433349cc55cSDimitry Andric /// function. Usage:
1434349cc55cSDimitry Andric ///
1435349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
1436349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1437349cc55cSDimitry Andric ///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
1438349cc55cSDimitry Andric /// }
1439349cc55cSDimitry Andric template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter {
1440349cc55cSDimitry Andric   RegisterMCCodeEmitter(Target &T) {
1441349cc55cSDimitry Andric     TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
1442349cc55cSDimitry Andric   }
1443349cc55cSDimitry Andric 
1444349cc55cSDimitry Andric private:
1445349cc55cSDimitry Andric   static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
1446349cc55cSDimitry Andric                                   MCContext & /*Ctx*/) {
1447349cc55cSDimitry Andric     return new MCCodeEmitterImpl();
1448349cc55cSDimitry Andric   }
1449349cc55cSDimitry Andric };
1450349cc55cSDimitry Andric 
1451349cc55cSDimitry Andric } // end namespace llvm
1452349cc55cSDimitry Andric 
1453349cc55cSDimitry Andric #endif // LLVM_MC_TARGETREGISTRY_H
1454