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