Sketch support for target specific assembly parser.
[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 <string>
23 #include <cassert>
24
25 namespace llvm {
26   class FunctionPass;
27   class Module;
28   class TargetAsmParser;
29   class TargetMachine;
30   class formatted_raw_ostream;
31
32   /// Target - Wrapper for Target specific information.
33   ///
34   /// For registration purposes, this is a POD type so that targets can be
35   /// registered without the use of static constructors.
36   ///
37   /// Targets should implement a single global instance of this class (which
38   /// will be zero initialized), and pass that instance to the TargetRegistry as
39   /// part of their initialization.
40   class Target {
41   private:
42     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
43     typedef unsigned (*ModuleMatchQualityFnTy)(const Module &M);
44     typedef unsigned (*JITMatchQualityFnTy)();
45
46     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &,
47                                                   const Module &, 
48                                                   const std::string &);
49     typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
50                                               TargetMachine &,
51                                               bool);
52     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &);
53
54     friend struct TargetRegistry;
55
56     /// Next - The next registered target in the linked list, maintained by the
57     /// TargetRegistry.
58     Target *Next;
59
60     /// TripleMatchQualityFn - The target function for rating the match quality
61     /// of a triple.
62     TripleMatchQualityFnTy TripleMatchQualityFn;
63
64     /// ModuleMatchQualityFn - The target function for rating the match quality
65     /// of a module.
66     ModuleMatchQualityFnTy ModuleMatchQualityFn;
67
68     /// JITMatchQualityFn - The target function for rating the match quality
69     /// with the host.
70     JITMatchQualityFnTy JITMatchQualityFn;
71
72     /// Name - The target name.
73     const char *Name;
74
75     /// ShortDesc - A short description of the target.
76     const char *ShortDesc;
77
78     /// TargetMachineCtorFn - Construction function for this target's
79     /// TargetMachine, if registered.
80     TargetMachineCtorTy TargetMachineCtorFn;
81
82     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
83     /// if registered.
84     AsmPrinterCtorTy AsmPrinterCtorFn;
85
86     /// AsmParserCtorFn - Construction function for this target's AsmParser,
87     /// if registered.
88     AsmParserCtorTy AsmParserCtorFn;
89
90   public:
91     // getNext - Return the next registered target.
92     const Target *getNext() const { return Next; }
93
94     /// getName - Get the target name.
95     const char *getName() const { return Name; }
96
97     /// getShortDescription - Get a short description of the target.
98     const char *getShortDescription() const { return ShortDesc; }
99
100     /// getJITMatchQuality - Get the quality of this targets match for use as a
101     /// JIT.
102     unsigned getJITMatchQuality() const { return JITMatchQualityFn(); }
103
104     /// hasTargetMachine - Check if this target supports code generation.
105     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
106
107     /// hasAsmPrinter - Check if this target supports .s printing.
108     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
109
110     /// hasAsmParser - Check if this target supports .s parsing.
111     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
112
113     /// createTargetMachine - Create a target specific machine implementation.
114     TargetMachine *createTargetMachine(const Module &M,
115                                        const std::string &Features) const {
116       if (!TargetMachineCtorFn)
117         return 0;
118       return TargetMachineCtorFn(*this, M, Features);
119     }
120
121     /// createAsmPrinter - Create a target specific assembly printer pass.
122     FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
123                                    TargetMachine &M,
124                                    bool Verbose) const {
125       if (!AsmPrinterCtorFn)
126         return 0;
127       return AsmPrinterCtorFn(OS, M, Verbose);
128     }
129
130     /// createAsmParser - Create a target specific assembly parser.
131     TargetAsmParser *createAsmParser() const {
132       if (!AsmParserCtorFn)
133         return 0;
134       return AsmParserCtorFn(*this);
135     }
136   };
137
138   /// TargetRegistry - Generic interface to target specific features.
139   //
140   // FIXME: Provide Target* iterator.
141   struct TargetRegistry {
142     class iterator {
143       const Target *Current;
144       explicit iterator(Target *T) : Current(T) {}
145       friend class TargetRegistry;
146     public:
147       iterator(const iterator &I) : Current(I.Current) {}
148       iterator() : Current(0) {}
149
150       bool operator==(const iterator &x) const {
151         return Current == x.Current;
152       }
153       bool operator!=(const iterator &x) const {
154         return !operator==(x);
155       }
156
157       // Iterator traversal: forward iteration only
158       iterator &operator++() {          // Preincrement
159         assert(Current && "Cannot increment end iterator!");
160         Current = Current->getNext();
161         return *this;
162       }
163       iterator operator++(int) {        // Postincrement
164         iterator tmp = *this; 
165         ++*this; 
166         return tmp;
167       }
168
169       const Target &operator*() const {
170         assert(Current && "Cannot dereference end iterator!");
171         return *Current;
172       }
173
174       const Target *operator->() const {
175         return &operator*();
176       }
177     };
178
179     /// @name Registry Access
180     /// @{
181
182     static iterator begin();
183
184     static iterator end() { return iterator(); }
185
186     /// getClosestStaticTargetForTriple - Given a target triple, pick the most
187     /// capable target for that triple.
188     static const Target *getClosestStaticTargetForTriple(const std::string &TT,
189                                                          std::string &Error);
190
191     /// getClosestStaticTargetForModule - Given an LLVM module, pick the best
192     /// target that is compatible with the module.  If no close target can be
193     /// found, this returns null and sets the Error string to a reason.
194     static const Target *getClosestStaticTargetForModule(const Module &M,
195                                                         std::string &Error);
196
197     /// getClosestTargetForJIT - Pick the best target that is compatible with
198     /// the current host.  If no close target can be found, this returns null
199     /// and sets the Error string to a reason.
200     //
201     // FIXME: Do we still need this interface, clients can always look for the
202     // match for the host triple.
203     static const Target *getClosestTargetForJIT(std::string &Error);
204
205     /// @}
206     /// @name Target Registration
207     /// @{
208
209     /// RegisterTarget - Register the given target. Attempts to register a
210     /// target which has already been registered will be ignored.
211     /// 
212     /// Clients are responsible for ensuring that registration doesn't occur
213     /// while another thread is attempting to access the registry. Typically
214     /// this is done by initializing all targets at program startup.
215     ///
216     /// @param T - The target being registered.
217     /// @param Name - The target name. This should be a static string.
218     /// @param ShortDesc - A short target description. This should be a static
219     /// string. 
220     /// @param TQualityFn - The triple match quality computation function for
221     /// this target.
222     /// @param MQualityFn - The module match quality computation function for
223     /// this target.
224     /// @param JITMatchQualityFn - The JIT match quality computation function
225     /// for this target.
226     static void RegisterTarget(Target &T,
227                                const char *Name,
228                                const char *ShortDesc,
229                                Target::TripleMatchQualityFnTy TQualityFn,
230                                Target::ModuleMatchQualityFnTy MQualityFn,
231                                Target::JITMatchQualityFnTy JITQualityFn);
232                                
233     /// RegisterTargetMachine - Register a TargetMachine implementation for the
234     /// given target.
235     /// 
236     /// Clients are responsible for ensuring that registration doesn't occur
237     /// while another thread is attempting to access the registry. Typically
238     /// this is done by initializing all targets at program startup.
239     /// 
240     /// @param T - The target being registered.
241     /// @param Fn - A function to construct a TargetMachine for the target.
242     static void RegisterTargetMachine(Target &T, 
243                                       Target::TargetMachineCtorTy Fn) {
244       // Ignore duplicate registration.
245       if (!T.TargetMachineCtorFn)
246         T.TargetMachineCtorFn = Fn;
247     }
248
249     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
250     /// target.
251     /// 
252     /// Clients are responsible for ensuring that registration doesn't occur
253     /// while another thread is attempting to access the registry. Typically
254     /// this is done by initializing all targets at program startup.
255     ///
256     /// @param T - The target being registered.
257     /// @param Fn - A function to construct an AsmPrinter for the target.
258     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
259       // Ignore duplicate registration.
260       if (!T.AsmPrinterCtorFn)
261         T.AsmPrinterCtorFn = Fn;
262     }
263
264     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
265     /// given target.
266     /// 
267     /// Clients are responsible for ensuring that registration doesn't occur
268     /// while another thread is attempting to access the registry. Typically
269     /// this is done by initializing all targets at program startup.
270     ///
271     /// @param T - The target being registered.
272     /// @param Fn - A function to construct an AsmPrinter for the target.
273     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
274       if (!T.AsmParserCtorFn)
275         T.AsmParserCtorFn = Fn;
276     }
277
278     /// @}
279   };
280
281 }
282
283 #endif