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