xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/MC/TargetRegistry.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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/iterator_range.h"
24349cc55cSDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
25349cc55cSDimitry Andric #include "llvm/Support/CodeGen.h"
26*0fca6ea1SDimitry Andric #include "llvm/Support/Compiler.h"
27349cc55cSDimitry Andric #include "llvm/Support/ErrorHandling.h"
28349cc55cSDimitry Andric #include "llvm/Support/FormattedStream.h"
2906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
30349cc55cSDimitry Andric #include <cassert>
31349cc55cSDimitry Andric #include <cstddef>
32349cc55cSDimitry Andric #include <iterator>
33349cc55cSDimitry Andric #include <memory>
34bdd1243dSDimitry Andric #include <optional>
35349cc55cSDimitry Andric #include <string>
36349cc55cSDimitry Andric 
37349cc55cSDimitry Andric namespace llvm {
38349cc55cSDimitry Andric 
39349cc55cSDimitry Andric class AsmPrinter;
40349cc55cSDimitry Andric class MCAsmBackend;
41349cc55cSDimitry Andric class MCAsmInfo;
42349cc55cSDimitry Andric class MCAsmParser;
43349cc55cSDimitry Andric class MCCodeEmitter;
44349cc55cSDimitry Andric class MCContext;
45349cc55cSDimitry Andric class MCDisassembler;
46349cc55cSDimitry Andric class MCInstPrinter;
47349cc55cSDimitry Andric class MCInstrAnalysis;
48349cc55cSDimitry Andric class MCInstrInfo;
49349cc55cSDimitry Andric class MCObjectWriter;
50349cc55cSDimitry Andric class MCRegisterInfo;
51349cc55cSDimitry Andric class MCRelocationInfo;
52349cc55cSDimitry Andric class MCStreamer;
53349cc55cSDimitry Andric class MCSubtargetInfo;
54349cc55cSDimitry Andric class MCSymbolizer;
55349cc55cSDimitry Andric class MCTargetAsmParser;
56349cc55cSDimitry Andric class MCTargetOptions;
57349cc55cSDimitry Andric class MCTargetStreamer;
58349cc55cSDimitry Andric class raw_ostream;
59349cc55cSDimitry Andric class TargetMachine;
60349cc55cSDimitry Andric class TargetOptions;
61349cc55cSDimitry Andric namespace mca {
62349cc55cSDimitry Andric class CustomBehaviour;
63349cc55cSDimitry Andric class InstrPostProcess;
64bdd1243dSDimitry Andric class InstrumentManager;
6581ad6265SDimitry Andric struct SourceMgr;
66349cc55cSDimitry Andric } // namespace mca
67349cc55cSDimitry Andric 
68349cc55cSDimitry Andric MCStreamer *createNullStreamer(MCContext &Ctx);
69349cc55cSDimitry Andric // Takes ownership of \p TAB and \p CE.
70349cc55cSDimitry Andric 
71349cc55cSDimitry Andric /// Create a machine code streamer which will print out assembly for the native
72349cc55cSDimitry Andric /// target, suitable for compiling with a native assembler.
73349cc55cSDimitry Andric ///
74349cc55cSDimitry Andric /// \param InstPrint - If given, the instruction printer to use. If not given
75349cc55cSDimitry Andric /// the MCInst representation will be printed.  This method takes ownership of
76349cc55cSDimitry Andric /// InstPrint.
77349cc55cSDimitry Andric ///
78349cc55cSDimitry Andric /// \param CE - If given, a code emitter to use to show the instruction
79349cc55cSDimitry Andric /// encoding inline with the assembly. This method takes ownership of \p CE.
80349cc55cSDimitry Andric ///
81349cc55cSDimitry Andric /// \param TAB - If given, a target asm backend to use to show the fixup
82349cc55cSDimitry Andric /// information in conjunction with encoding information. This method takes
83349cc55cSDimitry Andric /// ownership of \p TAB.
84349cc55cSDimitry Andric ///
85349cc55cSDimitry Andric /// \param ShowInst - Whether to show the MCInst representation inline with
86349cc55cSDimitry Andric /// the assembly.
87349cc55cSDimitry Andric MCStreamer *
88349cc55cSDimitry Andric createAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS,
89349cc55cSDimitry Andric                   MCInstPrinter *InstPrint, std::unique_ptr<MCCodeEmitter> &&CE,
90*0fca6ea1SDimitry Andric                   std::unique_ptr<MCAsmBackend> &&TAB);
91349cc55cSDimitry Andric 
92349cc55cSDimitry Andric MCStreamer *createELFStreamer(MCContext &Ctx,
93349cc55cSDimitry Andric                               std::unique_ptr<MCAsmBackend> &&TAB,
94349cc55cSDimitry Andric                               std::unique_ptr<MCObjectWriter> &&OW,
95*0fca6ea1SDimitry Andric                               std::unique_ptr<MCCodeEmitter> &&CE);
965f757f3fSDimitry Andric MCStreamer *createGOFFStreamer(MCContext &Ctx,
975f757f3fSDimitry Andric                                std::unique_ptr<MCAsmBackend> &&TAB,
985f757f3fSDimitry Andric                                std::unique_ptr<MCObjectWriter> &&OW,
99*0fca6ea1SDimitry Andric                                std::unique_ptr<MCCodeEmitter> &&CE);
100349cc55cSDimitry Andric MCStreamer *createMachOStreamer(MCContext &Ctx,
101349cc55cSDimitry Andric                                 std::unique_ptr<MCAsmBackend> &&TAB,
102349cc55cSDimitry Andric                                 std::unique_ptr<MCObjectWriter> &&OW,
103349cc55cSDimitry Andric                                 std::unique_ptr<MCCodeEmitter> &&CE,
104*0fca6ea1SDimitry Andric                                 bool DWARFMustBeAtTheEnd,
105349cc55cSDimitry Andric                                 bool LabelSections = false);
106349cc55cSDimitry Andric MCStreamer *createWasmStreamer(MCContext &Ctx,
107349cc55cSDimitry Andric                                std::unique_ptr<MCAsmBackend> &&TAB,
108349cc55cSDimitry Andric                                std::unique_ptr<MCObjectWriter> &&OW,
109*0fca6ea1SDimitry Andric                                std::unique_ptr<MCCodeEmitter> &&CE);
11081ad6265SDimitry Andric MCStreamer *createSPIRVStreamer(MCContext &Ctx,
11181ad6265SDimitry Andric                                 std::unique_ptr<MCAsmBackend> &&TAB,
11281ad6265SDimitry Andric                                 std::unique_ptr<MCObjectWriter> &&OW,
113*0fca6ea1SDimitry Andric                                 std::unique_ptr<MCCodeEmitter> &&CE);
11481ad6265SDimitry Andric MCStreamer *createDXContainerStreamer(MCContext &Ctx,
11581ad6265SDimitry Andric                                       std::unique_ptr<MCAsmBackend> &&TAB,
11681ad6265SDimitry Andric                                       std::unique_ptr<MCObjectWriter> &&OW,
117*0fca6ea1SDimitry Andric                                       std::unique_ptr<MCCodeEmitter> &&CE);
118349cc55cSDimitry Andric 
119349cc55cSDimitry Andric MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
120349cc55cSDimitry Andric 
121349cc55cSDimitry Andric MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
122349cc55cSDimitry Andric                                  LLVMSymbolLookupCallback SymbolLookUp,
123349cc55cSDimitry Andric                                  void *DisInfo, MCContext *Ctx,
124349cc55cSDimitry Andric                                  std::unique_ptr<MCRelocationInfo> &&RelInfo);
125349cc55cSDimitry Andric 
126349cc55cSDimitry Andric mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI,
127349cc55cSDimitry Andric                                             const mca::SourceMgr &SrcMgr,
128349cc55cSDimitry Andric                                             const MCInstrInfo &MCII);
129349cc55cSDimitry Andric 
130349cc55cSDimitry Andric mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI,
131349cc55cSDimitry Andric                                               const MCInstrInfo &MCII);
132349cc55cSDimitry Andric 
133bdd1243dSDimitry Andric mca::InstrumentManager *createInstrumentManager(const MCSubtargetInfo &STI,
134bdd1243dSDimitry Andric                                                 const MCInstrInfo &MCII);
135bdd1243dSDimitry Andric 
136349cc55cSDimitry Andric /// Target - Wrapper for Target specific information.
137349cc55cSDimitry Andric ///
138349cc55cSDimitry Andric /// For registration purposes, this is a POD type so that targets can be
139349cc55cSDimitry Andric /// registered without the use of static constructors.
140349cc55cSDimitry Andric ///
141349cc55cSDimitry Andric /// Targets should implement a single global instance of this class (which
142349cc55cSDimitry Andric /// will be zero initialized), and pass that instance to the TargetRegistry as
143349cc55cSDimitry Andric /// part of their initialization.
144349cc55cSDimitry Andric class Target {
145349cc55cSDimitry Andric public:
146349cc55cSDimitry Andric   friend struct TargetRegistry;
147349cc55cSDimitry Andric 
148349cc55cSDimitry Andric   using ArchMatchFnTy = bool (*)(Triple::ArchType Arch);
149349cc55cSDimitry Andric 
150349cc55cSDimitry Andric   using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI,
151349cc55cSDimitry Andric                                            const Triple &TT,
152349cc55cSDimitry Andric                                            const MCTargetOptions &Options);
153349cc55cSDimitry Andric   using MCObjectFileInfoCtorFnTy = MCObjectFileInfo *(*)(MCContext &Ctx,
154349cc55cSDimitry Andric                                                          bool PIC,
155349cc55cSDimitry Andric                                                          bool LargeCodeModel);
156349cc55cSDimitry Andric   using MCInstrInfoCtorFnTy = MCInstrInfo *(*)();
157349cc55cSDimitry Andric   using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info);
158349cc55cSDimitry Andric   using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT);
159349cc55cSDimitry Andric   using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT,
160349cc55cSDimitry Andric                                                        StringRef CPU,
161349cc55cSDimitry Andric                                                        StringRef Features);
162349cc55cSDimitry Andric   using TargetMachineCtorTy = TargetMachine
163349cc55cSDimitry Andric       *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
164bdd1243dSDimitry Andric            const TargetOptions &Options, std::optional<Reloc::Model> RM,
1655f757f3fSDimitry Andric            std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT);
166349cc55cSDimitry Andric   // If it weren't for layering issues (this header is in llvm/Support, but
167349cc55cSDimitry Andric   // depends on MC?) this should take the Streamer by value rather than rvalue
168349cc55cSDimitry Andric   // reference.
169349cc55cSDimitry Andric   using AsmPrinterCtorTy = AsmPrinter *(*)(
170349cc55cSDimitry Andric       TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
171349cc55cSDimitry Andric   using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
172349cc55cSDimitry Andric                                                const MCSubtargetInfo &STI,
173349cc55cSDimitry Andric                                                const MCRegisterInfo &MRI,
174349cc55cSDimitry Andric                                                const MCTargetOptions &Options);
175349cc55cSDimitry Andric   using MCAsmParserCtorTy = MCTargetAsmParser *(*)(
176349cc55cSDimitry Andric       const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII,
177349cc55cSDimitry Andric       const MCTargetOptions &Options);
178349cc55cSDimitry Andric   using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T,
179349cc55cSDimitry Andric                                                    const MCSubtargetInfo &STI,
180349cc55cSDimitry Andric                                                    MCContext &Ctx);
181349cc55cSDimitry Andric   using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T,
182349cc55cSDimitry Andric                                                  unsigned SyntaxVariant,
183349cc55cSDimitry Andric                                                  const MCAsmInfo &MAI,
184349cc55cSDimitry Andric                                                  const MCInstrInfo &MII,
185349cc55cSDimitry Andric                                                  const MCRegisterInfo &MRI);
186349cc55cSDimitry Andric   using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II,
187349cc55cSDimitry Andric                                                  MCContext &Ctx);
188349cc55cSDimitry Andric   using ELFStreamerCtorTy =
189349cc55cSDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
190349cc55cSDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
191349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
192*0fca6ea1SDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter);
193349cc55cSDimitry Andric   using MachOStreamerCtorTy =
194349cc55cSDimitry Andric       MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
195349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
196*0fca6ea1SDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter);
197349cc55cSDimitry Andric   using COFFStreamerCtorTy =
198349cc55cSDimitry Andric       MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
199349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
200*0fca6ea1SDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter);
201349cc55cSDimitry Andric   using XCOFFStreamerCtorTy =
202349cc55cSDimitry Andric       MCStreamer *(*)(const Triple &T, MCContext &Ctx,
203349cc55cSDimitry Andric                       std::unique_ptr<MCAsmBackend> &&TAB,
204349cc55cSDimitry Andric                       std::unique_ptr<MCObjectWriter> &&OW,
205*0fca6ea1SDimitry Andric                       std::unique_ptr<MCCodeEmitter> &&Emitter);
206349cc55cSDimitry Andric 
207349cc55cSDimitry Andric   using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S);
208*0fca6ea1SDimitry Andric   using AsmTargetStreamerCtorTy =
209*0fca6ea1SDimitry Andric       MCTargetStreamer *(*)(MCStreamer &S, formatted_raw_ostream &OS,
210*0fca6ea1SDimitry Andric                             MCInstPrinter *InstPrint);
211349cc55cSDimitry Andric   using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
212349cc55cSDimitry Andric       MCStreamer &S, const MCSubtargetInfo &STI);
213349cc55cSDimitry Andric   using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
214349cc55cSDimitry Andric                                                        MCContext &Ctx);
215349cc55cSDimitry Andric   using MCSymbolizerCtorTy = MCSymbolizer *(*)(
216349cc55cSDimitry Andric       const Triple &TT, LLVMOpInfoCallback GetOpInfo,
217349cc55cSDimitry Andric       LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
218349cc55cSDimitry Andric       std::unique_ptr<MCRelocationInfo> &&RelInfo);
219349cc55cSDimitry Andric 
220349cc55cSDimitry Andric   using CustomBehaviourCtorTy =
221349cc55cSDimitry Andric       mca::CustomBehaviour *(*)(const MCSubtargetInfo &STI,
222349cc55cSDimitry Andric                                 const mca::SourceMgr &SrcMgr,
223349cc55cSDimitry Andric                                 const MCInstrInfo &MCII);
224349cc55cSDimitry Andric 
225349cc55cSDimitry Andric   using InstrPostProcessCtorTy =
226349cc55cSDimitry Andric       mca::InstrPostProcess *(*)(const MCSubtargetInfo &STI,
227349cc55cSDimitry Andric                                  const MCInstrInfo &MCII);
228349cc55cSDimitry Andric 
229bdd1243dSDimitry Andric   using InstrumentManagerCtorTy =
230bdd1243dSDimitry Andric       mca::InstrumentManager *(*)(const MCSubtargetInfo &STI,
231bdd1243dSDimitry Andric                                   const MCInstrInfo &MCII);
232bdd1243dSDimitry Andric 
233349cc55cSDimitry Andric private:
234349cc55cSDimitry Andric   /// Next - The next registered target in the linked list, maintained by the
235349cc55cSDimitry Andric   /// TargetRegistry.
236349cc55cSDimitry Andric   Target *Next;
237349cc55cSDimitry Andric 
238349cc55cSDimitry Andric   /// The target function for checking if an architecture is supported.
239349cc55cSDimitry Andric   ArchMatchFnTy ArchMatchFn;
240349cc55cSDimitry Andric 
241349cc55cSDimitry Andric   /// Name - The target name.
242349cc55cSDimitry Andric   const char *Name;
243349cc55cSDimitry Andric 
244349cc55cSDimitry Andric   /// ShortDesc - A short description of the target.
245349cc55cSDimitry Andric   const char *ShortDesc;
246349cc55cSDimitry Andric 
247349cc55cSDimitry Andric   /// BackendName - The name of the backend implementation. This must match the
248349cc55cSDimitry Andric   /// name of the 'def X : Target ...' in TableGen.
249349cc55cSDimitry Andric   const char *BackendName;
250349cc55cSDimitry Andric 
251349cc55cSDimitry Andric   /// HasJIT - Whether this target supports the JIT.
252349cc55cSDimitry Andric   bool HasJIT;
253349cc55cSDimitry Andric 
254349cc55cSDimitry Andric   /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
255349cc55cSDimitry Andric   /// registered.
256349cc55cSDimitry Andric   MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
257349cc55cSDimitry Andric 
258349cc55cSDimitry Andric   /// Constructor function for this target's MCObjectFileInfo, if registered.
259349cc55cSDimitry Andric   MCObjectFileInfoCtorFnTy MCObjectFileInfoCtorFn;
260349cc55cSDimitry Andric 
261349cc55cSDimitry Andric   /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
262349cc55cSDimitry Andric   /// if registered.
263349cc55cSDimitry Andric   MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
264349cc55cSDimitry Andric 
265349cc55cSDimitry Andric   /// MCInstrAnalysisCtorFn - Constructor function for this target's
266349cc55cSDimitry Andric   /// MCInstrAnalysis, if registered.
267349cc55cSDimitry Andric   MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
268349cc55cSDimitry Andric 
269349cc55cSDimitry Andric   /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
270349cc55cSDimitry Andric   /// if registered.
271349cc55cSDimitry Andric   MCRegInfoCtorFnTy MCRegInfoCtorFn;
272349cc55cSDimitry Andric 
273349cc55cSDimitry Andric   /// MCSubtargetInfoCtorFn - Constructor function for this target's
274349cc55cSDimitry Andric   /// MCSubtargetInfo, if registered.
275349cc55cSDimitry Andric   MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
276349cc55cSDimitry Andric 
277349cc55cSDimitry Andric   /// TargetMachineCtorFn - Construction function for this target's
278349cc55cSDimitry Andric   /// TargetMachine, if registered.
279349cc55cSDimitry Andric   TargetMachineCtorTy TargetMachineCtorFn;
280349cc55cSDimitry Andric 
281349cc55cSDimitry Andric   /// MCAsmBackendCtorFn - Construction function for this target's
282349cc55cSDimitry Andric   /// MCAsmBackend, if registered.
283349cc55cSDimitry Andric   MCAsmBackendCtorTy MCAsmBackendCtorFn;
284349cc55cSDimitry Andric 
285349cc55cSDimitry Andric   /// MCAsmParserCtorFn - Construction function for this target's
286349cc55cSDimitry Andric   /// MCTargetAsmParser, if registered.
287349cc55cSDimitry Andric   MCAsmParserCtorTy MCAsmParserCtorFn;
288349cc55cSDimitry Andric 
289349cc55cSDimitry Andric   /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
290349cc55cSDimitry Andric   /// if registered.
291349cc55cSDimitry Andric   AsmPrinterCtorTy AsmPrinterCtorFn;
292349cc55cSDimitry Andric 
293349cc55cSDimitry Andric   /// MCDisassemblerCtorFn - Construction function for this target's
294349cc55cSDimitry Andric   /// MCDisassembler, if registered.
295349cc55cSDimitry Andric   MCDisassemblerCtorTy MCDisassemblerCtorFn;
296349cc55cSDimitry Andric 
297349cc55cSDimitry Andric   /// MCInstPrinterCtorFn - Construction function for this target's
298349cc55cSDimitry Andric   /// MCInstPrinter, if registered.
299349cc55cSDimitry Andric   MCInstPrinterCtorTy MCInstPrinterCtorFn;
300349cc55cSDimitry Andric 
301349cc55cSDimitry Andric   /// MCCodeEmitterCtorFn - Construction function for this target's
302349cc55cSDimitry Andric   /// CodeEmitter, if registered.
303349cc55cSDimitry Andric   MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
304349cc55cSDimitry Andric 
305349cc55cSDimitry Andric   // Construction functions for the various object formats, if registered.
306349cc55cSDimitry Andric   COFFStreamerCtorTy COFFStreamerCtorFn = nullptr;
307349cc55cSDimitry Andric   MachOStreamerCtorTy MachOStreamerCtorFn = nullptr;
308349cc55cSDimitry Andric   ELFStreamerCtorTy ELFStreamerCtorFn = nullptr;
309349cc55cSDimitry Andric   XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr;
310349cc55cSDimitry Andric 
311349cc55cSDimitry Andric   /// Construction function for this target's null TargetStreamer, if
312349cc55cSDimitry Andric   /// registered (default = nullptr).
313349cc55cSDimitry Andric   NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr;
314349cc55cSDimitry Andric 
315349cc55cSDimitry Andric   /// Construction function for this target's asm TargetStreamer, if
316349cc55cSDimitry Andric   /// registered (default = nullptr).
317349cc55cSDimitry Andric   AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
318349cc55cSDimitry Andric 
319349cc55cSDimitry Andric   /// Construction function for this target's obj TargetStreamer, if
320349cc55cSDimitry Andric   /// registered (default = nullptr).
321349cc55cSDimitry Andric   ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
322349cc55cSDimitry Andric 
323349cc55cSDimitry Andric   /// MCRelocationInfoCtorFn - Construction function for this target's
324349cc55cSDimitry Andric   /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
325349cc55cSDimitry Andric   MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr;
326349cc55cSDimitry Andric 
327349cc55cSDimitry Andric   /// MCSymbolizerCtorFn - Construction function for this target's
328349cc55cSDimitry Andric   /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
329349cc55cSDimitry Andric   MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr;
330349cc55cSDimitry Andric 
331349cc55cSDimitry Andric   /// CustomBehaviourCtorFn - Construction function for this target's
332349cc55cSDimitry Andric   /// CustomBehaviour, if registered (default = nullptr).
333349cc55cSDimitry Andric   CustomBehaviourCtorTy CustomBehaviourCtorFn = nullptr;
334349cc55cSDimitry Andric 
335349cc55cSDimitry Andric   /// InstrPostProcessCtorFn - Construction function for this target's
336349cc55cSDimitry Andric   /// InstrPostProcess, if registered (default = nullptr).
337349cc55cSDimitry Andric   InstrPostProcessCtorTy InstrPostProcessCtorFn = nullptr;
338349cc55cSDimitry Andric 
339bdd1243dSDimitry Andric   /// InstrumentManagerCtorFn - Construction function for this target's
340bdd1243dSDimitry Andric   /// InstrumentManager, if registered (default = nullptr).
341bdd1243dSDimitry Andric   InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr;
342bdd1243dSDimitry Andric 
343349cc55cSDimitry Andric public:
344349cc55cSDimitry Andric   Target() = default;
345349cc55cSDimitry Andric 
346349cc55cSDimitry Andric   /// @name Target Information
347349cc55cSDimitry Andric   /// @{
348349cc55cSDimitry Andric 
349349cc55cSDimitry Andric   // getNext - Return the next registered target.
350349cc55cSDimitry Andric   const Target *getNext() const { return Next; }
351349cc55cSDimitry Andric 
352349cc55cSDimitry Andric   /// getName - Get the target name.
353349cc55cSDimitry Andric   const char *getName() const { return Name; }
354349cc55cSDimitry Andric 
355349cc55cSDimitry Andric   /// getShortDescription - Get a short description of the target.
356349cc55cSDimitry Andric   const char *getShortDescription() const { return ShortDesc; }
357349cc55cSDimitry Andric 
358349cc55cSDimitry Andric   /// getBackendName - Get the backend name.
359349cc55cSDimitry Andric   const char *getBackendName() const { return BackendName; }
360349cc55cSDimitry Andric 
361349cc55cSDimitry Andric   /// @}
362349cc55cSDimitry Andric   /// @name Feature Predicates
363349cc55cSDimitry Andric   /// @{
364349cc55cSDimitry Andric 
365349cc55cSDimitry Andric   /// hasJIT - Check if this targets supports the just-in-time compilation.
366349cc55cSDimitry Andric   bool hasJIT() const { return HasJIT; }
367349cc55cSDimitry Andric 
368349cc55cSDimitry Andric   /// hasTargetMachine - Check if this target supports code generation.
369349cc55cSDimitry Andric   bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
370349cc55cSDimitry Andric 
371349cc55cSDimitry Andric   /// hasMCAsmBackend - Check if this target supports .o generation.
372349cc55cSDimitry Andric   bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
373349cc55cSDimitry Andric 
374349cc55cSDimitry Andric   /// hasMCAsmParser - Check if this target supports assembly parsing.
375349cc55cSDimitry Andric   bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; }
376349cc55cSDimitry Andric 
377349cc55cSDimitry Andric   /// @}
378349cc55cSDimitry Andric   /// @name Feature Constructors
379349cc55cSDimitry Andric   /// @{
380349cc55cSDimitry Andric 
381349cc55cSDimitry Andric   /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
382349cc55cSDimitry Andric   /// target triple.
383349cc55cSDimitry Andric   ///
384349cc55cSDimitry Andric   /// \param TheTriple This argument is used to determine the target machine
385349cc55cSDimitry Andric   /// feature set; it should always be provided. Generally this should be
386349cc55cSDimitry Andric   /// either the target triple from the module, or the target triple of the
387349cc55cSDimitry Andric   /// host if that does not exist.
388349cc55cSDimitry Andric   MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple,
389349cc55cSDimitry Andric                              const MCTargetOptions &Options) const {
390349cc55cSDimitry Andric     if (!MCAsmInfoCtorFn)
391349cc55cSDimitry Andric       return nullptr;
392349cc55cSDimitry Andric     return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options);
393349cc55cSDimitry Andric   }
394349cc55cSDimitry Andric 
395349cc55cSDimitry Andric   /// Create a MCObjectFileInfo implementation for the specified target
396349cc55cSDimitry Andric   /// triple.
397349cc55cSDimitry Andric   ///
398349cc55cSDimitry Andric   MCObjectFileInfo *createMCObjectFileInfo(MCContext &Ctx, bool PIC,
399349cc55cSDimitry Andric                                            bool LargeCodeModel = false) const {
400349cc55cSDimitry Andric     if (!MCObjectFileInfoCtorFn) {
401349cc55cSDimitry Andric       MCObjectFileInfo *MOFI = new MCObjectFileInfo();
402349cc55cSDimitry Andric       MOFI->initMCObjectFileInfo(Ctx, PIC, LargeCodeModel);
403349cc55cSDimitry Andric       return MOFI;
404349cc55cSDimitry Andric     }
405349cc55cSDimitry Andric     return MCObjectFileInfoCtorFn(Ctx, PIC, LargeCodeModel);
406349cc55cSDimitry Andric   }
407349cc55cSDimitry Andric 
408349cc55cSDimitry Andric   /// createMCInstrInfo - Create a MCInstrInfo implementation.
409349cc55cSDimitry Andric   ///
410349cc55cSDimitry Andric   MCInstrInfo *createMCInstrInfo() const {
411349cc55cSDimitry Andric     if (!MCInstrInfoCtorFn)
412349cc55cSDimitry Andric       return nullptr;
413349cc55cSDimitry Andric     return MCInstrInfoCtorFn();
414349cc55cSDimitry Andric   }
415349cc55cSDimitry Andric 
416349cc55cSDimitry Andric   /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
417349cc55cSDimitry Andric   ///
418349cc55cSDimitry Andric   MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
419349cc55cSDimitry Andric     if (!MCInstrAnalysisCtorFn)
420349cc55cSDimitry Andric       return nullptr;
421349cc55cSDimitry Andric     return MCInstrAnalysisCtorFn(Info);
422349cc55cSDimitry Andric   }
423349cc55cSDimitry Andric 
424349cc55cSDimitry Andric   /// createMCRegInfo - Create a MCRegisterInfo implementation.
425349cc55cSDimitry Andric   ///
426349cc55cSDimitry Andric   MCRegisterInfo *createMCRegInfo(StringRef TT) const {
427349cc55cSDimitry Andric     if (!MCRegInfoCtorFn)
428349cc55cSDimitry Andric       return nullptr;
429349cc55cSDimitry Andric     return MCRegInfoCtorFn(Triple(TT));
430349cc55cSDimitry Andric   }
431349cc55cSDimitry Andric 
432349cc55cSDimitry Andric   /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
433349cc55cSDimitry Andric   ///
434349cc55cSDimitry Andric   /// \param TheTriple This argument is used to determine the target machine
435349cc55cSDimitry Andric   /// feature set; it should always be provided. Generally this should be
436349cc55cSDimitry Andric   /// either the target triple from the module, or the target triple of the
437349cc55cSDimitry Andric   /// host if that does not exist.
438349cc55cSDimitry Andric   /// \param CPU This specifies the name of the target CPU.
439349cc55cSDimitry Andric   /// \param Features This specifies the string representation of the
440349cc55cSDimitry Andric   /// additional target features.
441349cc55cSDimitry Andric   MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU,
442349cc55cSDimitry Andric                                          StringRef Features) const {
443349cc55cSDimitry Andric     if (!MCSubtargetInfoCtorFn)
444349cc55cSDimitry Andric       return nullptr;
445349cc55cSDimitry Andric     return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features);
446349cc55cSDimitry Andric   }
447349cc55cSDimitry Andric 
448349cc55cSDimitry Andric   /// createTargetMachine - Create a target specific machine implementation
449349cc55cSDimitry Andric   /// for the specified \p Triple.
450349cc55cSDimitry Andric   ///
451349cc55cSDimitry Andric   /// \param TT This argument is used to determine the target machine
452349cc55cSDimitry Andric   /// feature set; it should always be provided. Generally this should be
453349cc55cSDimitry Andric   /// either the target triple from the module, or the target triple of the
454349cc55cSDimitry Andric   /// host if that does not exist.
455bdd1243dSDimitry Andric   TargetMachine *createTargetMachine(
456bdd1243dSDimitry Andric       StringRef TT, StringRef CPU, StringRef Features,
457bdd1243dSDimitry Andric       const TargetOptions &Options, std::optional<Reloc::Model> RM,
458bdd1243dSDimitry Andric       std::optional<CodeModel::Model> CM = std::nullopt,
4595f757f3fSDimitry Andric       CodeGenOptLevel OL = CodeGenOptLevel::Default, bool JIT = false) const {
460349cc55cSDimitry Andric     if (!TargetMachineCtorFn)
461349cc55cSDimitry Andric       return nullptr;
462349cc55cSDimitry Andric     return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM,
463349cc55cSDimitry Andric                                CM, OL, JIT);
464349cc55cSDimitry Andric   }
465349cc55cSDimitry Andric 
466349cc55cSDimitry Andric   /// createMCAsmBackend - Create a target specific assembly parser.
467349cc55cSDimitry Andric   MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI,
468349cc55cSDimitry Andric                                    const MCRegisterInfo &MRI,
469349cc55cSDimitry Andric                                    const MCTargetOptions &Options) const {
470349cc55cSDimitry Andric     if (!MCAsmBackendCtorFn)
471349cc55cSDimitry Andric       return nullptr;
472349cc55cSDimitry Andric     return MCAsmBackendCtorFn(*this, STI, MRI, Options);
473349cc55cSDimitry Andric   }
474349cc55cSDimitry Andric 
475349cc55cSDimitry Andric   /// createMCAsmParser - Create a target specific assembly parser.
476349cc55cSDimitry Andric   ///
477349cc55cSDimitry Andric   /// \param Parser The target independent parser implementation to use for
478349cc55cSDimitry Andric   /// parsing and lexing.
479349cc55cSDimitry Andric   MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI,
480349cc55cSDimitry Andric                                        MCAsmParser &Parser,
481349cc55cSDimitry Andric                                        const MCInstrInfo &MII,
482349cc55cSDimitry Andric                                        const MCTargetOptions &Options) const {
483349cc55cSDimitry Andric     if (!MCAsmParserCtorFn)
484349cc55cSDimitry Andric       return nullptr;
485349cc55cSDimitry Andric     return MCAsmParserCtorFn(STI, Parser, MII, Options);
486349cc55cSDimitry Andric   }
487349cc55cSDimitry Andric 
488349cc55cSDimitry Andric   /// createAsmPrinter - Create a target specific assembly printer pass.  This
489349cc55cSDimitry Andric   /// takes ownership of the MCStreamer object.
490349cc55cSDimitry Andric   AsmPrinter *createAsmPrinter(TargetMachine &TM,
491349cc55cSDimitry Andric                                std::unique_ptr<MCStreamer> &&Streamer) const {
492349cc55cSDimitry Andric     if (!AsmPrinterCtorFn)
493349cc55cSDimitry Andric       return nullptr;
494349cc55cSDimitry Andric     return AsmPrinterCtorFn(TM, std::move(Streamer));
495349cc55cSDimitry Andric   }
496349cc55cSDimitry Andric 
497349cc55cSDimitry Andric   MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
498349cc55cSDimitry Andric                                        MCContext &Ctx) const {
499349cc55cSDimitry Andric     if (!MCDisassemblerCtorFn)
500349cc55cSDimitry Andric       return nullptr;
501349cc55cSDimitry Andric     return MCDisassemblerCtorFn(*this, STI, Ctx);
502349cc55cSDimitry Andric   }
503349cc55cSDimitry Andric 
504349cc55cSDimitry Andric   MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
505349cc55cSDimitry Andric                                      const MCAsmInfo &MAI,
506349cc55cSDimitry Andric                                      const MCInstrInfo &MII,
507349cc55cSDimitry Andric                                      const MCRegisterInfo &MRI) const {
508349cc55cSDimitry Andric     if (!MCInstPrinterCtorFn)
509349cc55cSDimitry Andric       return nullptr;
510349cc55cSDimitry Andric     return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
511349cc55cSDimitry Andric   }
512349cc55cSDimitry Andric 
513349cc55cSDimitry Andric   /// createMCCodeEmitter - Create a target specific code emitter.
514349cc55cSDimitry Andric   MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
515349cc55cSDimitry Andric                                      MCContext &Ctx) const {
516349cc55cSDimitry Andric     if (!MCCodeEmitterCtorFn)
517349cc55cSDimitry Andric       return nullptr;
51881ad6265SDimitry Andric     return MCCodeEmitterCtorFn(II, Ctx);
519349cc55cSDimitry Andric   }
520349cc55cSDimitry Andric 
521349cc55cSDimitry Andric   /// Create a target specific MCStreamer.
522349cc55cSDimitry Andric   ///
523349cc55cSDimitry Andric   /// \param T The target triple.
524349cc55cSDimitry Andric   /// \param Ctx The target context.
525349cc55cSDimitry Andric   /// \param TAB The target assembler backend object. Takes ownership.
526349cc55cSDimitry Andric   /// \param OW The stream object.
527349cc55cSDimitry Andric   /// \param Emitter The target independent assembler object.Takes ownership.
528*0fca6ea1SDimitry Andric   MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
529*0fca6ea1SDimitry Andric                                      std::unique_ptr<MCAsmBackend> TAB,
530*0fca6ea1SDimitry Andric                                      std::unique_ptr<MCObjectWriter> OW,
531*0fca6ea1SDimitry Andric                                      std::unique_ptr<MCCodeEmitter> Emitter,
532*0fca6ea1SDimitry Andric                                      const MCSubtargetInfo &STI) const;
533*0fca6ea1SDimitry Andric   LLVM_DEPRECATED("Use the overload without the 3 trailing bool", "")
534349cc55cSDimitry Andric   MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
535349cc55cSDimitry Andric                                      std::unique_ptr<MCAsmBackend> &&TAB,
536349cc55cSDimitry Andric                                      std::unique_ptr<MCObjectWriter> &&OW,
537349cc55cSDimitry Andric                                      std::unique_ptr<MCCodeEmitter> &&Emitter,
538*0fca6ea1SDimitry Andric                                      const MCSubtargetInfo &STI, bool, bool,
539*0fca6ea1SDimitry Andric                                      bool) const;
540349cc55cSDimitry Andric 
541349cc55cSDimitry Andric   MCStreamer *createAsmStreamer(MCContext &Ctx,
542349cc55cSDimitry Andric                                 std::unique_ptr<formatted_raw_ostream> OS,
543*0fca6ea1SDimitry Andric                                 MCInstPrinter *IP,
544*0fca6ea1SDimitry Andric                                 std::unique_ptr<MCCodeEmitter> CE,
545*0fca6ea1SDimitry Andric                                 std::unique_ptr<MCAsmBackend> TAB) const;
546*0fca6ea1SDimitry Andric   LLVM_DEPRECATED("Use the overload without the 3 unused bool", "")
547*0fca6ea1SDimitry Andric   MCStreamer *
548*0fca6ea1SDimitry Andric   createAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS,
549349cc55cSDimitry Andric                     bool IsVerboseAsm, bool UseDwarfDirectory,
550*0fca6ea1SDimitry Andric                     MCInstPrinter *IP, std::unique_ptr<MCCodeEmitter> &&CE,
551*0fca6ea1SDimitry Andric                     std::unique_ptr<MCAsmBackend> &&TAB, bool ShowInst) const;
552349cc55cSDimitry Andric 
553349cc55cSDimitry Andric   MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
554349cc55cSDimitry Andric                                             formatted_raw_ostream &OS,
555*0fca6ea1SDimitry Andric                                             MCInstPrinter *InstPrint) const {
556349cc55cSDimitry Andric     if (AsmTargetStreamerCtorFn)
557*0fca6ea1SDimitry Andric       return AsmTargetStreamerCtorFn(S, OS, InstPrint);
558349cc55cSDimitry Andric     return nullptr;
559349cc55cSDimitry Andric   }
560349cc55cSDimitry Andric 
561349cc55cSDimitry Andric   MCStreamer *createNullStreamer(MCContext &Ctx) const {
562349cc55cSDimitry Andric     MCStreamer *S = llvm::createNullStreamer(Ctx);
563349cc55cSDimitry Andric     createNullTargetStreamer(*S);
564349cc55cSDimitry Andric     return S;
565349cc55cSDimitry Andric   }
566349cc55cSDimitry Andric 
567349cc55cSDimitry Andric   MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
568349cc55cSDimitry Andric     if (NullTargetStreamerCtorFn)
569349cc55cSDimitry Andric       return NullTargetStreamerCtorFn(S);
570349cc55cSDimitry Andric     return nullptr;
571349cc55cSDimitry Andric   }
572349cc55cSDimitry Andric 
573349cc55cSDimitry Andric   /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
574349cc55cSDimitry Andric   ///
575349cc55cSDimitry Andric   /// \param TT The target triple.
576349cc55cSDimitry Andric   /// \param Ctx The target context.
577349cc55cSDimitry Andric   MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
578349cc55cSDimitry Andric     MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
579349cc55cSDimitry Andric                                     ? MCRelocationInfoCtorFn
580349cc55cSDimitry Andric                                     : llvm::createMCRelocationInfo;
581349cc55cSDimitry Andric     return Fn(Triple(TT), Ctx);
582349cc55cSDimitry Andric   }
583349cc55cSDimitry Andric 
584349cc55cSDimitry Andric   /// createMCSymbolizer - Create a target specific MCSymbolizer.
585349cc55cSDimitry Andric   ///
586349cc55cSDimitry Andric   /// \param TT The target triple.
587349cc55cSDimitry Andric   /// \param GetOpInfo The function to get the symbolic information for
588349cc55cSDimitry Andric   /// operands.
589349cc55cSDimitry Andric   /// \param SymbolLookUp The function to lookup a symbol name.
590349cc55cSDimitry Andric   /// \param DisInfo The pointer to the block of symbolic information for above
591349cc55cSDimitry Andric   /// call
592349cc55cSDimitry Andric   /// back.
593349cc55cSDimitry Andric   /// \param Ctx The target context.
594349cc55cSDimitry Andric   /// \param RelInfo The relocation information for this target. Takes
595349cc55cSDimitry Andric   /// ownership.
596349cc55cSDimitry Andric   MCSymbolizer *
597349cc55cSDimitry Andric   createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
598349cc55cSDimitry Andric                      LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
599349cc55cSDimitry Andric                      MCContext *Ctx,
600349cc55cSDimitry Andric                      std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
601349cc55cSDimitry Andric     MCSymbolizerCtorTy Fn =
602349cc55cSDimitry Andric         MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
603349cc55cSDimitry Andric     return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx,
604349cc55cSDimitry Andric               std::move(RelInfo));
605349cc55cSDimitry Andric   }
606349cc55cSDimitry Andric 
607349cc55cSDimitry Andric   /// createCustomBehaviour - Create a target specific CustomBehaviour.
608349cc55cSDimitry Andric   /// This class is used by llvm-mca and requires backend functionality.
609349cc55cSDimitry Andric   mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI,
610349cc55cSDimitry Andric                                               const mca::SourceMgr &SrcMgr,
611349cc55cSDimitry Andric                                               const MCInstrInfo &MCII) const {
612349cc55cSDimitry Andric     if (CustomBehaviourCtorFn)
613349cc55cSDimitry Andric       return CustomBehaviourCtorFn(STI, SrcMgr, MCII);
614349cc55cSDimitry Andric     return nullptr;
615349cc55cSDimitry Andric   }
616349cc55cSDimitry Andric 
617349cc55cSDimitry Andric   /// createInstrPostProcess - Create a target specific InstrPostProcess.
618349cc55cSDimitry Andric   /// This class is used by llvm-mca and requires backend functionality.
619349cc55cSDimitry Andric   mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI,
620349cc55cSDimitry Andric                                                 const MCInstrInfo &MCII) const {
621349cc55cSDimitry Andric     if (InstrPostProcessCtorFn)
622349cc55cSDimitry Andric       return InstrPostProcessCtorFn(STI, MCII);
623349cc55cSDimitry Andric     return nullptr;
624349cc55cSDimitry Andric   }
625349cc55cSDimitry Andric 
626bdd1243dSDimitry Andric   /// createInstrumentManager - Create a target specific
627bdd1243dSDimitry Andric   /// InstrumentManager. This class is used by llvm-mca and requires
628bdd1243dSDimitry Andric   /// backend functionality.
629bdd1243dSDimitry Andric   mca::InstrumentManager *
630bdd1243dSDimitry Andric   createInstrumentManager(const MCSubtargetInfo &STI,
631bdd1243dSDimitry Andric                           const MCInstrInfo &MCII) const {
632bdd1243dSDimitry Andric     if (InstrumentManagerCtorFn)
633bdd1243dSDimitry Andric       return InstrumentManagerCtorFn(STI, MCII);
634bdd1243dSDimitry Andric     return nullptr;
635bdd1243dSDimitry Andric   }
636bdd1243dSDimitry Andric 
637349cc55cSDimitry Andric   /// @}
638349cc55cSDimitry Andric };
639349cc55cSDimitry Andric 
640349cc55cSDimitry Andric /// TargetRegistry - Generic interface to target specific features.
641349cc55cSDimitry Andric struct TargetRegistry {
642349cc55cSDimitry Andric   // FIXME: Make this a namespace, probably just move all the Register*
643349cc55cSDimitry Andric   // functions into Target (currently they all just set members on the Target
644349cc55cSDimitry Andric   // anyway, and Target friends this class so those functions can...
645349cc55cSDimitry Andric   // function).
646349cc55cSDimitry Andric   TargetRegistry() = delete;
647349cc55cSDimitry Andric 
648349cc55cSDimitry Andric   class iterator {
649349cc55cSDimitry Andric     friend struct TargetRegistry;
650349cc55cSDimitry Andric 
651349cc55cSDimitry Andric     const Target *Current = nullptr;
652349cc55cSDimitry Andric 
653349cc55cSDimitry Andric     explicit iterator(Target *T) : Current(T) {}
654349cc55cSDimitry Andric 
655349cc55cSDimitry Andric   public:
656349cc55cSDimitry Andric     using iterator_category = std::forward_iterator_tag;
657349cc55cSDimitry Andric     using value_type = Target;
658349cc55cSDimitry Andric     using difference_type = std::ptrdiff_t;
659349cc55cSDimitry Andric     using pointer = value_type *;
660349cc55cSDimitry Andric     using reference = value_type &;
661349cc55cSDimitry Andric 
662349cc55cSDimitry Andric     iterator() = default;
663349cc55cSDimitry Andric 
664349cc55cSDimitry Andric     bool operator==(const iterator &x) const { return Current == x.Current; }
665349cc55cSDimitry Andric     bool operator!=(const iterator &x) const { return !operator==(x); }
666349cc55cSDimitry Andric 
667349cc55cSDimitry Andric     // Iterator traversal: forward iteration only
668349cc55cSDimitry Andric     iterator &operator++() { // Preincrement
669349cc55cSDimitry Andric       assert(Current && "Cannot increment end iterator!");
670349cc55cSDimitry Andric       Current = Current->getNext();
671349cc55cSDimitry Andric       return *this;
672349cc55cSDimitry Andric     }
673349cc55cSDimitry Andric     iterator operator++(int) { // Postincrement
674349cc55cSDimitry Andric       iterator tmp = *this;
675349cc55cSDimitry Andric       ++*this;
676349cc55cSDimitry Andric       return tmp;
677349cc55cSDimitry Andric     }
678349cc55cSDimitry Andric 
679349cc55cSDimitry Andric     const Target &operator*() const {
680349cc55cSDimitry Andric       assert(Current && "Cannot dereference end iterator!");
681349cc55cSDimitry Andric       return *Current;
682349cc55cSDimitry Andric     }
683349cc55cSDimitry Andric 
684349cc55cSDimitry Andric     const Target *operator->() const { return &operator*(); }
685349cc55cSDimitry Andric   };
686349cc55cSDimitry Andric 
687349cc55cSDimitry Andric   /// printRegisteredTargetsForVersion - Print the registered targets
688349cc55cSDimitry Andric   /// appropriately for inclusion in a tool's version output.
689349cc55cSDimitry Andric   static void printRegisteredTargetsForVersion(raw_ostream &OS);
690349cc55cSDimitry Andric 
691349cc55cSDimitry Andric   /// @name Registry Access
692349cc55cSDimitry Andric   /// @{
693349cc55cSDimitry Andric 
694349cc55cSDimitry Andric   static iterator_range<iterator> targets();
695349cc55cSDimitry Andric 
696349cc55cSDimitry Andric   /// lookupTarget - Lookup a target based on a target triple.
697349cc55cSDimitry Andric   ///
698349cc55cSDimitry Andric   /// \param Triple - The triple to use for finding a target.
699349cc55cSDimitry Andric   /// \param Error - On failure, an error string describing why no target was
700349cc55cSDimitry Andric   /// found.
70106c3fb27SDimitry Andric   static const Target *lookupTarget(StringRef Triple, std::string &Error);
702349cc55cSDimitry Andric 
703349cc55cSDimitry Andric   /// lookupTarget - Lookup a target based on an architecture name
704349cc55cSDimitry Andric   /// and a target triple.  If the architecture name is non-empty,
705349cc55cSDimitry Andric   /// then the lookup is done by architecture.  Otherwise, the target
706349cc55cSDimitry Andric   /// triple is used.
707349cc55cSDimitry Andric   ///
708349cc55cSDimitry Andric   /// \param ArchName - The architecture to use for finding a target.
709349cc55cSDimitry Andric   /// \param TheTriple - The triple to use for finding a target.  The
710349cc55cSDimitry Andric   /// triple is updated with canonical architecture name if a lookup
711349cc55cSDimitry Andric   /// by architecture is done.
712349cc55cSDimitry Andric   /// \param Error - On failure, an error string describing why no target was
713349cc55cSDimitry Andric   /// found.
71406c3fb27SDimitry Andric   static const Target *lookupTarget(StringRef ArchName, Triple &TheTriple,
71506c3fb27SDimitry Andric                                     std::string &Error);
716349cc55cSDimitry Andric 
717349cc55cSDimitry Andric   /// @}
718349cc55cSDimitry Andric   /// @name Target Registration
719349cc55cSDimitry Andric   /// @{
720349cc55cSDimitry Andric 
721349cc55cSDimitry Andric   /// RegisterTarget - Register the given target. Attempts to register a
722349cc55cSDimitry Andric   /// target which has already been registered will be ignored.
723349cc55cSDimitry Andric   ///
724349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
725349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
726349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
727349cc55cSDimitry Andric   ///
728349cc55cSDimitry Andric   /// @param T - The target being registered.
729349cc55cSDimitry Andric   /// @param Name - The target name. This should be a static string.
730349cc55cSDimitry Andric   /// @param ShortDesc - A short target description. This should be a static
731349cc55cSDimitry Andric   /// string.
732349cc55cSDimitry Andric   /// @param BackendName - The name of the backend. This should be a static
733349cc55cSDimitry Andric   /// string that is the same for all targets that share a backend
734349cc55cSDimitry Andric   /// implementation and must match the name used in the 'def X : Target ...' in
735349cc55cSDimitry Andric   /// TableGen.
736349cc55cSDimitry Andric   /// @param ArchMatchFn - The arch match checking function for this target.
737349cc55cSDimitry Andric   /// @param HasJIT - Whether the target supports JIT code
738349cc55cSDimitry Andric   /// generation.
739349cc55cSDimitry Andric   static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc,
740349cc55cSDimitry Andric                              const char *BackendName,
741349cc55cSDimitry Andric                              Target::ArchMatchFnTy ArchMatchFn,
742349cc55cSDimitry Andric                              bool HasJIT = false);
743349cc55cSDimitry Andric 
744349cc55cSDimitry Andric   /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
745349cc55cSDimitry Andric   /// given target.
746349cc55cSDimitry Andric   ///
747349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
748349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
749349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
750349cc55cSDimitry Andric   ///
751349cc55cSDimitry Andric   /// @param T - The target being registered.
752349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCAsmInfo for the target.
753349cc55cSDimitry Andric   static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
754349cc55cSDimitry Andric     T.MCAsmInfoCtorFn = Fn;
755349cc55cSDimitry Andric   }
756349cc55cSDimitry Andric 
757349cc55cSDimitry Andric   /// Register a MCObjectFileInfo implementation for the given target.
758349cc55cSDimitry Andric   ///
759349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
760349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
761349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
762349cc55cSDimitry Andric   ///
763349cc55cSDimitry Andric   /// @param T - The target being registered.
764349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCObjectFileInfo for the target.
765349cc55cSDimitry Andric   static void RegisterMCObjectFileInfo(Target &T,
766349cc55cSDimitry Andric                                        Target::MCObjectFileInfoCtorFnTy Fn) {
767349cc55cSDimitry Andric     T.MCObjectFileInfoCtorFn = Fn;
768349cc55cSDimitry Andric   }
769349cc55cSDimitry Andric 
770349cc55cSDimitry Andric   /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
771349cc55cSDimitry Andric   /// given target.
772349cc55cSDimitry Andric   ///
773349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
774349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
775349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
776349cc55cSDimitry Andric   ///
777349cc55cSDimitry Andric   /// @param T - The target being registered.
778349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCInstrInfo for the target.
779349cc55cSDimitry Andric   static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
780349cc55cSDimitry Andric     T.MCInstrInfoCtorFn = Fn;
781349cc55cSDimitry Andric   }
782349cc55cSDimitry Andric 
783349cc55cSDimitry Andric   /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
784349cc55cSDimitry Andric   /// the given target.
785349cc55cSDimitry Andric   static void RegisterMCInstrAnalysis(Target &T,
786349cc55cSDimitry Andric                                       Target::MCInstrAnalysisCtorFnTy Fn) {
787349cc55cSDimitry Andric     T.MCInstrAnalysisCtorFn = Fn;
788349cc55cSDimitry Andric   }
789349cc55cSDimitry Andric 
790349cc55cSDimitry Andric   /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
791349cc55cSDimitry Andric   /// given target.
792349cc55cSDimitry Andric   ///
793349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
794349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
795349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
796349cc55cSDimitry Andric   ///
797349cc55cSDimitry Andric   /// @param T - The target being registered.
798349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCRegisterInfo for the target.
799349cc55cSDimitry Andric   static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
800349cc55cSDimitry Andric     T.MCRegInfoCtorFn = Fn;
801349cc55cSDimitry Andric   }
802349cc55cSDimitry Andric 
803349cc55cSDimitry Andric   /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
804349cc55cSDimitry Andric   /// the given target.
805349cc55cSDimitry Andric   ///
806349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
807349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
808349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
809349cc55cSDimitry Andric   ///
810349cc55cSDimitry Andric   /// @param T - The target being registered.
811349cc55cSDimitry Andric   /// @param Fn - A function to construct a MCSubtargetInfo for the target.
812349cc55cSDimitry Andric   static void RegisterMCSubtargetInfo(Target &T,
813349cc55cSDimitry Andric                                       Target::MCSubtargetInfoCtorFnTy Fn) {
814349cc55cSDimitry Andric     T.MCSubtargetInfoCtorFn = Fn;
815349cc55cSDimitry Andric   }
816349cc55cSDimitry Andric 
817349cc55cSDimitry Andric   /// RegisterTargetMachine - Register a TargetMachine implementation for the
818349cc55cSDimitry Andric   /// given target.
819349cc55cSDimitry Andric   ///
820349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
821349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
822349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
823349cc55cSDimitry Andric   ///
824349cc55cSDimitry Andric   /// @param T - The target being registered.
825349cc55cSDimitry Andric   /// @param Fn - A function to construct a TargetMachine for the target.
826349cc55cSDimitry Andric   static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) {
827349cc55cSDimitry Andric     T.TargetMachineCtorFn = Fn;
828349cc55cSDimitry Andric   }
829349cc55cSDimitry Andric 
830349cc55cSDimitry Andric   /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
831349cc55cSDimitry Andric   /// given target.
832349cc55cSDimitry Andric   ///
833349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
834349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
835349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
836349cc55cSDimitry Andric   ///
837349cc55cSDimitry Andric   /// @param T - The target being registered.
838349cc55cSDimitry Andric   /// @param Fn - A function to construct an AsmBackend for the target.
839349cc55cSDimitry Andric   static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
840349cc55cSDimitry Andric     T.MCAsmBackendCtorFn = Fn;
841349cc55cSDimitry Andric   }
842349cc55cSDimitry Andric 
843349cc55cSDimitry Andric   /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
844349cc55cSDimitry Andric   /// the given target.
845349cc55cSDimitry Andric   ///
846349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
847349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
848349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
849349cc55cSDimitry Andric   ///
850349cc55cSDimitry Andric   /// @param T - The target being registered.
851349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCTargetAsmParser for the target.
852349cc55cSDimitry Andric   static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
853349cc55cSDimitry Andric     T.MCAsmParserCtorFn = Fn;
854349cc55cSDimitry Andric   }
855349cc55cSDimitry Andric 
856349cc55cSDimitry Andric   /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
857349cc55cSDimitry Andric   /// target.
858349cc55cSDimitry Andric   ///
859349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
860349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
861349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
862349cc55cSDimitry Andric   ///
863349cc55cSDimitry Andric   /// @param T - The target being registered.
864349cc55cSDimitry Andric   /// @param Fn - A function to construct an AsmPrinter for the target.
865349cc55cSDimitry Andric   static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
866349cc55cSDimitry Andric     T.AsmPrinterCtorFn = Fn;
867349cc55cSDimitry Andric   }
868349cc55cSDimitry Andric 
869349cc55cSDimitry Andric   /// RegisterMCDisassembler - Register a MCDisassembler implementation for
870349cc55cSDimitry Andric   /// the given target.
871349cc55cSDimitry Andric   ///
872349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
873349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
874349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
875349cc55cSDimitry Andric   ///
876349cc55cSDimitry Andric   /// @param T - The target being registered.
877349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCDisassembler for the target.
878349cc55cSDimitry Andric   static void RegisterMCDisassembler(Target &T,
879349cc55cSDimitry Andric                                      Target::MCDisassemblerCtorTy Fn) {
880349cc55cSDimitry Andric     T.MCDisassemblerCtorFn = Fn;
881349cc55cSDimitry Andric   }
882349cc55cSDimitry Andric 
883349cc55cSDimitry Andric   /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
884349cc55cSDimitry Andric   /// given target.
885349cc55cSDimitry Andric   ///
886349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
887349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
888349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
889349cc55cSDimitry Andric   ///
890349cc55cSDimitry Andric   /// @param T - The target being registered.
891349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCInstPrinter for the target.
892349cc55cSDimitry Andric   static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) {
893349cc55cSDimitry Andric     T.MCInstPrinterCtorFn = Fn;
894349cc55cSDimitry Andric   }
895349cc55cSDimitry Andric 
896349cc55cSDimitry Andric   /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
897349cc55cSDimitry Andric   /// given target.
898349cc55cSDimitry Andric   ///
899349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
900349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
901349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
902349cc55cSDimitry Andric   ///
903349cc55cSDimitry Andric   /// @param T - The target being registered.
904349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCCodeEmitter for the target.
905349cc55cSDimitry Andric   static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) {
906349cc55cSDimitry Andric     T.MCCodeEmitterCtorFn = Fn;
907349cc55cSDimitry Andric   }
908349cc55cSDimitry Andric 
909349cc55cSDimitry Andric   static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
910349cc55cSDimitry Andric     T.COFFStreamerCtorFn = Fn;
911349cc55cSDimitry Andric   }
912349cc55cSDimitry Andric 
913349cc55cSDimitry Andric   static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) {
914349cc55cSDimitry Andric     T.MachOStreamerCtorFn = Fn;
915349cc55cSDimitry Andric   }
916349cc55cSDimitry Andric 
917349cc55cSDimitry Andric   static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
918349cc55cSDimitry Andric     T.ELFStreamerCtorFn = Fn;
919349cc55cSDimitry Andric   }
920349cc55cSDimitry Andric 
921349cc55cSDimitry Andric   static void RegisterXCOFFStreamer(Target &T, Target::XCOFFStreamerCtorTy Fn) {
922349cc55cSDimitry Andric     T.XCOFFStreamerCtorFn = Fn;
923349cc55cSDimitry Andric   }
924349cc55cSDimitry Andric 
925349cc55cSDimitry Andric   static void RegisterNullTargetStreamer(Target &T,
926349cc55cSDimitry Andric                                          Target::NullTargetStreamerCtorTy Fn) {
927349cc55cSDimitry Andric     T.NullTargetStreamerCtorFn = Fn;
928349cc55cSDimitry Andric   }
929349cc55cSDimitry Andric 
930349cc55cSDimitry Andric   static void RegisterAsmTargetStreamer(Target &T,
931349cc55cSDimitry Andric                                         Target::AsmTargetStreamerCtorTy Fn) {
932349cc55cSDimitry Andric     T.AsmTargetStreamerCtorFn = Fn;
933349cc55cSDimitry Andric   }
934349cc55cSDimitry Andric 
935349cc55cSDimitry Andric   static void
936349cc55cSDimitry Andric   RegisterObjectTargetStreamer(Target &T,
937349cc55cSDimitry Andric                                Target::ObjectTargetStreamerCtorTy Fn) {
938349cc55cSDimitry Andric     T.ObjectTargetStreamerCtorFn = Fn;
939349cc55cSDimitry Andric   }
940349cc55cSDimitry Andric 
941349cc55cSDimitry Andric   /// RegisterMCRelocationInfo - Register an MCRelocationInfo
942349cc55cSDimitry Andric   /// implementation for the given target.
943349cc55cSDimitry Andric   ///
944349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
945349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
946349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
947349cc55cSDimitry Andric   ///
948349cc55cSDimitry Andric   /// @param T - The target being registered.
949349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCRelocationInfo for the target.
950349cc55cSDimitry Andric   static void RegisterMCRelocationInfo(Target &T,
951349cc55cSDimitry Andric                                        Target::MCRelocationInfoCtorTy Fn) {
952349cc55cSDimitry Andric     T.MCRelocationInfoCtorFn = Fn;
953349cc55cSDimitry Andric   }
954349cc55cSDimitry Andric 
955349cc55cSDimitry Andric   /// RegisterMCSymbolizer - Register an MCSymbolizer
956349cc55cSDimitry Andric   /// implementation for the given target.
957349cc55cSDimitry Andric   ///
958349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
959349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
960349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
961349cc55cSDimitry Andric   ///
962349cc55cSDimitry Andric   /// @param T - The target being registered.
963349cc55cSDimitry Andric   /// @param Fn - A function to construct an MCSymbolizer for the target.
964349cc55cSDimitry Andric   static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) {
965349cc55cSDimitry Andric     T.MCSymbolizerCtorFn = Fn;
966349cc55cSDimitry Andric   }
967349cc55cSDimitry Andric 
968349cc55cSDimitry Andric   /// RegisterCustomBehaviour - Register a CustomBehaviour
969349cc55cSDimitry Andric   /// implementation for the given target.
970349cc55cSDimitry Andric   ///
971349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
972349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
973349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
974349cc55cSDimitry Andric   ///
975349cc55cSDimitry Andric   /// @param T - The target being registered.
976349cc55cSDimitry Andric   /// @param Fn - A function to construct a CustomBehaviour for the target.
977349cc55cSDimitry Andric   static void RegisterCustomBehaviour(Target &T,
978349cc55cSDimitry Andric                                       Target::CustomBehaviourCtorTy Fn) {
979349cc55cSDimitry Andric     T.CustomBehaviourCtorFn = Fn;
980349cc55cSDimitry Andric   }
981349cc55cSDimitry Andric 
982349cc55cSDimitry Andric   /// RegisterInstrPostProcess - Register an InstrPostProcess
983349cc55cSDimitry Andric   /// implementation for the given target.
984349cc55cSDimitry Andric   ///
985349cc55cSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
986349cc55cSDimitry Andric   /// while another thread is attempting to access the registry. Typically
987349cc55cSDimitry Andric   /// this is done by initializing all targets at program startup.
988349cc55cSDimitry Andric   ///
989349cc55cSDimitry Andric   /// @param T - The target being registered.
990349cc55cSDimitry Andric   /// @param Fn - A function to construct an InstrPostProcess for the target.
991349cc55cSDimitry Andric   static void RegisterInstrPostProcess(Target &T,
992349cc55cSDimitry Andric                                        Target::InstrPostProcessCtorTy Fn) {
993349cc55cSDimitry Andric     T.InstrPostProcessCtorFn = Fn;
994349cc55cSDimitry Andric   }
995349cc55cSDimitry Andric 
996bdd1243dSDimitry Andric   /// RegisterInstrumentManager - Register an InstrumentManager
997bdd1243dSDimitry Andric   /// implementation for the given target.
998bdd1243dSDimitry Andric   ///
999bdd1243dSDimitry Andric   /// Clients are responsible for ensuring that registration doesn't occur
1000bdd1243dSDimitry Andric   /// while another thread is attempting to access the registry. Typically
1001bdd1243dSDimitry Andric   /// this is done by initializing all targets at program startup.
1002bdd1243dSDimitry Andric   ///
1003bdd1243dSDimitry Andric   /// @param T - The target being registered.
1004bdd1243dSDimitry Andric   /// @param Fn - A function to construct an InstrumentManager for the
1005bdd1243dSDimitry Andric   /// target.
1006bdd1243dSDimitry Andric   static void RegisterInstrumentManager(Target &T,
1007bdd1243dSDimitry Andric                                         Target::InstrumentManagerCtorTy Fn) {
1008bdd1243dSDimitry Andric     T.InstrumentManagerCtorFn = Fn;
1009bdd1243dSDimitry Andric   }
1010bdd1243dSDimitry Andric 
1011349cc55cSDimitry Andric   /// @}
1012349cc55cSDimitry Andric };
1013349cc55cSDimitry Andric 
1014349cc55cSDimitry Andric //===--------------------------------------------------------------------===//
1015349cc55cSDimitry Andric 
1016349cc55cSDimitry Andric /// RegisterTarget - Helper template for registering a target, for use in the
1017349cc55cSDimitry Andric /// target's initialization function. Usage:
1018349cc55cSDimitry Andric ///
1019349cc55cSDimitry Andric ///
1020349cc55cSDimitry Andric /// Target &getTheFooTarget() { // The global target instance.
1021349cc55cSDimitry Andric ///   static Target TheFooTarget;
1022349cc55cSDimitry Andric ///   return TheFooTarget;
1023349cc55cSDimitry Andric /// }
1024349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTargetInfo() {
1025349cc55cSDimitry Andric ///   RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo
1026349cc55cSDimitry Andric ///   description", "Foo" /* Backend Name */);
1027349cc55cSDimitry Andric /// }
1028349cc55cSDimitry Andric template <Triple::ArchType TargetArchType = Triple::UnknownArch,
1029349cc55cSDimitry Andric           bool HasJIT = false>
1030349cc55cSDimitry Andric struct RegisterTarget {
1031349cc55cSDimitry Andric   RegisterTarget(Target &T, const char *Name, const char *Desc,
1032349cc55cSDimitry Andric                  const char *BackendName) {
1033349cc55cSDimitry Andric     TargetRegistry::RegisterTarget(T, Name, Desc, BackendName, &getArchMatch,
1034349cc55cSDimitry Andric                                    HasJIT);
1035349cc55cSDimitry Andric   }
1036349cc55cSDimitry Andric 
1037349cc55cSDimitry Andric   static bool getArchMatch(Triple::ArchType Arch) {
1038349cc55cSDimitry Andric     return Arch == TargetArchType;
1039349cc55cSDimitry Andric   }
1040349cc55cSDimitry Andric };
1041349cc55cSDimitry Andric 
1042349cc55cSDimitry Andric /// RegisterMCAsmInfo - Helper template for registering a target assembly info
1043349cc55cSDimitry Andric /// implementation.  This invokes the static "Create" method on the class to
1044349cc55cSDimitry Andric /// actually do the construction.  Usage:
1045349cc55cSDimitry Andric ///
1046349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1047349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1048349cc55cSDimitry Andric ///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
1049349cc55cSDimitry Andric /// }
1050349cc55cSDimitry Andric template <class MCAsmInfoImpl> struct RegisterMCAsmInfo {
1051349cc55cSDimitry Andric   RegisterMCAsmInfo(Target &T) {
1052349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
1053349cc55cSDimitry Andric   }
1054349cc55cSDimitry Andric 
1055349cc55cSDimitry Andric private:
1056349cc55cSDimitry Andric   static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, const Triple &TT,
1057349cc55cSDimitry Andric                               const MCTargetOptions &Options) {
1058349cc55cSDimitry Andric     return new MCAsmInfoImpl(TT, Options);
1059349cc55cSDimitry Andric   }
1060349cc55cSDimitry Andric };
1061349cc55cSDimitry Andric 
1062349cc55cSDimitry Andric /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
1063349cc55cSDimitry Andric /// implementation.  This invokes the specified function to do the
1064349cc55cSDimitry Andric /// construction.  Usage:
1065349cc55cSDimitry Andric ///
1066349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1067349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1068349cc55cSDimitry Andric ///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
1069349cc55cSDimitry Andric /// }
1070349cc55cSDimitry Andric struct RegisterMCAsmInfoFn {
1071349cc55cSDimitry Andric   RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
1072349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmInfo(T, Fn);
1073349cc55cSDimitry Andric   }
1074349cc55cSDimitry Andric };
1075349cc55cSDimitry Andric 
1076349cc55cSDimitry Andric /// Helper template for registering a target object file info implementation.
1077349cc55cSDimitry Andric /// This invokes the static "Create" method on the class to actually do the
1078349cc55cSDimitry Andric /// construction.  Usage:
1079349cc55cSDimitry Andric ///
1080349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1081349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1082349cc55cSDimitry Andric ///   RegisterMCObjectFileInfo<FooMCObjectFileInfo> X(TheFooTarget);
1083349cc55cSDimitry Andric /// }
1084349cc55cSDimitry Andric template <class MCObjectFileInfoImpl> struct RegisterMCObjectFileInfo {
1085349cc55cSDimitry Andric   RegisterMCObjectFileInfo(Target &T) {
1086349cc55cSDimitry Andric     TargetRegistry::RegisterMCObjectFileInfo(T, &Allocator);
1087349cc55cSDimitry Andric   }
1088349cc55cSDimitry Andric 
1089349cc55cSDimitry Andric private:
1090349cc55cSDimitry Andric   static MCObjectFileInfo *Allocator(MCContext &Ctx, bool PIC,
1091349cc55cSDimitry Andric                                      bool LargeCodeModel = false) {
1092349cc55cSDimitry Andric     return new MCObjectFileInfoImpl(Ctx, PIC, LargeCodeModel);
1093349cc55cSDimitry Andric   }
1094349cc55cSDimitry Andric };
1095349cc55cSDimitry Andric 
1096349cc55cSDimitry Andric /// Helper template for registering a target object file info implementation.
1097349cc55cSDimitry Andric /// This invokes the specified function to do the construction.  Usage:
1098349cc55cSDimitry Andric ///
1099349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1100349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1101349cc55cSDimitry Andric ///   RegisterMCObjectFileInfoFn X(TheFooTarget, TheFunction);
1102349cc55cSDimitry Andric /// }
1103349cc55cSDimitry Andric struct RegisterMCObjectFileInfoFn {
1104349cc55cSDimitry Andric   RegisterMCObjectFileInfoFn(Target &T, Target::MCObjectFileInfoCtorFnTy Fn) {
1105349cc55cSDimitry Andric     TargetRegistry::RegisterMCObjectFileInfo(T, Fn);
1106349cc55cSDimitry Andric   }
1107349cc55cSDimitry Andric };
1108349cc55cSDimitry Andric 
1109349cc55cSDimitry Andric /// RegisterMCInstrInfo - Helper template for registering a target instruction
1110349cc55cSDimitry Andric /// info implementation.  This invokes the static "Create" method on the class
1111349cc55cSDimitry Andric /// to actually do the construction.  Usage:
1112349cc55cSDimitry Andric ///
1113349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1114349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1115349cc55cSDimitry Andric ///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
1116349cc55cSDimitry Andric /// }
1117349cc55cSDimitry Andric template <class MCInstrInfoImpl> struct RegisterMCInstrInfo {
1118349cc55cSDimitry Andric   RegisterMCInstrInfo(Target &T) {
1119349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
1120349cc55cSDimitry Andric   }
1121349cc55cSDimitry Andric 
1122349cc55cSDimitry Andric private:
1123349cc55cSDimitry Andric   static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); }
1124349cc55cSDimitry Andric };
1125349cc55cSDimitry Andric 
1126349cc55cSDimitry Andric /// RegisterMCInstrInfoFn - Helper template for registering a target
1127349cc55cSDimitry Andric /// instruction info implementation.  This invokes the specified function to
1128349cc55cSDimitry Andric /// do the construction.  Usage:
1129349cc55cSDimitry Andric ///
1130349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1131349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1132349cc55cSDimitry Andric ///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
1133349cc55cSDimitry Andric /// }
1134349cc55cSDimitry Andric struct RegisterMCInstrInfoFn {
1135349cc55cSDimitry Andric   RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
1136349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrInfo(T, Fn);
1137349cc55cSDimitry Andric   }
1138349cc55cSDimitry Andric };
1139349cc55cSDimitry Andric 
1140349cc55cSDimitry Andric /// RegisterMCInstrAnalysis - Helper template for registering a target
1141349cc55cSDimitry Andric /// instruction analyzer implementation.  This invokes the static "Create"
1142349cc55cSDimitry Andric /// method on the class to actually do the construction.  Usage:
1143349cc55cSDimitry Andric ///
1144349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1145349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1146349cc55cSDimitry Andric ///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
1147349cc55cSDimitry Andric /// }
1148349cc55cSDimitry Andric template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis {
1149349cc55cSDimitry Andric   RegisterMCInstrAnalysis(Target &T) {
1150349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
1151349cc55cSDimitry Andric   }
1152349cc55cSDimitry Andric 
1153349cc55cSDimitry Andric private:
1154349cc55cSDimitry Andric   static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
1155349cc55cSDimitry Andric     return new MCInstrAnalysisImpl(Info);
1156349cc55cSDimitry Andric   }
1157349cc55cSDimitry Andric };
1158349cc55cSDimitry Andric 
1159349cc55cSDimitry Andric /// RegisterMCInstrAnalysisFn - Helper template for registering a target
1160349cc55cSDimitry Andric /// instruction analyzer implementation.  This invokes the specified function
1161349cc55cSDimitry Andric /// to do the construction.  Usage:
1162349cc55cSDimitry Andric ///
1163349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1164349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1165349cc55cSDimitry Andric ///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
1166349cc55cSDimitry Andric /// }
1167349cc55cSDimitry Andric struct RegisterMCInstrAnalysisFn {
1168349cc55cSDimitry Andric   RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
1169349cc55cSDimitry Andric     TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
1170349cc55cSDimitry Andric   }
1171349cc55cSDimitry Andric };
1172349cc55cSDimitry Andric 
1173349cc55cSDimitry Andric /// RegisterMCRegInfo - Helper template for registering a target register info
1174349cc55cSDimitry Andric /// implementation.  This invokes the static "Create" method on the class to
1175349cc55cSDimitry Andric /// actually do the construction.  Usage:
1176349cc55cSDimitry Andric ///
1177349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1178349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1179349cc55cSDimitry Andric ///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
1180349cc55cSDimitry Andric /// }
1181349cc55cSDimitry Andric template <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
1182349cc55cSDimitry Andric   RegisterMCRegInfo(Target &T) {
1183349cc55cSDimitry Andric     TargetRegistry::RegisterMCRegInfo(T, &Allocator);
1184349cc55cSDimitry Andric   }
1185349cc55cSDimitry Andric 
1186349cc55cSDimitry Andric private:
1187349cc55cSDimitry Andric   static MCRegisterInfo *Allocator(const Triple & /*TT*/) {
1188349cc55cSDimitry Andric     return new MCRegisterInfoImpl();
1189349cc55cSDimitry Andric   }
1190349cc55cSDimitry Andric };
1191349cc55cSDimitry Andric 
1192349cc55cSDimitry Andric /// RegisterMCRegInfoFn - Helper template for registering a target register
1193349cc55cSDimitry Andric /// info implementation.  This invokes the specified function to do the
1194349cc55cSDimitry Andric /// construction.  Usage:
1195349cc55cSDimitry Andric ///
1196349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1197349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1198349cc55cSDimitry Andric ///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
1199349cc55cSDimitry Andric /// }
1200349cc55cSDimitry Andric struct RegisterMCRegInfoFn {
1201349cc55cSDimitry Andric   RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
1202349cc55cSDimitry Andric     TargetRegistry::RegisterMCRegInfo(T, Fn);
1203349cc55cSDimitry Andric   }
1204349cc55cSDimitry Andric };
1205349cc55cSDimitry Andric 
1206349cc55cSDimitry Andric /// RegisterMCSubtargetInfo - Helper template for registering a target
1207349cc55cSDimitry Andric /// subtarget info implementation.  This invokes the static "Create" method
1208349cc55cSDimitry Andric /// on the class to actually do the construction.  Usage:
1209349cc55cSDimitry Andric ///
1210349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1211349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1212349cc55cSDimitry Andric ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
1213349cc55cSDimitry Andric /// }
1214349cc55cSDimitry Andric template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo {
1215349cc55cSDimitry Andric   RegisterMCSubtargetInfo(Target &T) {
1216349cc55cSDimitry Andric     TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
1217349cc55cSDimitry Andric   }
1218349cc55cSDimitry Andric 
1219349cc55cSDimitry Andric private:
1220349cc55cSDimitry Andric   static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/,
1221349cc55cSDimitry Andric                                     StringRef /*FS*/) {
1222349cc55cSDimitry Andric     return new MCSubtargetInfoImpl();
1223349cc55cSDimitry Andric   }
1224349cc55cSDimitry Andric };
1225349cc55cSDimitry Andric 
1226349cc55cSDimitry Andric /// RegisterMCSubtargetInfoFn - Helper template for registering a target
1227349cc55cSDimitry Andric /// subtarget info implementation.  This invokes the specified function to
1228349cc55cSDimitry Andric /// do the construction.  Usage:
1229349cc55cSDimitry Andric ///
1230349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1231349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1232349cc55cSDimitry Andric ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
1233349cc55cSDimitry Andric /// }
1234349cc55cSDimitry Andric struct RegisterMCSubtargetInfoFn {
1235349cc55cSDimitry Andric   RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
1236349cc55cSDimitry Andric     TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
1237349cc55cSDimitry Andric   }
1238349cc55cSDimitry Andric };
1239349cc55cSDimitry Andric 
1240349cc55cSDimitry Andric /// RegisterTargetMachine - Helper template for registering a target machine
1241349cc55cSDimitry Andric /// implementation, for use in the target machine initialization
1242349cc55cSDimitry Andric /// function. Usage:
1243349cc55cSDimitry Andric ///
1244349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() {
1245349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1246349cc55cSDimitry Andric ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
1247349cc55cSDimitry Andric /// }
1248349cc55cSDimitry Andric template <class TargetMachineImpl> struct RegisterTargetMachine {
1249349cc55cSDimitry Andric   RegisterTargetMachine(Target &T) {
1250349cc55cSDimitry Andric     TargetRegistry::RegisterTargetMachine(T, &Allocator);
1251349cc55cSDimitry Andric   }
1252349cc55cSDimitry Andric 
1253349cc55cSDimitry Andric private:
12545f757f3fSDimitry Andric   static TargetMachine *
12555f757f3fSDimitry Andric   Allocator(const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
12565f757f3fSDimitry Andric             const TargetOptions &Options, std::optional<Reloc::Model> RM,
12575f757f3fSDimitry Andric             std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT) {
1258349cc55cSDimitry Andric     return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT);
1259349cc55cSDimitry Andric   }
1260349cc55cSDimitry Andric };
1261349cc55cSDimitry Andric 
1262349cc55cSDimitry Andric /// RegisterMCAsmBackend - Helper template for registering a target specific
1263349cc55cSDimitry Andric /// assembler backend. Usage:
1264349cc55cSDimitry Andric ///
1265349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCAsmBackend() {
1266349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1267349cc55cSDimitry Andric ///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
1268349cc55cSDimitry Andric /// }
1269349cc55cSDimitry Andric template <class MCAsmBackendImpl> struct RegisterMCAsmBackend {
1270349cc55cSDimitry Andric   RegisterMCAsmBackend(Target &T) {
1271349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
1272349cc55cSDimitry Andric   }
1273349cc55cSDimitry Andric 
1274349cc55cSDimitry Andric private:
1275349cc55cSDimitry Andric   static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI,
1276349cc55cSDimitry Andric                                  const MCRegisterInfo &MRI,
1277349cc55cSDimitry Andric                                  const MCTargetOptions &Options) {
1278349cc55cSDimitry Andric     return new MCAsmBackendImpl(T, STI, MRI);
1279349cc55cSDimitry Andric   }
1280349cc55cSDimitry Andric };
1281349cc55cSDimitry Andric 
1282349cc55cSDimitry Andric /// RegisterMCAsmParser - Helper template for registering a target specific
1283349cc55cSDimitry Andric /// assembly parser, for use in the target machine initialization
1284349cc55cSDimitry Andric /// function. Usage:
1285349cc55cSDimitry Andric ///
1286349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCAsmParser() {
1287349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1288349cc55cSDimitry Andric ///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
1289349cc55cSDimitry Andric /// }
1290349cc55cSDimitry Andric template <class MCAsmParserImpl> struct RegisterMCAsmParser {
1291349cc55cSDimitry Andric   RegisterMCAsmParser(Target &T) {
1292349cc55cSDimitry Andric     TargetRegistry::RegisterMCAsmParser(T, &Allocator);
1293349cc55cSDimitry Andric   }
1294349cc55cSDimitry Andric 
1295349cc55cSDimitry Andric private:
1296349cc55cSDimitry Andric   static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI,
1297349cc55cSDimitry Andric                                       MCAsmParser &P, const MCInstrInfo &MII,
1298349cc55cSDimitry Andric                                       const MCTargetOptions &Options) {
1299349cc55cSDimitry Andric     return new MCAsmParserImpl(STI, P, MII, Options);
1300349cc55cSDimitry Andric   }
1301349cc55cSDimitry Andric };
1302349cc55cSDimitry Andric 
1303349cc55cSDimitry Andric /// RegisterAsmPrinter - Helper template for registering a target specific
1304349cc55cSDimitry Andric /// assembly printer, for use in the target machine initialization
1305349cc55cSDimitry Andric /// function. Usage:
1306349cc55cSDimitry Andric ///
1307349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooAsmPrinter() {
1308349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1309349cc55cSDimitry Andric ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
1310349cc55cSDimitry Andric /// }
1311349cc55cSDimitry Andric template <class AsmPrinterImpl> struct RegisterAsmPrinter {
1312349cc55cSDimitry Andric   RegisterAsmPrinter(Target &T) {
1313349cc55cSDimitry Andric     TargetRegistry::RegisterAsmPrinter(T, &Allocator);
1314349cc55cSDimitry Andric   }
1315349cc55cSDimitry Andric 
1316349cc55cSDimitry Andric private:
1317349cc55cSDimitry Andric   static AsmPrinter *Allocator(TargetMachine &TM,
1318349cc55cSDimitry Andric                                std::unique_ptr<MCStreamer> &&Streamer) {
1319349cc55cSDimitry Andric     return new AsmPrinterImpl(TM, std::move(Streamer));
1320349cc55cSDimitry Andric   }
1321349cc55cSDimitry Andric };
1322349cc55cSDimitry Andric 
1323349cc55cSDimitry Andric /// RegisterMCCodeEmitter - Helper template for registering a target specific
1324349cc55cSDimitry Andric /// machine code emitter, for use in the target initialization
1325349cc55cSDimitry Andric /// function. Usage:
1326349cc55cSDimitry Andric ///
1327349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
1328349cc55cSDimitry Andric ///   extern Target TheFooTarget;
1329349cc55cSDimitry Andric ///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
1330349cc55cSDimitry Andric /// }
1331349cc55cSDimitry Andric template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter {
1332349cc55cSDimitry Andric   RegisterMCCodeEmitter(Target &T) {
1333349cc55cSDimitry Andric     TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
1334349cc55cSDimitry Andric   }
1335349cc55cSDimitry Andric 
1336349cc55cSDimitry Andric private:
1337349cc55cSDimitry Andric   static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
1338349cc55cSDimitry Andric                                   MCContext & /*Ctx*/) {
1339349cc55cSDimitry Andric     return new MCCodeEmitterImpl();
1340349cc55cSDimitry Andric   }
1341349cc55cSDimitry Andric };
1342349cc55cSDimitry Andric 
1343349cc55cSDimitry Andric } // end namespace llvm
1344349cc55cSDimitry Andric 
1345349cc55cSDimitry Andric #endif // LLVM_MC_TARGETREGISTRY_H
1346