allow registering target lexers.
[oota-llvm.git] / include / llvm / Target / TargetRegistry.h
1 //===-- Target/TargetRegistry.h - Target Registration -----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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.
13 //
14 // Target specific class implementations should register themselves using the
15 // appropriate TargetRegistry interfaces.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_TARGET_TARGETREGISTRY_H
20 #define LLVM_TARGET_TARGETREGISTRY_H
21
22 #include "llvm/ADT/Triple.h"
23 #include <string>
24 #include <cassert>
25
26 namespace llvm {
27   class AsmPrinter;
28   class MCAsmParser;
29   class MCCodeEmitter;
30   class Module;
31   class MCAsmInfo;
32   class MCDisassembler;
33   class MCInstPrinter;
34   class TargetAsmLexer;
35   class TargetAsmParser;
36   class TargetMachine;
37   class formatted_raw_ostream;
38   class raw_ostream;
39
40   /// Target - Wrapper for Target specific information.
41   ///
42   /// For registration purposes, this is a POD type so that targets can be
43   /// registered without the use of static constructors.
44   ///
45   /// Targets should implement a single global instance of this class (which
46   /// will be zero initialized), and pass that instance to the TargetRegistry as
47   /// part of their initialization.
48   class Target {
49   public:
50     friend struct TargetRegistry;
51
52     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
53
54     typedef const MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
55                                                 StringRef TT);
56     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
57                                                   const std::string &TT,
58                                                   const std::string &Features);
59     typedef AsmPrinter *(*AsmPrinterCtorTy)(formatted_raw_ostream &OS,
60                                             TargetMachine &TM,
61                                             const MCAsmInfo *MAI,
62                                             bool VerboseAsm);
63     typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
64                                               const MCAsmInfo &MAI);
65     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P);
66     typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
67     typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
68                                                   unsigned SyntaxVariant,
69                                                   const MCAsmInfo &MAI,
70                                                   raw_ostream &O);
71     typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
72                                                 TargetMachine &TM);
73
74   private:
75     /// Next - The next registered target in the linked list, maintained by the
76     /// TargetRegistry.
77     Target *Next;
78
79     /// TripleMatchQualityFn - The target function for rating the match quality
80     /// of a triple.
81     TripleMatchQualityFnTy TripleMatchQualityFn;
82
83     /// Name - The target name.
84     const char *Name;
85
86     /// ShortDesc - A short description of the target.
87     const char *ShortDesc;
88
89     /// HasJIT - Whether this target supports the JIT.
90     bool HasJIT;
91
92     AsmInfoCtorFnTy AsmInfoCtorFn;
93     
94     /// TargetMachineCtorFn - Construction function for this target's
95     /// TargetMachine, if registered.
96     TargetMachineCtorTy TargetMachineCtorFn;
97
98     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
99     /// if registered.
100     AsmPrinterCtorTy AsmPrinterCtorFn;
101
102     /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer,
103     /// if registered.
104     AsmLexerCtorTy AsmLexerCtorFn;
105     
106     /// AsmParserCtorFn - Construction function for this target's
107     /// TargetAsmParser, if registered.
108     AsmParserCtorTy AsmParserCtorFn;
109     
110     /// MCDisassemblerCtorFn - Construction function for this target's
111     /// MCDisassembler, if registered.
112     MCDisassemblerCtorTy MCDisassemblerCtorFn;
113
114     
115     /// MCInstPrinterCtorFn - Construction function for this target's 
116     /// MCInstPrinter, if registered.
117     MCInstPrinterCtorTy MCInstPrinterCtorFn;
118     
119     /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
120     /// if registered.
121     CodeEmitterCtorTy CodeEmitterCtorFn;
122
123   public:
124     /// @name Target Information
125     /// @{
126
127     // getNext - Return the next registered target.
128     const Target *getNext() const { return Next; }
129
130     /// getName - Get the target name.
131     const char *getName() const { return Name; }
132
133     /// getShortDescription - Get a short description of the target.
134     const char *getShortDescription() const { return ShortDesc; }
135
136     /// @}
137     /// @name Feature Predicates
138     /// @{
139
140     /// hasJIT - Check if this targets supports the just-in-time compilation.
141     bool hasJIT() const { return HasJIT; }
142
143     /// hasTargetMachine - Check if this target supports code generation.
144     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
145
146     /// hasAsmPrinter - Check if this target supports .s printing.
147     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
148
149     /// hasAsmParser - Check if this target supports .s parsing.
150     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
151     
152     /// hasMCDisassembler - Check if this target has a disassembler.
153     bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
154
155     /// hasMCInstPrinter - Check if this target has an instruction printer.
156     bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
157
158     /// hasCodeEmitter - Check if this target supports instruction encoding.
159     bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
160
161     /// @}
162     /// @name Feature Constructors
163     /// @{
164     
165     /// createAsmInfo - Create a MCAsmInfo implementation for the specified
166     /// target triple.
167     ///
168     /// \arg Triple - This argument is used to determine the target machine
169     /// feature set; it should always be provided. Generally this should be
170     /// either the target triple from the module, or the target triple of the
171     /// host if that does not exist.
172     const MCAsmInfo *createAsmInfo(StringRef Triple) const {
173       if (!AsmInfoCtorFn)
174         return 0;
175       return AsmInfoCtorFn(*this, Triple);
176     }
177     
178     /// createTargetMachine - Create a target specific machine implementation
179     /// for the specified \arg Triple.
180     ///
181     /// \arg Triple - This argument is used to determine the target machine
182     /// feature set; it should always be provided. Generally this should be
183     /// either the target triple from the module, or the target triple of the
184     /// host if that does not exist.
185     TargetMachine *createTargetMachine(const std::string &Triple,
186                                        const std::string &Features) const {
187       if (!TargetMachineCtorFn)
188         return 0;
189       return TargetMachineCtorFn(*this, Triple, Features);
190     }
191
192     /// createAsmPrinter - Create a target specific assembly printer pass.
193     AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM,
194                                  const MCAsmInfo *MAI, bool Verbose) const {
195       if (!AsmPrinterCtorFn)
196         return 0;
197       return AsmPrinterCtorFn(OS, TM, MAI, Verbose);
198     }
199
200     /// createAsmLexer - Create a target specific assembly lexer.
201     ///
202     TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const {
203       if (!AsmLexerCtorFn)
204         return 0;
205       return AsmLexerCtorFn(*this, MAI);
206     }
207     
208     /// createAsmParser - Create a target specific assembly parser.
209     ///
210     /// \arg Parser - The target independent parser implementation to use for
211     /// parsing and lexing.
212     TargetAsmParser *createAsmParser(MCAsmParser &Parser) const {
213       if (!AsmParserCtorFn)
214         return 0;
215       return AsmParserCtorFn(*this, Parser);
216     }
217     
218     const MCDisassembler *createMCDisassembler() const {
219       if (!MCDisassemblerCtorFn)
220         return 0;
221       return MCDisassemblerCtorFn(*this);
222     }
223
224     MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
225                                        const MCAsmInfo &MAI,
226                                        raw_ostream &O) const {
227       if (!MCInstPrinterCtorFn)
228         return 0;
229       return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, O);
230     }
231     
232     
233     /// createCodeEmitter - Create a target specific code emitter.
234     MCCodeEmitter *createCodeEmitter(TargetMachine &TM) const {
235       if (!CodeEmitterCtorFn)
236         return 0;
237       return CodeEmitterCtorFn(*this, TM);
238     }
239
240     /// @}
241   };
242
243   /// TargetRegistry - Generic interface to target specific features.
244   struct TargetRegistry {
245     class iterator {
246       const Target *Current;
247       explicit iterator(Target *T) : Current(T) {}
248       friend struct TargetRegistry;
249     public:
250       iterator(const iterator &I) : Current(I.Current) {}
251       iterator() : Current(0) {}
252
253       bool operator==(const iterator &x) const {
254         return Current == x.Current;
255       }
256       bool operator!=(const iterator &x) const {
257         return !operator==(x);
258       }
259
260       // Iterator traversal: forward iteration only
261       iterator &operator++() {          // Preincrement
262         assert(Current && "Cannot increment end iterator!");
263         Current = Current->getNext();
264         return *this;
265       }
266       iterator operator++(int) {        // Postincrement
267         iterator tmp = *this; 
268         ++*this; 
269         return tmp;
270       }
271
272       const Target &operator*() const {
273         assert(Current && "Cannot dereference end iterator!");
274         return *Current;
275       }
276
277       const Target *operator->() const {
278         return &operator*();
279       }
280     };
281
282     /// @name Registry Access
283     /// @{
284
285     static iterator begin();
286
287     static iterator end() { return iterator(); }
288
289     /// lookupTarget - Lookup a target based on a target triple.
290     ///
291     /// \param Triple - The triple to use for finding a target.
292     /// \param Error - On failure, an error string describing why no target was
293     /// found.
294     static const Target *lookupTarget(const std::string &Triple,
295                                       std::string &Error);
296
297     /// getClosestTargetForJIT - Pick the best target that is compatible with
298     /// the current host.  If no close target can be found, this returns null
299     /// and sets the Error string to a reason.
300     ///
301     /// Maintained for compatibility through 2.6.
302     static const Target *getClosestTargetForJIT(std::string &Error);
303
304     /// @}
305     /// @name Target Registration
306     /// @{
307
308     /// RegisterTarget - Register the given target. Attempts to register a
309     /// target which has already been registered will be ignored.
310     /// 
311     /// Clients are responsible for ensuring that registration doesn't occur
312     /// while another thread is attempting to access the registry. Typically
313     /// this is done by initializing all targets at program startup.
314     ///
315     /// @param T - The target being registered.
316     /// @param Name - The target name. This should be a static string.
317     /// @param ShortDesc - A short target description. This should be a static
318     /// string. 
319     /// @param TQualityFn - The triple match quality computation function for
320     /// this target.
321     /// @param HasJIT - Whether the target supports JIT code
322     /// generation.
323     static void RegisterTarget(Target &T,
324                                const char *Name,
325                                const char *ShortDesc,
326                                Target::TripleMatchQualityFnTy TQualityFn,
327                                bool HasJIT = false);
328
329     /// RegisterAsmInfo - Register a MCAsmInfo implementation for the
330     /// given target.
331     /// 
332     /// Clients are responsible for ensuring that registration doesn't occur
333     /// while another thread is attempting to access the registry. Typically
334     /// this is done by initializing all targets at program startup.
335     /// 
336     /// @param T - The target being registered.
337     /// @param Fn - A function to construct a MCAsmInfo for the target.
338     static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) {
339       // Ignore duplicate registration.
340       if (!T.AsmInfoCtorFn)
341         T.AsmInfoCtorFn = Fn;
342     }
343     
344     /// RegisterTargetMachine - Register a TargetMachine implementation for the
345     /// given target.
346     /// 
347     /// Clients are responsible for ensuring that registration doesn't occur
348     /// while another thread is attempting to access the registry. Typically
349     /// this is done by initializing all targets at program startup.
350     /// 
351     /// @param T - The target being registered.
352     /// @param Fn - A function to construct a TargetMachine for the target.
353     static void RegisterTargetMachine(Target &T, 
354                                       Target::TargetMachineCtorTy Fn) {
355       // Ignore duplicate registration.
356       if (!T.TargetMachineCtorFn)
357         T.TargetMachineCtorFn = Fn;
358     }
359
360     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
361     /// target.
362     /// 
363     /// Clients are responsible for ensuring that registration doesn't occur
364     /// while another thread is attempting to access the registry. Typically
365     /// this is done by initializing all targets at program startup.
366     ///
367     /// @param T - The target being registered.
368     /// @param Fn - A function to construct an AsmPrinter for the target.
369     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
370       // Ignore duplicate registration.
371       if (!T.AsmPrinterCtorFn)
372         T.AsmPrinterCtorFn = Fn;
373     }
374
375     /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the
376     /// given target.
377     /// 
378     /// Clients are responsible for ensuring that registration doesn't occur
379     /// while another thread is attempting to access the registry. Typically
380     /// this is done by initializing all targets at program startup.
381     ///
382     /// @param T - The target being registered.
383     /// @param Fn - A function to construct an AsmPrinter for the target.
384     static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) {
385       if (!T.AsmLexerCtorFn)
386         T.AsmLexerCtorFn = Fn;
387     }
388     
389     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
390     /// given target.
391     /// 
392     /// Clients are responsible for ensuring that registration doesn't occur
393     /// while another thread is attempting to access the registry. Typically
394     /// this is done by initializing all targets at program startup.
395     ///
396     /// @param T - The target being registered.
397     /// @param Fn - A function to construct an AsmPrinter for the target.
398     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
399       if (!T.AsmParserCtorFn)
400         T.AsmParserCtorFn = Fn;
401     }
402     
403     /// RegisterMCDisassembler - Register a MCDisassembler implementation for
404     /// the given target.
405     /// 
406     /// Clients are responsible for ensuring that registration doesn't occur
407     /// while another thread is attempting to access the registry. Typically
408     /// this is done by initializing all targets at program startup.
409     ///
410     /// @param T - The target being registered.
411     /// @param Fn - A function to construct an MCDisassembler for the target.
412     static void RegisterMCDisassembler(Target &T, 
413                                        Target::MCDisassemblerCtorTy Fn) {
414       if (!T.MCDisassemblerCtorFn)
415         T.MCDisassemblerCtorFn = Fn;
416     }
417
418     /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
419     /// given target.
420     /// 
421     /// Clients are responsible for ensuring that registration doesn't occur
422     /// while another thread is attempting to access the registry. Typically
423     /// this is done by initializing all targets at program startup.
424     ///
425     /// @param T - The target being registered.
426     /// @param Fn - A function to construct an MCInstPrinter for the target.
427     static void RegisterMCInstPrinter(Target &T,
428                                       Target::MCInstPrinterCtorTy Fn) {
429       if (!T.MCInstPrinterCtorFn)
430         T.MCInstPrinterCtorFn = Fn;
431     }
432     
433     /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
434     /// given target.
435     ///
436     /// Clients are responsible for ensuring that registration doesn't occur
437     /// while another thread is attempting to access the registry. Typically
438     /// this is done by initializing all targets at program startup.
439     ///
440     /// @param T - The target being registered.
441     /// @param Fn - A function to construct an AsmPrinter for the target.
442     static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) {
443       if (!T.CodeEmitterCtorFn)
444         T.CodeEmitterCtorFn = Fn;
445     }
446
447     /// @}
448   };
449
450
451   //===--------------------------------------------------------------------===//
452
453   /// RegisterTarget - Helper template for registering a target, for use in the
454   /// target's initialization function. Usage:
455   ///
456   ///
457   /// Target TheFooTarget; // The global target instance.
458   ///
459   /// extern "C" void LLVMInitializeFooTargetInfo() {
460   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
461   /// }
462   template<Triple::ArchType TargetArchType = Triple::InvalidArch,
463            bool HasJIT = false>
464   struct RegisterTarget {
465     RegisterTarget(Target &T, const char *Name, const char *Desc) {
466       TargetRegistry::RegisterTarget(T, Name, Desc,
467                                      &getTripleMatchQuality,
468                                      HasJIT);
469     }
470
471     static unsigned getTripleMatchQuality(const std::string &TT) {
472       if (Triple(TT).getArch() == TargetArchType)
473         return 20;
474       return 0;
475     }
476   };
477
478   /// RegisterAsmInfo - Helper template for registering a target assembly info
479   /// implementation.  This invokes the static "Create" method on the class to
480   /// actually do the construction.  Usage:
481   ///
482   /// extern "C" void LLVMInitializeFooTarget() {
483   ///   extern Target TheFooTarget;
484   ///   RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget);
485   /// }
486   template<class MCAsmInfoImpl>
487   struct RegisterAsmInfo {
488     RegisterAsmInfo(Target &T) {
489       TargetRegistry::RegisterAsmInfo(T, &Allocator);
490     }
491   private:
492     static const MCAsmInfo *Allocator(const Target &T, StringRef TT) {
493       return new MCAsmInfoImpl(T, TT);
494     }
495     
496   };
497
498   /// RegisterAsmInfoFn - Helper template for registering a target assembly info
499   /// implementation.  This invokes the specified function to do the
500   /// construction.  Usage:
501   ///
502   /// extern "C" void LLVMInitializeFooTarget() {
503   ///   extern Target TheFooTarget;
504   ///   RegisterAsmInfoFn X(TheFooTarget, TheFunction);
505   /// }
506   struct RegisterAsmInfoFn {
507     RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) {
508       TargetRegistry::RegisterAsmInfo(T, Fn);
509     }
510   };
511
512
513   /// RegisterTargetMachine - Helper template for registering a target machine
514   /// implementation, for use in the target machine initialization
515   /// function. Usage:
516   ///
517   /// extern "C" void LLVMInitializeFooTarget() {
518   ///   extern Target TheFooTarget;
519   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
520   /// }
521   template<class TargetMachineImpl>
522   struct RegisterTargetMachine {
523     RegisterTargetMachine(Target &T) {
524       TargetRegistry::RegisterTargetMachine(T, &Allocator);
525     }
526
527   private:
528     static TargetMachine *Allocator(const Target &T, const std::string &TT,
529                                     const std::string &FS) {
530       return new TargetMachineImpl(T, TT, FS);
531     }
532   };
533
534   /// RegisterAsmPrinter - Helper template for registering a target specific
535   /// assembly printer, for use in the target machine initialization
536   /// function. Usage:
537   ///
538   /// extern "C" void LLVMInitializeFooAsmPrinter() {
539   ///   extern Target TheFooTarget;
540   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
541   /// }
542   template<class AsmPrinterImpl>
543   struct RegisterAsmPrinter {
544     RegisterAsmPrinter(Target &T) {
545       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
546     }
547
548   private:
549     static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM,
550                                  const MCAsmInfo *MAI, bool Verbose) {
551       return new AsmPrinterImpl(OS, TM, MAI, Verbose);
552     }
553   };
554
555   /// RegisterAsmLexer - Helper template for registering a target specific
556   /// assembly lexer, for use in the target machine initialization
557   /// function. Usage:
558   ///
559   /// extern "C" void LLVMInitializeFooAsmLexer() {
560   ///   extern Target TheFooTarget;
561   ///   RegisterAsmLexer<FooAsmLexer> X(TheFooTarget);
562   /// }
563   template<class AsmLexerImpl>
564   struct RegisterAsmLexer {
565     RegisterAsmLexer(Target &T) {
566       TargetRegistry::RegisterAsmLexer(T, &Allocator);
567     }
568     
569   private:
570     static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) {
571       return new AsmLexerImpl(T, MAI);
572     }
573   };
574
575   /// RegisterAsmParser - Helper template for registering a target specific
576   /// assembly parser, for use in the target machine initialization
577   /// function. Usage:
578   ///
579   /// extern "C" void LLVMInitializeFooAsmParser() {
580   ///   extern Target TheFooTarget;
581   ///   RegisterAsmParser<FooAsmParser> X(TheFooTarget);
582   /// }
583   template<class AsmParserImpl>
584   struct RegisterAsmParser {
585     RegisterAsmParser(Target &T) {
586       TargetRegistry::RegisterAsmParser(T, &Allocator);
587     }
588
589   private:
590     static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P) {
591       return new AsmParserImpl(T, P);
592     }
593   };
594
595   /// RegisterCodeEmitter - Helper template for registering a target specific
596   /// machine code emitter, for use in the target initialization
597   /// function. Usage:
598   ///
599   /// extern "C" void LLVMInitializeFooCodeEmitter() {
600   ///   extern Target TheFooTarget;
601   ///   RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget);
602   /// }
603   template<class CodeEmitterImpl>
604   struct RegisterCodeEmitter {
605     RegisterCodeEmitter(Target &T) {
606       TargetRegistry::RegisterCodeEmitter(T, &Allocator);
607     }
608
609   private:
610     static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM) {
611       return new CodeEmitterImpl(T, TM);
612     }
613   };
614
615 }
616
617 #endif