pass the TargetTriple down from each target ctor to the
[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 // FIXME: We shouldn't need this header, but we need it until there is a
24 // different interface to get the TargetAsmInfo.
25 #include "llvm/Target/TargetMachine.h"
26 #include <string>
27 #include <cassert>
28
29 namespace llvm {
30   class FunctionPass;
31   class MCAsmParser;
32   class Module;
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   private:
47     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
48
49     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &,
50                                                   const std::string &,
51                                                   const std::string &);
52     typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
53                                               TargetMachine &,
54                                               bool);
55     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &,
56                                                 MCAsmParser &);
57
58     friend struct TargetRegistry;
59
60     /// Next - The next registered target in the linked list, maintained by the
61     /// TargetRegistry.
62     Target *Next;
63
64     /// TripleMatchQualityFn - The target function for rating the match quality
65     /// of a triple.
66     TripleMatchQualityFnTy TripleMatchQualityFn;
67
68     /// Name - The target name.
69     const char *Name;
70
71     /// ShortDesc - A short description of the target.
72     const char *ShortDesc;
73
74     /// HasJIT - Whether this target supports the JIT.
75     bool HasJIT;
76
77     /// TargetMachineCtorFn - Construction function for this target's
78     /// TargetMachine, if registered.
79     TargetMachineCtorTy TargetMachineCtorFn;
80
81     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
82     /// if registered.
83     AsmPrinterCtorTy AsmPrinterCtorFn;
84
85     /// AsmParserCtorFn - Construction function for this target's AsmParser,
86     /// if registered.
87     AsmParserCtorTy AsmParserCtorFn;
88
89   public:
90     // getNext - Return the next registered target.
91     const Target *getNext() const { return Next; }
92
93     /// getName - Get the target name.
94     const char *getName() const { return Name; }
95
96     /// getShortDescription - Get a short description of the target.
97     const char *getShortDescription() const { return ShortDesc; }
98
99     bool hasJIT() const { return HasJIT; }
100
101     /// hasTargetMachine - Check if this target supports code generation.
102     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
103
104     /// hasAsmPrinter - Check if this target supports .s printing.
105     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
106
107     /// hasAsmParser - Check if this target supports .s parsing.
108     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
109
110     /// createTargetMachine - Create a target specific machine implementation
111     /// for the module \arg M and \arg Triple.
112     ///
113     /// \arg M - This argument is used for some machines to access the target
114     /// data.
115     /// \arg Triple - This argument is used to determine the target machine
116     /// feature set; it should always be provided. Generally this should be
117     /// either the target triple from the module, or the target triple of the
118     /// host if that does not exist.
119     TargetMachine *createTargetMachine(const std::string &Triple,
120                                        const std::string &Features) const {
121       if (!TargetMachineCtorFn)
122         return 0;
123       return TargetMachineCtorFn(*this, Triple, Features);
124     }
125
126     /// createAsmPrinter - Create a target specific assembly printer pass.
127     FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
128                                    TargetMachine &M,
129                                    bool Verbose) const {
130       if (!AsmPrinterCtorFn)
131         return 0;
132       return AsmPrinterCtorFn(OS, M, Verbose);
133     }
134
135     /// createAsmParser - Create a target specific assembly parser.
136     ///
137     /// \arg Parser - The target independent parser implementation to use for
138     /// parsing and lexing.
139     TargetAsmParser *createAsmParser(MCAsmParser &Parser) const {
140       if (!AsmParserCtorFn)
141         return 0;
142       return AsmParserCtorFn(*this, Parser);
143     }
144   };
145
146   /// TargetRegistry - Generic interface to target specific features.
147   struct TargetRegistry {
148     class iterator {
149       const Target *Current;
150       explicit iterator(Target *T) : Current(T) {}
151       friend struct TargetRegistry;
152     public:
153       iterator(const iterator &I) : Current(I.Current) {}
154       iterator() : Current(0) {}
155
156       bool operator==(const iterator &x) const {
157         return Current == x.Current;
158       }
159       bool operator!=(const iterator &x) const {
160         return !operator==(x);
161       }
162
163       // Iterator traversal: forward iteration only
164       iterator &operator++() {          // Preincrement
165         assert(Current && "Cannot increment end iterator!");
166         Current = Current->getNext();
167         return *this;
168       }
169       iterator operator++(int) {        // Postincrement
170         iterator tmp = *this; 
171         ++*this; 
172         return tmp;
173       }
174
175       const Target &operator*() const {
176         assert(Current && "Cannot dereference end iterator!");
177         return *Current;
178       }
179
180       const Target *operator->() const {
181         return &operator*();
182       }
183     };
184
185     /// @name Registry Access
186     /// @{
187
188     static iterator begin();
189
190     static iterator end() { return iterator(); }
191
192     /// lookupTarget - Lookup a target based on a target triple.
193     ///
194     /// \param Triple - The triple to use for finding a target.
195     /// \param Error - On failure, an error string describing why no target was
196     /// found.
197     static const Target *lookupTarget(const std::string &Triple,
198                                       std::string &Error);
199
200     /// getClosestTargetForJIT - Pick the best target that is compatible with
201     /// the current host.  If no close target can be found, this returns null
202     /// and sets the Error string to a reason.
203     ///
204     /// Mainted for compatibility through 2.6.
205     static const Target *getClosestTargetForJIT(std::string &Error);
206
207     /// @}
208     /// @name Target Registration
209     /// @{
210
211     /// RegisterTarget - Register the given target. Attempts to register a
212     /// target which has already been registered will be ignored.
213     /// 
214     /// Clients are responsible for ensuring that registration doesn't occur
215     /// while another thread is attempting to access the registry. Typically
216     /// this is done by initializing all targets at program startup.
217     ///
218     /// @param T - The target being registered.
219     /// @param Name - The target name. This should be a static string.
220     /// @param ShortDesc - A short target description. This should be a static
221     /// string. 
222     /// @param TQualityFn - The triple match quality computation function for
223     /// this target.
224     /// @param HasJIT - Whether the target supports JIT code
225     /// generation.
226     static void RegisterTarget(Target &T,
227                                const char *Name,
228                                const char *ShortDesc,
229                                Target::TripleMatchQualityFnTy TQualityFn,
230                                bool HasJIT = false);
231                                
232     /// RegisterTargetMachine - Register a TargetMachine implementation for the
233     /// given target.
234     /// 
235     /// Clients are responsible for ensuring that registration doesn't occur
236     /// while another thread is attempting to access the registry. Typically
237     /// this is done by initializing all targets at program startup.
238     /// 
239     /// @param T - The target being registered.
240     /// @param Fn - A function to construct a TargetMachine for the target.
241     static void RegisterTargetMachine(Target &T, 
242                                       Target::TargetMachineCtorTy Fn) {
243       // Ignore duplicate registration.
244       if (!T.TargetMachineCtorFn)
245         T.TargetMachineCtorFn = Fn;
246     }
247
248     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
249     /// target.
250     /// 
251     /// Clients are responsible for ensuring that registration doesn't occur
252     /// while another thread is attempting to access the registry. Typically
253     /// this is done by initializing all targets at program startup.
254     ///
255     /// @param T - The target being registered.
256     /// @param Fn - A function to construct an AsmPrinter for the target.
257     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
258       // Ignore duplicate registration.
259       if (!T.AsmPrinterCtorFn)
260         T.AsmPrinterCtorFn = Fn;
261     }
262
263     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
264     /// given target.
265     /// 
266     /// Clients are responsible for ensuring that registration doesn't occur
267     /// while another thread is attempting to access the registry. Typically
268     /// this is done by initializing all targets at program startup.
269     ///
270     /// @param T - The target being registered.
271     /// @param Fn - A function to construct an AsmPrinter for the target.
272     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
273       if (!T.AsmParserCtorFn)
274         T.AsmParserCtorFn = Fn;
275     }
276
277     /// @}
278   };
279
280
281   //===--------------------------------------------------------------------===//
282
283   /// RegisterTarget - Helper template for registering a target, for use in the
284   /// target's initialization function. Usage:
285   ///
286   ///
287   /// Target TheFooTarget; // The global target instance.
288   ///
289   /// extern "C" void LLVMInitializeFooTargetInfo() {
290   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
291   /// }
292   template<Triple::ArchType TargetArchType = Triple::InvalidArch,
293            bool HasJIT = false>
294   struct RegisterTarget {
295     RegisterTarget(Target &T, const char *Name, const char *Desc) {
296       TargetRegistry::RegisterTarget(T, Name, Desc,
297                                      &getTripleMatchQuality,
298                                      HasJIT);
299     }
300
301     static unsigned getTripleMatchQuality(const std::string &TT) {
302       if (Triple(TT.c_str()).getArch() == TargetArchType)
303         return 20;
304       return 0;
305     }
306   };
307
308   /// RegisterTargetMachine - Helper template for registering a target machine
309   /// implementation, for use in the target machine initialization
310   /// function. Usage:
311   ///
312   /// extern "C" void LLVMInitializeFooTarget() {
313   ///   extern Target TheFooTarget;
314   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
315   /// }
316   template<class TargetMachineImpl>
317   struct RegisterTargetMachine {
318     RegisterTargetMachine(Target &T) {
319       TargetRegistry::RegisterTargetMachine(T, &Allocator);
320     }
321
322   private:
323     static TargetMachine *Allocator(const Target &T, const std::string &TT,
324                                     const std::string &FS) {
325       return new TargetMachineImpl(T, TT, FS);
326     }
327   };
328
329   /// RegisterAsmPrinter - Helper template for registering a target specific
330   /// assembly printer, for use in the target machine initialization
331   /// function. Usage:
332   ///
333   /// extern "C" void LLVMInitializeFooAsmPrinter() {
334   ///   extern Target TheFooTarget;
335   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
336   /// }
337   template<class AsmPrinterImpl>
338   struct RegisterAsmPrinter {
339     RegisterAsmPrinter(Target &T) {
340       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
341     }
342
343   private:
344     static FunctionPass *Allocator(formatted_raw_ostream &OS,
345                                    TargetMachine &TM,
346                                    bool Verbose) {
347       return new AsmPrinterImpl(OS, TM, TM.getTargetAsmInfo(), Verbose);
348     }
349   };
350
351   /// RegisterAsmParser - Helper template for registering a target specific
352   /// assembly parser, for use in the target machine initialization
353   /// function. Usage:
354   ///
355   /// extern "C" void LLVMInitializeFooAsmParser() {
356   ///   extern Target TheFooTarget;
357   ///   RegisterAsmParser<FooAsmParser> X(TheFooTarget);
358   /// }
359   template<class AsmParserImpl>
360   struct RegisterAsmParser {
361     RegisterAsmParser(Target &T) {
362       TargetRegistry::RegisterAsmParser(T, &Allocator);
363     }
364
365   private:
366     static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P) {
367       return new AsmParserImpl(T, P);
368     }
369   };
370
371 }
372
373 #endif