1 //===-- Target/TargetRegistry.h - Target Registration -----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file exposes the TargetRegistry interface, which tools can use to access
11 // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
12 // which have been registered.
14 // Target specific class implementations should register themselves using the
15 // appropriate TargetRegistry interfaces.
17 //===----------------------------------------------------------------------===//
19 #ifndef LLVM_TARGET_TARGETREGISTRY_H
20 #define LLVM_TARGET_TARGETREGISTRY_H
22 #include "llvm/ADT/Triple.h"
37 class TargetAsmParser;
39 class formatted_raw_ostream;
42 /// Target - Wrapper for Target specific information.
44 /// For registration purposes, this is a POD type so that targets can be
45 /// registered without the use of static constructors.
47 /// Targets should implement a single global instance of this class (which
48 /// will be zero initialized), and pass that instance to the TargetRegistry as
49 /// part of their initialization.
52 friend struct TargetRegistry;
54 typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
56 typedef const MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
58 typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
59 const std::string &TT,
60 const std::string &Features);
61 typedef AsmPrinter *(*AsmPrinterCtorTy)(formatted_raw_ostream &OS,
65 const MCAsmInfo *MAI);
66 typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
67 const MCAsmInfo &MAI);
68 typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P);
69 typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
70 typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
71 unsigned SyntaxVariant,
74 typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
79 /// Next - The next registered target in the linked list, maintained by the
83 /// TripleMatchQualityFn - The target function for rating the match quality
85 TripleMatchQualityFnTy TripleMatchQualityFn;
87 /// Name - The target name.
90 /// ShortDesc - A short description of the target.
91 const char *ShortDesc;
93 /// HasJIT - Whether this target supports the JIT.
96 AsmInfoCtorFnTy AsmInfoCtorFn;
98 /// TargetMachineCtorFn - Construction function for this target's
99 /// TargetMachine, if registered.
100 TargetMachineCtorTy TargetMachineCtorFn;
102 /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer,
104 AsmLexerCtorTy AsmLexerCtorFn;
106 /// AsmParserCtorFn - Construction function for this target's
107 /// TargetAsmParser, if registered.
108 AsmParserCtorTy AsmParserCtorFn;
110 /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
112 AsmPrinterCtorTy AsmPrinterCtorFn;
114 /// MCDisassemblerCtorFn - Construction function for this target's
115 /// MCDisassembler, if registered.
116 MCDisassemblerCtorTy MCDisassemblerCtorFn;
118 /// MCInstPrinterCtorFn - Construction function for this target's
119 /// MCInstPrinter, if registered.
120 MCInstPrinterCtorTy MCInstPrinterCtorFn;
122 /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
124 CodeEmitterCtorTy CodeEmitterCtorFn;
127 /// @name Target Information
130 // getNext - Return the next registered target.
131 const Target *getNext() const { return Next; }
133 /// getName - Get the target name.
134 const char *getName() const { return Name; }
136 /// getShortDescription - Get a short description of the target.
137 const char *getShortDescription() const { return ShortDesc; }
140 /// @name Feature Predicates
143 /// hasJIT - Check if this targets supports the just-in-time compilation.
144 bool hasJIT() const { return HasJIT; }
146 /// hasTargetMachine - Check if this target supports code generation.
147 bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
149 /// hasAsmLexer - Check if this target supports .s lexing.
150 bool hasAsmLexer() const { return AsmLexerCtorFn != 0; }
152 /// hasAsmParser - Check if this target supports .s parsing.
153 bool hasAsmParser() const { return AsmParserCtorFn != 0; }
155 /// hasAsmPrinter - Check if this target supports .s printing.
156 bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
158 /// hasMCDisassembler - Check if this target has a disassembler.
159 bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
161 /// hasMCInstPrinter - Check if this target has an instruction printer.
162 bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
164 /// hasCodeEmitter - Check if this target supports instruction encoding.
165 bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
168 /// @name Feature Constructors
171 /// createAsmInfo - Create a MCAsmInfo implementation for the specified
174 /// \arg Triple - This argument is used to determine the target machine
175 /// feature set; it should always be provided. Generally this should be
176 /// either the target triple from the module, or the target triple of the
177 /// host if that does not exist.
178 const MCAsmInfo *createAsmInfo(StringRef Triple) const {
181 return AsmInfoCtorFn(*this, Triple);
184 /// createTargetMachine - Create a target specific machine implementation
185 /// for the specified \arg Triple.
187 /// \arg Triple - This argument is used to determine the target machine
188 /// feature set; it should always be provided. Generally this should be
189 /// either the target triple from the module, or the target triple of the
190 /// host if that does not exist.
191 TargetMachine *createTargetMachine(const std::string &Triple,
192 const std::string &Features) const {
193 if (!TargetMachineCtorFn)
195 return TargetMachineCtorFn(*this, Triple, Features);
198 /// createAsmLexer - Create a target specific assembly lexer.
200 TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const {
203 return AsmLexerCtorFn(*this, MAI);
206 /// createAsmParser - Create a target specific assembly parser.
208 /// \arg Parser - The target independent parser implementation to use for
209 /// parsing and lexing.
210 TargetAsmParser *createAsmParser(MCAsmParser &Parser) const {
211 if (!AsmParserCtorFn)
213 return AsmParserCtorFn(*this, Parser);
216 /// createAsmPrinter - Create a target specific assembly printer pass. This
217 /// takes ownership of the MCContext and MCStreamer objects but not the MAI.
218 AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM,
219 MCContext &Ctx, MCStreamer &Streamer,
220 const MCAsmInfo *MAI) const {
221 if (!AsmPrinterCtorFn)
223 return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI);
226 const MCDisassembler *createMCDisassembler() const {
227 if (!MCDisassemblerCtorFn)
229 return MCDisassemblerCtorFn(*this);
232 MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
233 const MCAsmInfo &MAI,
234 raw_ostream &O) const {
235 if (!MCInstPrinterCtorFn)
237 return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, O);
241 /// createCodeEmitter - Create a target specific code emitter.
242 MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const {
243 if (!CodeEmitterCtorFn)
245 return CodeEmitterCtorFn(*this, TM, Ctx);
251 /// TargetRegistry - Generic interface to target specific features.
252 struct TargetRegistry {
254 const Target *Current;
255 explicit iterator(Target *T) : Current(T) {}
256 friend struct TargetRegistry;
258 iterator(const iterator &I) : Current(I.Current) {}
259 iterator() : Current(0) {}
261 bool operator==(const iterator &x) const {
262 return Current == x.Current;
264 bool operator!=(const iterator &x) const {
265 return !operator==(x);
268 // Iterator traversal: forward iteration only
269 iterator &operator++() { // Preincrement
270 assert(Current && "Cannot increment end iterator!");
271 Current = Current->getNext();
274 iterator operator++(int) { // Postincrement
275 iterator tmp = *this;
280 const Target &operator*() const {
281 assert(Current && "Cannot dereference end iterator!");
285 const Target *operator->() const {
290 /// @name Registry Access
293 static iterator begin();
295 static iterator end() { return iterator(); }
297 /// lookupTarget - Lookup a target based on a target triple.
299 /// \param Triple - The triple to use for finding a target.
300 /// \param Error - On failure, an error string describing why no target was
302 static const Target *lookupTarget(const std::string &Triple,
305 /// getClosestTargetForJIT - Pick the best target that is compatible with
306 /// the current host. If no close target can be found, this returns null
307 /// and sets the Error string to a reason.
309 /// Maintained for compatibility through 2.6.
310 static const Target *getClosestTargetForJIT(std::string &Error);
313 /// @name Target Registration
316 /// RegisterTarget - Register the given target. Attempts to register a
317 /// target which has already been registered will be ignored.
319 /// Clients are responsible for ensuring that registration doesn't occur
320 /// while another thread is attempting to access the registry. Typically
321 /// this is done by initializing all targets at program startup.
323 /// @param T - The target being registered.
324 /// @param Name - The target name. This should be a static string.
325 /// @param ShortDesc - A short target description. This should be a static
327 /// @param TQualityFn - The triple match quality computation function for
329 /// @param HasJIT - Whether the target supports JIT code
331 static void RegisterTarget(Target &T,
333 const char *ShortDesc,
334 Target::TripleMatchQualityFnTy TQualityFn,
335 bool HasJIT = false);
337 /// RegisterAsmInfo - Register a MCAsmInfo implementation for the
340 /// Clients are responsible for ensuring that registration doesn't occur
341 /// while another thread is attempting to access the registry. Typically
342 /// this is done by initializing all targets at program startup.
344 /// @param T - The target being registered.
345 /// @param Fn - A function to construct a MCAsmInfo for the target.
346 static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) {
347 // Ignore duplicate registration.
348 if (!T.AsmInfoCtorFn)
349 T.AsmInfoCtorFn = Fn;
352 /// RegisterTargetMachine - Register a TargetMachine implementation for the
355 /// Clients are responsible for ensuring that registration doesn't occur
356 /// while another thread is attempting to access the registry. Typically
357 /// this is done by initializing all targets at program startup.
359 /// @param T - The target being registered.
360 /// @param Fn - A function to construct a TargetMachine for the target.
361 static void RegisterTargetMachine(Target &T,
362 Target::TargetMachineCtorTy Fn) {
363 // Ignore duplicate registration.
364 if (!T.TargetMachineCtorFn)
365 T.TargetMachineCtorFn = Fn;
368 /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the
371 /// Clients are responsible for ensuring that registration doesn't occur
372 /// while another thread is attempting to access the registry. Typically
373 /// this is done by initializing all targets at program startup.
375 /// @param T - The target being registered.
376 /// @param Fn - A function to construct an AsmLexer for the target.
377 static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) {
378 if (!T.AsmLexerCtorFn)
379 T.AsmLexerCtorFn = Fn;
382 /// RegisterAsmParser - Register a TargetAsmParser implementation for the
385 /// Clients are responsible for ensuring that registration doesn't occur
386 /// while another thread is attempting to access the registry. Typically
387 /// this is done by initializing all targets at program startup.
389 /// @param T - The target being registered.
390 /// @param Fn - A function to construct an AsmParser for the target.
391 static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
392 if (!T.AsmParserCtorFn)
393 T.AsmParserCtorFn = Fn;
396 /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
399 /// Clients are responsible for ensuring that registration doesn't occur
400 /// while another thread is attempting to access the registry. Typically
401 /// this is done by initializing all targets at program startup.
403 /// @param T - The target being registered.
404 /// @param Fn - A function to construct an AsmPrinter for the target.
405 static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
406 // Ignore duplicate registration.
407 if (!T.AsmPrinterCtorFn)
408 T.AsmPrinterCtorFn = Fn;
411 /// RegisterMCDisassembler - Register a MCDisassembler implementation for
412 /// the given target.
414 /// Clients are responsible for ensuring that registration doesn't occur
415 /// while another thread is attempting to access the registry. Typically
416 /// this is done by initializing all targets at program startup.
418 /// @param T - The target being registered.
419 /// @param Fn - A function to construct an MCDisassembler for the target.
420 static void RegisterMCDisassembler(Target &T,
421 Target::MCDisassemblerCtorTy Fn) {
422 if (!T.MCDisassemblerCtorFn)
423 T.MCDisassemblerCtorFn = Fn;
426 /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
429 /// Clients are responsible for ensuring that registration doesn't occur
430 /// while another thread is attempting to access the registry. Typically
431 /// this is done by initializing all targets at program startup.
433 /// @param T - The target being registered.
434 /// @param Fn - A function to construct an MCInstPrinter for the target.
435 static void RegisterMCInstPrinter(Target &T,
436 Target::MCInstPrinterCtorTy Fn) {
437 if (!T.MCInstPrinterCtorFn)
438 T.MCInstPrinterCtorFn = Fn;
441 /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
444 /// Clients are responsible for ensuring that registration doesn't occur
445 /// while another thread is attempting to access the registry. Typically
446 /// this is done by initializing all targets at program startup.
448 /// @param T - The target being registered.
449 /// @param Fn - A function to construct an MCCodeEmitter for the target.
450 static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) {
451 if (!T.CodeEmitterCtorFn)
452 T.CodeEmitterCtorFn = Fn;
459 //===--------------------------------------------------------------------===//
461 /// RegisterTarget - Helper template for registering a target, for use in the
462 /// target's initialization function. Usage:
465 /// Target TheFooTarget; // The global target instance.
467 /// extern "C" void LLVMInitializeFooTargetInfo() {
468 /// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
470 template<Triple::ArchType TargetArchType = Triple::InvalidArch,
472 struct RegisterTarget {
473 RegisterTarget(Target &T, const char *Name, const char *Desc) {
474 TargetRegistry::RegisterTarget(T, Name, Desc,
475 &getTripleMatchQuality,
479 static unsigned getTripleMatchQuality(const std::string &TT) {
480 if (Triple(TT).getArch() == TargetArchType)
486 /// RegisterAsmInfo - Helper template for registering a target assembly info
487 /// implementation. This invokes the static "Create" method on the class to
488 /// actually do the construction. Usage:
490 /// extern "C" void LLVMInitializeFooTarget() {
491 /// extern Target TheFooTarget;
492 /// RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget);
494 template<class MCAsmInfoImpl>
495 struct RegisterAsmInfo {
496 RegisterAsmInfo(Target &T) {
497 TargetRegistry::RegisterAsmInfo(T, &Allocator);
500 static const MCAsmInfo *Allocator(const Target &T, StringRef TT) {
501 return new MCAsmInfoImpl(T, TT);
506 /// RegisterAsmInfoFn - Helper template for registering a target assembly info
507 /// implementation. This invokes the specified function to do the
508 /// construction. Usage:
510 /// extern "C" void LLVMInitializeFooTarget() {
511 /// extern Target TheFooTarget;
512 /// RegisterAsmInfoFn X(TheFooTarget, TheFunction);
514 struct RegisterAsmInfoFn {
515 RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) {
516 TargetRegistry::RegisterAsmInfo(T, Fn);
521 /// RegisterTargetMachine - Helper template for registering a target machine
522 /// implementation, for use in the target machine initialization
525 /// extern "C" void LLVMInitializeFooTarget() {
526 /// extern Target TheFooTarget;
527 /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
529 template<class TargetMachineImpl>
530 struct RegisterTargetMachine {
531 RegisterTargetMachine(Target &T) {
532 TargetRegistry::RegisterTargetMachine(T, &Allocator);
536 static TargetMachine *Allocator(const Target &T, const std::string &TT,
537 const std::string &FS) {
538 return new TargetMachineImpl(T, TT, FS);
542 /// RegisterAsmLexer - Helper template for registering a target specific
543 /// assembly lexer, for use in the target machine initialization
546 /// extern "C" void LLVMInitializeFooAsmLexer() {
547 /// extern Target TheFooTarget;
548 /// RegisterAsmLexer<FooAsmLexer> X(TheFooTarget);
550 template<class AsmLexerImpl>
551 struct RegisterAsmLexer {
552 RegisterAsmLexer(Target &T) {
553 TargetRegistry::RegisterAsmLexer(T, &Allocator);
557 static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) {
558 return new AsmLexerImpl(T, MAI);
562 /// RegisterAsmParser - Helper template for registering a target specific
563 /// assembly parser, for use in the target machine initialization
566 /// extern "C" void LLVMInitializeFooAsmParser() {
567 /// extern Target TheFooTarget;
568 /// RegisterAsmParser<FooAsmParser> X(TheFooTarget);
570 template<class AsmParserImpl>
571 struct RegisterAsmParser {
572 RegisterAsmParser(Target &T) {
573 TargetRegistry::RegisterAsmParser(T, &Allocator);
577 static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P) {
578 return new AsmParserImpl(T, P);
582 /// RegisterAsmPrinter - Helper template for registering a target specific
583 /// assembly printer, for use in the target machine initialization
586 /// extern "C" void LLVMInitializeFooAsmPrinter() {
587 /// extern Target TheFooTarget;
588 /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
590 template<class AsmPrinterImpl>
591 struct RegisterAsmPrinter {
592 RegisterAsmPrinter(Target &T) {
593 TargetRegistry::RegisterAsmPrinter(T, &Allocator);
597 static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM,
598 MCContext &Ctx, MCStreamer &Streamer,
599 const MCAsmInfo *MAI) {
600 return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI);
604 /// RegisterCodeEmitter - Helper template for registering a target specific
605 /// machine code emitter, for use in the target initialization
608 /// extern "C" void LLVMInitializeFooCodeEmitter() {
609 /// extern Target TheFooTarget;
610 /// RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget);
612 template<class CodeEmitterImpl>
613 struct RegisterCodeEmitter {
614 RegisterCodeEmitter(Target &T) {
615 TargetRegistry::RegisterCodeEmitter(T, &Allocator);
619 static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
621 return new CodeEmitterImpl(T, TM, Ctx);