Formatting tweaks (trailing whitespace, ordering, comments).
[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 Module;
29   class MCAsmInfo;
30   class MCAsmParser;
31   class MCCodeEmitter;
32   class MCContext;
33   class MCDisassembler;
34   class MCInstPrinter;
35   class MCStreamer;
36   class TargetAsmLexer;
37   class TargetAsmParser;
38   class TargetMachine;
39   class formatted_raw_ostream;
40   class raw_ostream;
41
42   /// Target - Wrapper for Target specific information.
43   ///
44   /// For registration purposes, this is a POD type so that targets can be
45   /// registered without the use of static constructors.
46   ///
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.
50   class Target {
51   public:
52     friend struct TargetRegistry;
53
54     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
55
56     typedef const MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
57                                                 StringRef TT);
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,
62                                             TargetMachine &TM,
63                                             MCContext &Ctx,
64                                             MCStreamer &Streamer,
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,
72                                                   const MCAsmInfo &MAI,
73                                                   raw_ostream &O);
74     typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
75                                                 TargetMachine &TM,
76                                                 MCContext &Ctx);
77
78   private:
79     /// Next - The next registered target in the linked list, maintained by the
80     /// TargetRegistry.
81     Target *Next;
82
83     /// TripleMatchQualityFn - The target function for rating the match quality
84     /// of a triple.
85     TripleMatchQualityFnTy TripleMatchQualityFn;
86
87     /// Name - The target name.
88     const char *Name;
89
90     /// ShortDesc - A short description of the target.
91     const char *ShortDesc;
92
93     /// HasJIT - Whether this target supports the JIT.
94     bool HasJIT;
95
96     AsmInfoCtorFnTy AsmInfoCtorFn;
97
98     /// TargetMachineCtorFn - Construction function for this target's
99     /// TargetMachine, if registered.
100     TargetMachineCtorTy TargetMachineCtorFn;
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     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
111     /// if registered.
112     AsmPrinterCtorTy AsmPrinterCtorFn;
113
114     /// MCDisassemblerCtorFn - Construction function for this target's
115     /// MCDisassembler, if registered.
116     MCDisassemblerCtorTy MCDisassemblerCtorFn;
117
118     /// MCInstPrinterCtorFn - Construction function for this target's
119     /// MCInstPrinter, if registered.
120     MCInstPrinterCtorTy MCInstPrinterCtorFn;
121
122     /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
123     /// if registered.
124     CodeEmitterCtorTy CodeEmitterCtorFn;
125
126   public:
127     /// @name Target Information
128     /// @{
129
130     // getNext - Return the next registered target.
131     const Target *getNext() const { return Next; }
132
133     /// getName - Get the target name.
134     const char *getName() const { return Name; }
135
136     /// getShortDescription - Get a short description of the target.
137     const char *getShortDescription() const { return ShortDesc; }
138
139     /// @}
140     /// @name Feature Predicates
141     /// @{
142
143     /// hasJIT - Check if this targets supports the just-in-time compilation.
144     bool hasJIT() const { return HasJIT; }
145
146     /// hasTargetMachine - Check if this target supports code generation.
147     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
148
149     /// hasAsmLexer - Check if this target supports .s lexing.
150     bool hasAsmLexer() const { return AsmLexerCtorFn != 0; }
151
152     /// hasAsmParser - Check if this target supports .s parsing.
153     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
154
155     /// hasAsmPrinter - Check if this target supports .s printing.
156     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
157
158     /// hasMCDisassembler - Check if this target has a disassembler.
159     bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
160
161     /// hasMCInstPrinter - Check if this target has an instruction printer.
162     bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
163
164     /// hasCodeEmitter - Check if this target supports instruction encoding.
165     bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
166
167     /// @}
168     /// @name Feature Constructors
169     /// @{
170
171     /// createAsmInfo - Create a MCAsmInfo implementation for the specified
172     /// target triple.
173     ///
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 {
179       if (!AsmInfoCtorFn)
180         return 0;
181       return AsmInfoCtorFn(*this, Triple);
182     }
183
184     /// createTargetMachine - Create a target specific machine implementation
185     /// for the specified \arg Triple.
186     ///
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)
194         return 0;
195       return TargetMachineCtorFn(*this, Triple, Features);
196     }
197
198     /// createAsmLexer - Create a target specific assembly lexer.
199     ///
200     TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const {
201       if (!AsmLexerCtorFn)
202         return 0;
203       return AsmLexerCtorFn(*this, MAI);
204     }
205
206     /// createAsmParser - Create a target specific assembly parser.
207     ///
208     /// \arg Parser - The target independent parser implementation to use for
209     /// parsing and lexing.
210     TargetAsmParser *createAsmParser(MCAsmParser &Parser) const {
211       if (!AsmParserCtorFn)
212         return 0;
213       return AsmParserCtorFn(*this, Parser);
214     }
215
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)
222         return 0;
223       return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI);
224     }
225
226     const MCDisassembler *createMCDisassembler() const {
227       if (!MCDisassemblerCtorFn)
228         return 0;
229       return MCDisassemblerCtorFn(*this);
230     }
231
232     MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
233                                        const MCAsmInfo &MAI,
234                                        raw_ostream &O) const {
235       if (!MCInstPrinterCtorFn)
236         return 0;
237       return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, O);
238     }
239
240
241     /// createCodeEmitter - Create a target specific code emitter.
242     MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const {
243       if (!CodeEmitterCtorFn)
244         return 0;
245       return CodeEmitterCtorFn(*this, TM, Ctx);
246     }
247
248     /// @}
249   };
250
251   /// TargetRegistry - Generic interface to target specific features.
252   struct TargetRegistry {
253     class iterator {
254       const Target *Current;
255       explicit iterator(Target *T) : Current(T) {}
256       friend struct TargetRegistry;
257     public:
258       iterator(const iterator &I) : Current(I.Current) {}
259       iterator() : Current(0) {}
260
261       bool operator==(const iterator &x) const {
262         return Current == x.Current;
263       }
264       bool operator!=(const iterator &x) const {
265         return !operator==(x);
266       }
267
268       // Iterator traversal: forward iteration only
269       iterator &operator++() {          // Preincrement
270         assert(Current && "Cannot increment end iterator!");
271         Current = Current->getNext();
272         return *this;
273       }
274       iterator operator++(int) {        // Postincrement
275         iterator tmp = *this;
276         ++*this;
277         return tmp;
278       }
279
280       const Target &operator*() const {
281         assert(Current && "Cannot dereference end iterator!");
282         return *Current;
283       }
284
285       const Target *operator->() const {
286         return &operator*();
287       }
288     };
289
290     /// @name Registry Access
291     /// @{
292
293     static iterator begin();
294
295     static iterator end() { return iterator(); }
296
297     /// lookupTarget - Lookup a target based on a target triple.
298     ///
299     /// \param Triple - The triple to use for finding a target.
300     /// \param Error - On failure, an error string describing why no target was
301     /// found.
302     static const Target *lookupTarget(const std::string &Triple,
303                                       std::string &Error);
304
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.
308     ///
309     /// Maintained for compatibility through 2.6.
310     static const Target *getClosestTargetForJIT(std::string &Error);
311
312     /// @}
313     /// @name Target Registration
314     /// @{
315
316     /// RegisterTarget - Register the given target. Attempts to register a
317     /// target which has already been registered will be ignored.
318     ///
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.
322     ///
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
326     /// string.
327     /// @param TQualityFn - The triple match quality computation function for
328     /// this target.
329     /// @param HasJIT - Whether the target supports JIT code
330     /// generation.
331     static void RegisterTarget(Target &T,
332                                const char *Name,
333                                const char *ShortDesc,
334                                Target::TripleMatchQualityFnTy TQualityFn,
335                                bool HasJIT = false);
336
337     /// RegisterAsmInfo - Register a MCAsmInfo 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 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;
350     }
351
352     /// RegisterTargetMachine - Register a TargetMachine implementation for the
353     /// given target.
354     ///
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.
358     ///
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;
366     }
367
368     /// RegisterAsmLexer - Register a TargetAsmLexer 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 AsmLexer for the target.
377     static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) {
378       if (!T.AsmLexerCtorFn)
379         T.AsmLexerCtorFn = Fn;
380     }
381
382     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
383     /// 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 AsmParser for the target.
391     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
392       if (!T.AsmParserCtorFn)
393         T.AsmParserCtorFn = Fn;
394     }
395
396     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
397     /// target.
398     ///
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.
402     ///
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;
409     }
410
411     /// RegisterMCDisassembler - Register a MCDisassembler implementation for
412     /// the given target.
413     ///
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.
417     ///
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;
424     }
425
426     /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
427     /// given target.
428     ///
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.
432     ///
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;
439     }
440
441     /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
442     /// given target.
443     ///
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.
447     ///
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;
453     }
454
455     /// @}
456   };
457
458
459   //===--------------------------------------------------------------------===//
460
461   /// RegisterTarget - Helper template for registering a target, for use in the
462   /// target's initialization function. Usage:
463   ///
464   ///
465   /// Target TheFooTarget; // The global target instance.
466   ///
467   /// extern "C" void LLVMInitializeFooTargetInfo() {
468   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
469   /// }
470   template<Triple::ArchType TargetArchType = Triple::InvalidArch,
471            bool HasJIT = false>
472   struct RegisterTarget {
473     RegisterTarget(Target &T, const char *Name, const char *Desc) {
474       TargetRegistry::RegisterTarget(T, Name, Desc,
475                                      &getTripleMatchQuality,
476                                      HasJIT);
477     }
478
479     static unsigned getTripleMatchQuality(const std::string &TT) {
480       if (Triple(TT).getArch() == TargetArchType)
481         return 20;
482       return 0;
483     }
484   };
485
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:
489   ///
490   /// extern "C" void LLVMInitializeFooTarget() {
491   ///   extern Target TheFooTarget;
492   ///   RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget);
493   /// }
494   template<class MCAsmInfoImpl>
495   struct RegisterAsmInfo {
496     RegisterAsmInfo(Target &T) {
497       TargetRegistry::RegisterAsmInfo(T, &Allocator);
498     }
499   private:
500     static const MCAsmInfo *Allocator(const Target &T, StringRef TT) {
501       return new MCAsmInfoImpl(T, TT);
502     }
503
504   };
505
506   /// RegisterAsmInfoFn - Helper template for registering a target assembly info
507   /// implementation.  This invokes the specified function to do the
508   /// construction.  Usage:
509   ///
510   /// extern "C" void LLVMInitializeFooTarget() {
511   ///   extern Target TheFooTarget;
512   ///   RegisterAsmInfoFn X(TheFooTarget, TheFunction);
513   /// }
514   struct RegisterAsmInfoFn {
515     RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) {
516       TargetRegistry::RegisterAsmInfo(T, Fn);
517     }
518   };
519
520
521   /// RegisterTargetMachine - Helper template for registering a target machine
522   /// implementation, for use in the target machine initialization
523   /// function. Usage:
524   ///
525   /// extern "C" void LLVMInitializeFooTarget() {
526   ///   extern Target TheFooTarget;
527   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
528   /// }
529   template<class TargetMachineImpl>
530   struct RegisterTargetMachine {
531     RegisterTargetMachine(Target &T) {
532       TargetRegistry::RegisterTargetMachine(T, &Allocator);
533     }
534
535   private:
536     static TargetMachine *Allocator(const Target &T, const std::string &TT,
537                                     const std::string &FS) {
538       return new TargetMachineImpl(T, TT, FS);
539     }
540   };
541
542   /// RegisterAsmLexer - Helper template for registering a target specific
543   /// assembly lexer, for use in the target machine initialization
544   /// function. Usage:
545   ///
546   /// extern "C" void LLVMInitializeFooAsmLexer() {
547   ///   extern Target TheFooTarget;
548   ///   RegisterAsmLexer<FooAsmLexer> X(TheFooTarget);
549   /// }
550   template<class AsmLexerImpl>
551   struct RegisterAsmLexer {
552     RegisterAsmLexer(Target &T) {
553       TargetRegistry::RegisterAsmLexer(T, &Allocator);
554     }
555
556   private:
557     static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) {
558       return new AsmLexerImpl(T, MAI);
559     }
560   };
561
562   /// RegisterAsmParser - Helper template for registering a target specific
563   /// assembly parser, for use in the target machine initialization
564   /// function. Usage:
565   ///
566   /// extern "C" void LLVMInitializeFooAsmParser() {
567   ///   extern Target TheFooTarget;
568   ///   RegisterAsmParser<FooAsmParser> X(TheFooTarget);
569   /// }
570   template<class AsmParserImpl>
571   struct RegisterAsmParser {
572     RegisterAsmParser(Target &T) {
573       TargetRegistry::RegisterAsmParser(T, &Allocator);
574     }
575
576   private:
577     static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P) {
578       return new AsmParserImpl(T, P);
579     }
580   };
581
582   /// RegisterAsmPrinter - Helper template for registering a target specific
583   /// assembly printer, for use in the target machine initialization
584   /// function. Usage:
585   ///
586   /// extern "C" void LLVMInitializeFooAsmPrinter() {
587   ///   extern Target TheFooTarget;
588   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
589   /// }
590   template<class AsmPrinterImpl>
591   struct RegisterAsmPrinter {
592     RegisterAsmPrinter(Target &T) {
593       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
594     }
595
596   private:
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);
601     }
602   };
603
604   /// RegisterCodeEmitter - Helper template for registering a target specific
605   /// machine code emitter, for use in the target initialization
606   /// function. Usage:
607   ///
608   /// extern "C" void LLVMInitializeFooCodeEmitter() {
609   ///   extern Target TheFooTarget;
610   ///   RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget);
611   /// }
612   template<class CodeEmitterImpl>
613   struct RegisterCodeEmitter {
614     RegisterCodeEmitter(Target &T) {
615       TargetRegistry::RegisterCodeEmitter(T, &Allocator);
616     }
617
618   private:
619     static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
620                                     MCContext &Ctx) {
621       return new CodeEmitterImpl(T, TM, Ctx);
622     }
623   };
624
625 }
626
627 #endif