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