1226584Sdim//===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===//
2226584Sdim//
3226584Sdim//                     The LLVM Compiler Infrastructure
4226584Sdim//
5226584Sdim// This file is distributed under the University of Illinois Open Source
6226584Sdim// License. See LICENSE.TXT for details.
7226584Sdim//
8226584Sdim//===----------------------------------------------------------------------===//
9226584Sdim//
10226584Sdim// This file exposes the TargetRegistry interface, which tools can use to access
11226584Sdim// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
12226584Sdim// which have been registered.
13226584Sdim//
14226584Sdim// Target specific class implementations should register themselves using the
15226584Sdim// appropriate TargetRegistry interfaces.
16226584Sdim//
17226584Sdim//===----------------------------------------------------------------------===//
18226584Sdim
19226584Sdim#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
20226584Sdim#define LLVM_SUPPORT_TARGETREGISTRY_H
21226584Sdim
22252723Sdim#include "llvm/ADT/Triple.h"
23226584Sdim#include "llvm/Support/CodeGen.h"
24263509Sdim#include "llvm-c/Disassembler.h"
25252723Sdim#include <cassert>
26226584Sdim#include <string>
27226584Sdim
28226584Sdimnamespace llvm {
29226584Sdim  class AsmPrinter;
30226584Sdim  class Module;
31226584Sdim  class MCAssembler;
32226584Sdim  class MCAsmBackend;
33226584Sdim  class MCAsmInfo;
34226584Sdim  class MCAsmParser;
35226584Sdim  class MCCodeEmitter;
36226584Sdim  class MCCodeGenInfo;
37226584Sdim  class MCContext;
38226584Sdim  class MCDisassembler;
39226584Sdim  class MCInstrAnalysis;
40226584Sdim  class MCInstPrinter;
41226584Sdim  class MCInstrInfo;
42226584Sdim  class MCRegisterInfo;
43226584Sdim  class MCStreamer;
44226584Sdim  class MCSubtargetInfo;
45263509Sdim  class MCSymbolizer;
46263509Sdim  class MCRelocationInfo;
47226584Sdim  class MCTargetAsmParser;
48226584Sdim  class TargetMachine;
49263509Sdim  class MCTargetStreamer;
50235633Sdim  class TargetOptions;
51226584Sdim  class raw_ostream;
52226584Sdim  class formatted_raw_ostream;
53226584Sdim
54263509Sdim  MCStreamer *createAsmStreamer(MCContext &Ctx,
55263509Sdim                                MCTargetStreamer *TargetStreamer,
56263509Sdim                                formatted_raw_ostream &OS, bool isVerboseAsm,
57226584Sdim                                bool useLoc, bool useCFI,
58235633Sdim                                bool useDwarfDirectory,
59263509Sdim                                MCInstPrinter *InstPrint, MCCodeEmitter *CE,
60263509Sdim                                MCAsmBackend *TAB, bool ShowInst);
61226584Sdim
62263509Sdim  MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
63263509Sdim
64263509Sdim  MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
65263509Sdim                                   LLVMSymbolLookupCallback SymbolLookUp,
66263509Sdim                                   void *DisInfo,
67263509Sdim                                   MCContext *Ctx,
68263509Sdim                                   MCRelocationInfo *RelInfo);
69263509Sdim
70226584Sdim  /// Target - Wrapper for Target specific information.
71226584Sdim  ///
72226584Sdim  /// For registration purposes, this is a POD type so that targets can be
73226584Sdim  /// registered without the use of static constructors.
74226584Sdim  ///
75226584Sdim  /// Targets should implement a single global instance of this class (which
76226584Sdim  /// will be zero initialized), and pass that instance to the TargetRegistry as
77226584Sdim  /// part of their initialization.
78226584Sdim  class Target {
79226584Sdim  public:
80226584Sdim    friend struct TargetRegistry;
81226584Sdim
82226584Sdim    typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
83226584Sdim
84263509Sdim    typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
85226584Sdim                                            StringRef TT);
86226584Sdim    typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
87226584Sdim                                                    Reloc::Model RM,
88235633Sdim                                                    CodeModel::Model CM,
89235633Sdim                                                    CodeGenOpt::Level OL);
90226584Sdim    typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
91226584Sdim    typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
92226584Sdim    typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
93226584Sdim    typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
94226584Sdim                                                        StringRef CPU,
95226584Sdim                                                        StringRef Features);
96226584Sdim    typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
97226584Sdim                                                  StringRef TT,
98226584Sdim                                                  StringRef CPU,
99226584Sdim                                                  StringRef Features,
100235633Sdim                                                  const TargetOptions &Options,
101226584Sdim                                                  Reloc::Model RM,
102235633Sdim                                                  CodeModel::Model CM,
103235633Sdim                                                  CodeGenOpt::Level OL);
104226584Sdim    typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
105226584Sdim                                            MCStreamer &Streamer);
106241506Sdim    typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
107263509Sdim                                                const MCRegisterInfo &MRI,
108241506Sdim                                                StringRef TT,
109241506Sdim                                                StringRef CPU);
110226584Sdim    typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
111263509Sdim                                                    MCAsmParser &P,
112263509Sdim                                                    const MCInstrInfo &MII);
113226584Sdim    typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
114226584Sdim                                                    const MCSubtargetInfo &STI);
115226584Sdim    typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
116226584Sdim                                                  unsigned SyntaxVariant,
117226584Sdim                                                  const MCAsmInfo &MAI,
118235633Sdim                                                  const MCInstrInfo &MII,
119235633Sdim                                                  const MCRegisterInfo &MRI,
120226584Sdim                                                  const MCSubtargetInfo &STI);
121226584Sdim    typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
122245431Sdim                                                  const MCRegisterInfo &MRI,
123226584Sdim                                                  const MCSubtargetInfo &STI,
124226584Sdim                                                  MCContext &Ctx);
125226584Sdim    typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
126226584Sdim                                                  StringRef TT,
127226584Sdim                                                  MCContext &Ctx,
128226584Sdim                                                  MCAsmBackend &TAB,
129226584Sdim                                                  raw_ostream &_OS,
130226584Sdim                                                  MCCodeEmitter *_Emitter,
131226584Sdim                                                  bool RelaxAll,
132226584Sdim                                                  bool NoExecStack);
133226584Sdim    typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
134226584Sdim                                             formatted_raw_ostream &OS,
135226584Sdim                                             bool isVerboseAsm,
136226584Sdim                                             bool useLoc,
137226584Sdim                                             bool useCFI,
138235633Sdim                                             bool useDwarfDirectory,
139226584Sdim                                             MCInstPrinter *InstPrint,
140226584Sdim                                             MCCodeEmitter *CE,
141226584Sdim                                             MCAsmBackend *TAB,
142226584Sdim                                             bool ShowInst);
143263509Sdim    typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
144263509Sdim                                                        MCContext &Ctx);
145263509Sdim    typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT,
146263509Sdim                                   LLVMOpInfoCallback GetOpInfo,
147263509Sdim                                   LLVMSymbolLookupCallback SymbolLookUp,
148263509Sdim                                   void *DisInfo,
149263509Sdim                                   MCContext *Ctx,
150263509Sdim                                   MCRelocationInfo *RelInfo);
151226584Sdim
152226584Sdim  private:
153226584Sdim    /// Next - The next registered target in the linked list, maintained by the
154226584Sdim    /// TargetRegistry.
155226584Sdim    Target *Next;
156226584Sdim
157226584Sdim    /// TripleMatchQualityFn - The target function for rating the match quality
158226584Sdim    /// of a triple.
159226584Sdim    TripleMatchQualityFnTy TripleMatchQualityFn;
160226584Sdim
161226584Sdim    /// Name - The target name.
162226584Sdim    const char *Name;
163226584Sdim
164226584Sdim    /// ShortDesc - A short description of the target.
165226584Sdim    const char *ShortDesc;
166226584Sdim
167226584Sdim    /// HasJIT - Whether this target supports the JIT.
168226584Sdim    bool HasJIT;
169226584Sdim
170226584Sdim    /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
171226584Sdim    /// registered.
172226584Sdim    MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
173226584Sdim
174235633Sdim    /// MCCodeGenInfoCtorFn - Constructor function for this target's
175235633Sdim    /// MCCodeGenInfo, if registered.
176226584Sdim    MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
177226584Sdim
178226584Sdim    /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
179226584Sdim    /// if registered.
180226584Sdim    MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
181226584Sdim
182226584Sdim    /// MCInstrAnalysisCtorFn - Constructor function for this target's
183226584Sdim    /// MCInstrAnalysis, if registered.
184226584Sdim    MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
185226584Sdim
186226584Sdim    /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
187226584Sdim    /// if registered.
188226584Sdim    MCRegInfoCtorFnTy MCRegInfoCtorFn;
189226584Sdim
190226584Sdim    /// MCSubtargetInfoCtorFn - Constructor function for this target's
191226584Sdim    /// MCSubtargetInfo, if registered.
192226584Sdim    MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
193226584Sdim
194226584Sdim    /// TargetMachineCtorFn - Construction function for this target's
195226584Sdim    /// TargetMachine, if registered.
196226584Sdim    TargetMachineCtorTy TargetMachineCtorFn;
197226584Sdim
198226584Sdim    /// MCAsmBackendCtorFn - Construction function for this target's
199226584Sdim    /// MCAsmBackend, if registered.
200226584Sdim    MCAsmBackendCtorTy MCAsmBackendCtorFn;
201226584Sdim
202226584Sdim    /// MCAsmParserCtorFn - Construction function for this target's
203226584Sdim    /// MCTargetAsmParser, if registered.
204226584Sdim    MCAsmParserCtorTy MCAsmParserCtorFn;
205226584Sdim
206226584Sdim    /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
207226584Sdim    /// if registered.
208226584Sdim    AsmPrinterCtorTy AsmPrinterCtorFn;
209226584Sdim
210226584Sdim    /// MCDisassemblerCtorFn - Construction function for this target's
211226584Sdim    /// MCDisassembler, if registered.
212226584Sdim    MCDisassemblerCtorTy MCDisassemblerCtorFn;
213226584Sdim
214226584Sdim    /// MCInstPrinterCtorFn - Construction function for this target's
215226584Sdim    /// MCInstPrinter, if registered.
216226584Sdim    MCInstPrinterCtorTy MCInstPrinterCtorFn;
217226584Sdim
218226584Sdim    /// MCCodeEmitterCtorFn - Construction function for this target's
219226584Sdim    /// CodeEmitter, if registered.
220226584Sdim    MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
221226584Sdim
222226584Sdim    /// MCObjectStreamerCtorFn - Construction function for this target's
223226584Sdim    /// MCObjectStreamer, if registered.
224226584Sdim    MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
225226584Sdim
226226584Sdim    /// AsmStreamerCtorFn - Construction function for this target's
227226584Sdim    /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
228226584Sdim    AsmStreamerCtorTy AsmStreamerCtorFn;
229226584Sdim
230263509Sdim    /// MCRelocationInfoCtorFn - Construction function for this target's
231263509Sdim    /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
232263509Sdim    MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
233263509Sdim
234263509Sdim    /// MCSymbolizerCtorFn - Construction function for this target's
235263509Sdim    /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
236263509Sdim    MCSymbolizerCtorTy MCSymbolizerCtorFn;
237263509Sdim
238226584Sdim  public:
239263509Sdim    Target()
240263509Sdim        : AsmStreamerCtorFn(0), MCRelocationInfoCtorFn(0),
241263509Sdim          MCSymbolizerCtorFn(0) {}
242226584Sdim
243226584Sdim    /// @name Target Information
244226584Sdim    /// @{
245226584Sdim
246226584Sdim    // getNext - Return the next registered target.
247226584Sdim    const Target *getNext() const { return Next; }
248226584Sdim
249226584Sdim    /// getName - Get the target name.
250226584Sdim    const char *getName() const { return Name; }
251226584Sdim
252226584Sdim    /// getShortDescription - Get a short description of the target.
253226584Sdim    const char *getShortDescription() const { return ShortDesc; }
254226584Sdim
255226584Sdim    /// @}
256226584Sdim    /// @name Feature Predicates
257226584Sdim    /// @{
258226584Sdim
259226584Sdim    /// hasJIT - Check if this targets supports the just-in-time compilation.
260226584Sdim    bool hasJIT() const { return HasJIT; }
261226584Sdim
262226584Sdim    /// hasTargetMachine - Check if this target supports code generation.
263226584Sdim    bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
264226584Sdim
265226584Sdim    /// hasMCAsmBackend - Check if this target supports .o generation.
266226584Sdim    bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; }
267226584Sdim
268226584Sdim    /// @}
269226584Sdim    /// @name Feature Constructors
270226584Sdim    /// @{
271226584Sdim
272226584Sdim    /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
273226584Sdim    /// target triple.
274226584Sdim    ///
275245431Sdim    /// \param Triple This argument is used to determine the target machine
276226584Sdim    /// feature set; it should always be provided. Generally this should be
277226584Sdim    /// either the target triple from the module, or the target triple of the
278226584Sdim    /// host if that does not exist.
279263509Sdim    MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
280263509Sdim                               StringRef Triple) const {
281226584Sdim      if (!MCAsmInfoCtorFn)
282226584Sdim        return 0;
283263509Sdim      return MCAsmInfoCtorFn(MRI, Triple);
284226584Sdim    }
285226584Sdim
286226584Sdim    /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
287226584Sdim    ///
288226584Sdim    MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
289235633Sdim                                       CodeModel::Model CM,
290235633Sdim                                       CodeGenOpt::Level OL) const {
291226584Sdim      if (!MCCodeGenInfoCtorFn)
292226584Sdim        return 0;
293235633Sdim      return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
294226584Sdim    }
295226584Sdim
296226584Sdim    /// createMCInstrInfo - Create a MCInstrInfo implementation.
297226584Sdim    ///
298226584Sdim    MCInstrInfo *createMCInstrInfo() const {
299226584Sdim      if (!MCInstrInfoCtorFn)
300226584Sdim        return 0;
301226584Sdim      return MCInstrInfoCtorFn();
302226584Sdim    }
303226584Sdim
304226584Sdim    /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
305226584Sdim    ///
306226584Sdim    MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
307226584Sdim      if (!MCInstrAnalysisCtorFn)
308226584Sdim        return 0;
309226584Sdim      return MCInstrAnalysisCtorFn(Info);
310226584Sdim    }
311226584Sdim
312226584Sdim    /// createMCRegInfo - Create a MCRegisterInfo implementation.
313226584Sdim    ///
314226584Sdim    MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
315226584Sdim      if (!MCRegInfoCtorFn)
316226584Sdim        return 0;
317226584Sdim      return MCRegInfoCtorFn(Triple);
318226584Sdim    }
319226584Sdim
320226584Sdim    /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
321226584Sdim    ///
322245431Sdim    /// \param Triple This argument is used to determine the target machine
323226584Sdim    /// feature set; it should always be provided. Generally this should be
324226584Sdim    /// either the target triple from the module, or the target triple of the
325226584Sdim    /// host if that does not exist.
326245431Sdim    /// \param CPU This specifies the name of the target CPU.
327245431Sdim    /// \param Features This specifies the string representation of the
328226584Sdim    /// additional target features.
329226584Sdim    MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
330226584Sdim                                           StringRef Features) const {
331226584Sdim      if (!MCSubtargetInfoCtorFn)
332226584Sdim        return 0;
333226584Sdim      return MCSubtargetInfoCtorFn(Triple, CPU, Features);
334226584Sdim    }
335226584Sdim
336226584Sdim    /// createTargetMachine - Create a target specific machine implementation
337245431Sdim    /// for the specified \p Triple.
338226584Sdim    ///
339245431Sdim    /// \param Triple This argument is used to determine the target machine
340226584Sdim    /// feature set; it should always be provided. Generally this should be
341226584Sdim    /// either the target triple from the module, or the target triple of the
342226584Sdim    /// host if that does not exist.
343226584Sdim    TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
344235633Sdim                             StringRef Features, const TargetOptions &Options,
345235633Sdim                             Reloc::Model RM = Reloc::Default,
346235633Sdim                             CodeModel::Model CM = CodeModel::Default,
347235633Sdim                             CodeGenOpt::Level OL = CodeGenOpt::Default) const {
348226584Sdim      if (!TargetMachineCtorFn)
349226584Sdim        return 0;
350235633Sdim      return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
351235633Sdim                                 RM, CM, OL);
352226584Sdim    }
353226584Sdim
354226584Sdim    /// createMCAsmBackend - Create a target specific assembly parser.
355226584Sdim    ///
356245431Sdim    /// \param Triple The target triple string.
357263509Sdim    MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
358263509Sdim                                     StringRef Triple, StringRef CPU) const {
359226584Sdim      if (!MCAsmBackendCtorFn)
360226584Sdim        return 0;
361263509Sdim      return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
362226584Sdim    }
363226584Sdim
364226584Sdim    /// createMCAsmParser - Create a target specific assembly parser.
365226584Sdim    ///
366245431Sdim    /// \param Parser The target independent parser implementation to use for
367226584Sdim    /// parsing and lexing.
368226584Sdim    MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
369263509Sdim                                         MCAsmParser &Parser,
370263509Sdim                                         const MCInstrInfo &MII) const {
371226584Sdim      if (!MCAsmParserCtorFn)
372226584Sdim        return 0;
373263509Sdim      return MCAsmParserCtorFn(STI, Parser, MII);
374226584Sdim    }
375226584Sdim
376226584Sdim    /// createAsmPrinter - Create a target specific assembly printer pass.  This
377226584Sdim    /// takes ownership of the MCStreamer object.
378226584Sdim    AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
379226584Sdim      if (!AsmPrinterCtorFn)
380226584Sdim        return 0;
381226584Sdim      return AsmPrinterCtorFn(TM, Streamer);
382226584Sdim    }
383226584Sdim
384226584Sdim    MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI) const {
385226584Sdim      if (!MCDisassemblerCtorFn)
386226584Sdim        return 0;
387226584Sdim      return MCDisassemblerCtorFn(*this, STI);
388226584Sdim    }
389226584Sdim
390226584Sdim    MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
391226584Sdim                                       const MCAsmInfo &MAI,
392235633Sdim                                       const MCInstrInfo &MII,
393235633Sdim                                       const MCRegisterInfo &MRI,
394226584Sdim                                       const MCSubtargetInfo &STI) const {
395226584Sdim      if (!MCInstPrinterCtorFn)
396226584Sdim        return 0;
397235633Sdim      return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
398226584Sdim    }
399226584Sdim
400226584Sdim
401226584Sdim    /// createMCCodeEmitter - Create a target specific code emitter.
402226584Sdim    MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
403245431Sdim                                       const MCRegisterInfo &MRI,
404226584Sdim                                       const MCSubtargetInfo &STI,
405226584Sdim                                       MCContext &Ctx) const {
406226584Sdim      if (!MCCodeEmitterCtorFn)
407226584Sdim        return 0;
408245431Sdim      return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
409226584Sdim    }
410226584Sdim
411226584Sdim    /// createMCObjectStreamer - Create a target specific MCStreamer.
412226584Sdim    ///
413245431Sdim    /// \param TT The target triple.
414245431Sdim    /// \param Ctx The target context.
415245431Sdim    /// \param TAB The target assembler backend object. Takes ownership.
416245431Sdim    /// \param _OS The stream object.
417245431Sdim    /// \param _Emitter The target independent assembler object.Takes ownership.
418245431Sdim    /// \param RelaxAll Relax all fixups?
419245431Sdim    /// \param NoExecStack Mark file as not needing a executable stack.
420226584Sdim    MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
421226584Sdim                                       MCAsmBackend &TAB,
422226584Sdim                                       raw_ostream &_OS,
423226584Sdim                                       MCCodeEmitter *_Emitter,
424226584Sdim                                       bool RelaxAll,
425226584Sdim                                       bool NoExecStack) const {
426226584Sdim      if (!MCObjectStreamerCtorFn)
427226584Sdim        return 0;
428226584Sdim      return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter,
429226584Sdim                                    RelaxAll, NoExecStack);
430226584Sdim    }
431226584Sdim
432226584Sdim    /// createAsmStreamer - Create a target specific MCStreamer.
433226584Sdim    MCStreamer *createAsmStreamer(MCContext &Ctx,
434226584Sdim                                  formatted_raw_ostream &OS,
435226584Sdim                                  bool isVerboseAsm,
436226584Sdim                                  bool useLoc,
437226584Sdim                                  bool useCFI,
438235633Sdim                                  bool useDwarfDirectory,
439226584Sdim                                  MCInstPrinter *InstPrint,
440226584Sdim                                  MCCodeEmitter *CE,
441226584Sdim                                  MCAsmBackend *TAB,
442226584Sdim                                  bool ShowInst) const {
443263509Sdim      if (AsmStreamerCtorFn)
444263509Sdim        return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
445263509Sdim                                 useDwarfDirectory, InstPrint, CE, TAB,
446263509Sdim                                 ShowInst);
447263509Sdim      return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI,
448263509Sdim                                     useDwarfDirectory, InstPrint, CE, TAB,
449263509Sdim                                     ShowInst);
450226584Sdim    }
451226584Sdim
452263509Sdim    /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
453263509Sdim    ///
454263509Sdim    /// \param TT The target triple.
455263509Sdim    /// \param Ctx The target context.
456263509Sdim    MCRelocationInfo *
457263509Sdim      createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
458263509Sdim      MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
459263509Sdim                                      ? MCRelocationInfoCtorFn
460263509Sdim                                      : llvm::createMCRelocationInfo;
461263509Sdim      return Fn(TT, Ctx);
462263509Sdim    }
463263509Sdim
464263509Sdim    /// createMCSymbolizer - Create a target specific MCSymbolizer.
465263509Sdim    ///
466263509Sdim    /// \param TT The target triple.
467263509Sdim    /// \param GetOpInfo The function to get the symbolic information for operands.
468263509Sdim    /// \param SymbolLookUp The function to lookup a symbol name.
469263509Sdim    /// \param DisInfo The pointer to the block of symbolic information for above call
470263509Sdim    /// back.
471263509Sdim    /// \param Ctx The target context.
472263509Sdim    /// \param RelInfo The relocation information for this target. Takes ownership.
473263509Sdim    MCSymbolizer *
474263509Sdim    createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
475263509Sdim                       LLVMSymbolLookupCallback SymbolLookUp,
476263509Sdim                       void *DisInfo,
477263509Sdim                       MCContext *Ctx, MCRelocationInfo *RelInfo) const {
478263509Sdim      MCSymbolizerCtorTy Fn =
479263509Sdim          MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
480263509Sdim      return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo);
481263509Sdim    }
482263509Sdim
483226584Sdim    /// @}
484226584Sdim  };
485226584Sdim
486226584Sdim  /// TargetRegistry - Generic interface to target specific features.
487226584Sdim  struct TargetRegistry {
488226584Sdim    class iterator {
489226584Sdim      const Target *Current;
490226584Sdim      explicit iterator(Target *T) : Current(T) {}
491226584Sdim      friend struct TargetRegistry;
492226584Sdim    public:
493226584Sdim      iterator(const iterator &I) : Current(I.Current) {}
494226584Sdim      iterator() : Current(0) {}
495226584Sdim
496226584Sdim      bool operator==(const iterator &x) const {
497226584Sdim        return Current == x.Current;
498226584Sdim      }
499226584Sdim      bool operator!=(const iterator &x) const {
500226584Sdim        return !operator==(x);
501226584Sdim      }
502226584Sdim
503226584Sdim      // Iterator traversal: forward iteration only
504226584Sdim      iterator &operator++() {          // Preincrement
505226584Sdim        assert(Current && "Cannot increment end iterator!");
506226584Sdim        Current = Current->getNext();
507226584Sdim        return *this;
508226584Sdim      }
509226584Sdim      iterator operator++(int) {        // Postincrement
510226584Sdim        iterator tmp = *this;
511226584Sdim        ++*this;
512226584Sdim        return tmp;
513226584Sdim      }
514226584Sdim
515226584Sdim      const Target &operator*() const {
516226584Sdim        assert(Current && "Cannot dereference end iterator!");
517226584Sdim        return *Current;
518226584Sdim      }
519226584Sdim
520226584Sdim      const Target *operator->() const {
521226584Sdim        return &operator*();
522226584Sdim      }
523226584Sdim    };
524226584Sdim
525226584Sdim    /// printRegisteredTargetsForVersion - Print the registered targets
526226584Sdim    /// appropriately for inclusion in a tool's version output.
527226584Sdim    static void printRegisteredTargetsForVersion();
528226584Sdim
529226584Sdim    /// @name Registry Access
530226584Sdim    /// @{
531226584Sdim
532226584Sdim    static iterator begin();
533226584Sdim
534226584Sdim    static iterator end() { return iterator(); }
535226584Sdim
536226584Sdim    /// lookupTarget - Lookup a target based on a target triple.
537226584Sdim    ///
538226584Sdim    /// \param Triple - The triple to use for finding a target.
539226584Sdim    /// \param Error - On failure, an error string describing why no target was
540226584Sdim    /// found.
541226584Sdim    static const Target *lookupTarget(const std::string &Triple,
542226584Sdim                                      std::string &Error);
543226584Sdim
544245431Sdim    /// lookupTarget - Lookup a target based on an architecture name
545245431Sdim    /// and a target triple.  If the architecture name is non-empty,
546245431Sdim    /// then the lookup is done by architecture.  Otherwise, the target
547245431Sdim    /// triple is used.
548245431Sdim    ///
549245431Sdim    /// \param ArchName - The architecture to use for finding a target.
550245431Sdim    /// \param TheTriple - The triple to use for finding a target.  The
551245431Sdim    /// triple is updated with canonical architecture name if a lookup
552245431Sdim    /// by architecture is done.
553245431Sdim    /// \param Error - On failure, an error string describing why no target was
554245431Sdim    /// found.
555245431Sdim    static const Target *lookupTarget(const std::string &ArchName,
556245431Sdim                                      Triple &TheTriple,
557245431Sdim                                      std::string &Error);
558245431Sdim
559226584Sdim    /// getClosestTargetForJIT - Pick the best target that is compatible with
560226584Sdim    /// the current host.  If no close target can be found, this returns null
561226584Sdim    /// and sets the Error string to a reason.
562226584Sdim    ///
563226584Sdim    /// Maintained for compatibility through 2.6.
564226584Sdim    static const Target *getClosestTargetForJIT(std::string &Error);
565226584Sdim
566226584Sdim    /// @}
567226584Sdim    /// @name Target Registration
568226584Sdim    /// @{
569226584Sdim
570226584Sdim    /// RegisterTarget - Register the given target. Attempts to register a
571226584Sdim    /// target which has already been registered will be ignored.
572226584Sdim    ///
573226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
574226584Sdim    /// while another thread is attempting to access the registry. Typically
575226584Sdim    /// this is done by initializing all targets at program startup.
576226584Sdim    ///
577226584Sdim    /// @param T - The target being registered.
578226584Sdim    /// @param Name - The target name. This should be a static string.
579226584Sdim    /// @param ShortDesc - A short target description. This should be a static
580226584Sdim    /// string.
581226584Sdim    /// @param TQualityFn - The triple match quality computation function for
582226584Sdim    /// this target.
583226584Sdim    /// @param HasJIT - Whether the target supports JIT code
584226584Sdim    /// generation.
585226584Sdim    static void RegisterTarget(Target &T,
586226584Sdim                               const char *Name,
587226584Sdim                               const char *ShortDesc,
588226584Sdim                               Target::TripleMatchQualityFnTy TQualityFn,
589226584Sdim                               bool HasJIT = false);
590226584Sdim
591226584Sdim    /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
592226584Sdim    /// given target.
593226584Sdim    ///
594226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
595226584Sdim    /// while another thread is attempting to access the registry. Typically
596226584Sdim    /// this is done by initializing all targets at program startup.
597226584Sdim    ///
598226584Sdim    /// @param T - The target being registered.
599226584Sdim    /// @param Fn - A function to construct a MCAsmInfo for the target.
600226584Sdim    static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
601263509Sdim      T.MCAsmInfoCtorFn = Fn;
602226584Sdim    }
603226584Sdim
604226584Sdim    /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
605226584Sdim    /// given target.
606226584Sdim    ///
607226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
608226584Sdim    /// while another thread is attempting to access the registry. Typically
609226584Sdim    /// this is done by initializing all targets at program startup.
610226584Sdim    ///
611226584Sdim    /// @param T - The target being registered.
612226584Sdim    /// @param Fn - A function to construct a MCCodeGenInfo for the target.
613226584Sdim    static void RegisterMCCodeGenInfo(Target &T,
614226584Sdim                                     Target::MCCodeGenInfoCtorFnTy Fn) {
615263509Sdim      T.MCCodeGenInfoCtorFn = Fn;
616226584Sdim    }
617226584Sdim
618226584Sdim    /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
619226584Sdim    /// given target.
620226584Sdim    ///
621226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
622226584Sdim    /// while another thread is attempting to access the registry. Typically
623226584Sdim    /// this is done by initializing all targets at program startup.
624226584Sdim    ///
625226584Sdim    /// @param T - The target being registered.
626226584Sdim    /// @param Fn - A function to construct a MCInstrInfo for the target.
627226584Sdim    static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
628263509Sdim      T.MCInstrInfoCtorFn = Fn;
629226584Sdim    }
630226584Sdim
631226584Sdim    /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
632226584Sdim    /// the given target.
633226584Sdim    static void RegisterMCInstrAnalysis(Target &T,
634226584Sdim                                        Target::MCInstrAnalysisCtorFnTy Fn) {
635263509Sdim      T.MCInstrAnalysisCtorFn = Fn;
636226584Sdim    }
637226584Sdim
638226584Sdim    /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
639226584Sdim    /// given target.
640226584Sdim    ///
641226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
642226584Sdim    /// while another thread is attempting to access the registry. Typically
643226584Sdim    /// this is done by initializing all targets at program startup.
644226584Sdim    ///
645226584Sdim    /// @param T - The target being registered.
646226584Sdim    /// @param Fn - A function to construct a MCRegisterInfo for the target.
647226584Sdim    static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
648263509Sdim      T.MCRegInfoCtorFn = Fn;
649226584Sdim    }
650226584Sdim
651226584Sdim    /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
652226584Sdim    /// the given target.
653226584Sdim    ///
654226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
655226584Sdim    /// while another thread is attempting to access the registry. Typically
656226584Sdim    /// this is done by initializing all targets at program startup.
657226584Sdim    ///
658226584Sdim    /// @param T - The target being registered.
659226584Sdim    /// @param Fn - A function to construct a MCSubtargetInfo for the target.
660226584Sdim    static void RegisterMCSubtargetInfo(Target &T,
661226584Sdim                                        Target::MCSubtargetInfoCtorFnTy Fn) {
662263509Sdim      T.MCSubtargetInfoCtorFn = Fn;
663226584Sdim    }
664226584Sdim
665226584Sdim    /// RegisterTargetMachine - Register a TargetMachine implementation for the
666226584Sdim    /// given target.
667226584Sdim    ///
668226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
669226584Sdim    /// while another thread is attempting to access the registry. Typically
670226584Sdim    /// this is done by initializing all targets at program startup.
671226584Sdim    ///
672226584Sdim    /// @param T - The target being registered.
673226584Sdim    /// @param Fn - A function to construct a TargetMachine for the target.
674226584Sdim    static void RegisterTargetMachine(Target &T,
675226584Sdim                                      Target::TargetMachineCtorTy Fn) {
676263509Sdim      T.TargetMachineCtorFn = Fn;
677226584Sdim    }
678226584Sdim
679226584Sdim    /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
680226584Sdim    /// given target.
681226584Sdim    ///
682226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
683226584Sdim    /// while another thread is attempting to access the registry. Typically
684226584Sdim    /// this is done by initializing all targets at program startup.
685226584Sdim    ///
686226584Sdim    /// @param T - The target being registered.
687226584Sdim    /// @param Fn - A function to construct an AsmBackend for the target.
688226584Sdim    static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
689263509Sdim      T.MCAsmBackendCtorFn = Fn;
690226584Sdim    }
691226584Sdim
692226584Sdim    /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
693226584Sdim    /// the given target.
694226584Sdim    ///
695226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
696226584Sdim    /// while another thread is attempting to access the registry. Typically
697226584Sdim    /// this is done by initializing all targets at program startup.
698226584Sdim    ///
699226584Sdim    /// @param T - The target being registered.
700226584Sdim    /// @param Fn - A function to construct an MCTargetAsmParser for the target.
701226584Sdim    static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
702263509Sdim      T.MCAsmParserCtorFn = Fn;
703226584Sdim    }
704226584Sdim
705226584Sdim    /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
706226584Sdim    /// target.
707226584Sdim    ///
708226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
709226584Sdim    /// while another thread is attempting to access the registry. Typically
710226584Sdim    /// this is done by initializing all targets at program startup.
711226584Sdim    ///
712226584Sdim    /// @param T - The target being registered.
713226584Sdim    /// @param Fn - A function to construct an AsmPrinter for the target.
714226584Sdim    static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
715263509Sdim      T.AsmPrinterCtorFn = Fn;
716226584Sdim    }
717226584Sdim
718226584Sdim    /// RegisterMCDisassembler - Register a MCDisassembler implementation for
719226584Sdim    /// the given target.
720226584Sdim    ///
721226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
722226584Sdim    /// while another thread is attempting to access the registry. Typically
723226584Sdim    /// this is done by initializing all targets at program startup.
724226584Sdim    ///
725226584Sdim    /// @param T - The target being registered.
726226584Sdim    /// @param Fn - A function to construct an MCDisassembler for the target.
727226584Sdim    static void RegisterMCDisassembler(Target &T,
728226584Sdim                                       Target::MCDisassemblerCtorTy Fn) {
729263509Sdim      T.MCDisassemblerCtorFn = Fn;
730226584Sdim    }
731226584Sdim
732226584Sdim    /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
733226584Sdim    /// given target.
734226584Sdim    ///
735226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
736226584Sdim    /// while another thread is attempting to access the registry. Typically
737226584Sdim    /// this is done by initializing all targets at program startup.
738226584Sdim    ///
739226584Sdim    /// @param T - The target being registered.
740226584Sdim    /// @param Fn - A function to construct an MCInstPrinter for the target.
741226584Sdim    static void RegisterMCInstPrinter(Target &T,
742226584Sdim                                      Target::MCInstPrinterCtorTy Fn) {
743263509Sdim      T.MCInstPrinterCtorFn = Fn;
744226584Sdim    }
745226584Sdim
746226584Sdim    /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
747226584Sdim    /// given target.
748226584Sdim    ///
749226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
750226584Sdim    /// while another thread is attempting to access the registry. Typically
751226584Sdim    /// this is done by initializing all targets at program startup.
752226584Sdim    ///
753226584Sdim    /// @param T - The target being registered.
754226584Sdim    /// @param Fn - A function to construct an MCCodeEmitter for the target.
755226584Sdim    static void RegisterMCCodeEmitter(Target &T,
756226584Sdim                                      Target::MCCodeEmitterCtorTy Fn) {
757263509Sdim      T.MCCodeEmitterCtorFn = Fn;
758226584Sdim    }
759226584Sdim
760226584Sdim    /// RegisterMCObjectStreamer - Register a object code MCStreamer
761226584Sdim    /// implementation for the given target.
762226584Sdim    ///
763226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
764226584Sdim    /// while another thread is attempting to access the registry. Typically
765226584Sdim    /// this is done by initializing all targets at program startup.
766226584Sdim    ///
767226584Sdim    /// @param T - The target being registered.
768226584Sdim    /// @param Fn - A function to construct an MCStreamer for the target.
769226584Sdim    static void RegisterMCObjectStreamer(Target &T,
770226584Sdim                                         Target::MCObjectStreamerCtorTy Fn) {
771263509Sdim      T.MCObjectStreamerCtorFn = Fn;
772226584Sdim    }
773226584Sdim
774226584Sdim    /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
775226584Sdim    /// for the given target.
776226584Sdim    ///
777226584Sdim    /// Clients are responsible for ensuring that registration doesn't occur
778226584Sdim    /// while another thread is attempting to access the registry. Typically
779226584Sdim    /// this is done by initializing all targets at program startup.
780226584Sdim    ///
781226584Sdim    /// @param T - The target being registered.
782226584Sdim    /// @param Fn - A function to construct an MCStreamer for the target.
783226584Sdim    static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
784263509Sdim      T.AsmStreamerCtorFn = Fn;
785226584Sdim    }
786226584Sdim
787263509Sdim    /// RegisterMCRelocationInfo - Register an MCRelocationInfo
788263509Sdim    /// implementation for the given target.
789263509Sdim    ///
790263509Sdim    /// Clients are responsible for ensuring that registration doesn't occur
791263509Sdim    /// while another thread is attempting to access the registry. Typically
792263509Sdim    /// this is done by initializing all targets at program startup.
793263509Sdim    ///
794263509Sdim    /// @param T - The target being registered.
795263509Sdim    /// @param Fn - A function to construct an MCRelocationInfo for the target.
796263509Sdim    static void RegisterMCRelocationInfo(Target &T,
797263509Sdim                                         Target::MCRelocationInfoCtorTy Fn) {
798263509Sdim      T.MCRelocationInfoCtorFn = Fn;
799263509Sdim    }
800263509Sdim
801263509Sdim    /// RegisterMCSymbolizer - Register an MCSymbolizer
802263509Sdim    /// implementation for the given target.
803263509Sdim    ///
804263509Sdim    /// Clients are responsible for ensuring that registration doesn't occur
805263509Sdim    /// while another thread is attempting to access the registry. Typically
806263509Sdim    /// this is done by initializing all targets at program startup.
807263509Sdim    ///
808263509Sdim    /// @param T - The target being registered.
809263509Sdim    /// @param Fn - A function to construct an MCSymbolizer for the target.
810263509Sdim    static void RegisterMCSymbolizer(Target &T,
811263509Sdim                                     Target::MCSymbolizerCtorTy Fn) {
812263509Sdim      T.MCSymbolizerCtorFn = Fn;
813263509Sdim    }
814263509Sdim
815226584Sdim    /// @}
816226584Sdim  };
817226584Sdim
818226584Sdim
819226584Sdim  //===--------------------------------------------------------------------===//
820226584Sdim
821226584Sdim  /// RegisterTarget - Helper template for registering a target, for use in the
822226584Sdim  /// target's initialization function. Usage:
823226584Sdim  ///
824226584Sdim  ///
825226584Sdim  /// Target TheFooTarget; // The global target instance.
826226584Sdim  ///
827226584Sdim  /// extern "C" void LLVMInitializeFooTargetInfo() {
828226584Sdim  ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
829226584Sdim  /// }
830235633Sdim  template<Triple::ArchType TargetArchType = Triple::UnknownArch,
831226584Sdim           bool HasJIT = false>
832226584Sdim  struct RegisterTarget {
833226584Sdim    RegisterTarget(Target &T, const char *Name, const char *Desc) {
834226584Sdim      TargetRegistry::RegisterTarget(T, Name, Desc,
835226584Sdim                                     &getTripleMatchQuality,
836226584Sdim                                     HasJIT);
837226584Sdim    }
838226584Sdim
839226584Sdim    static unsigned getTripleMatchQuality(const std::string &TT) {
840226584Sdim      if (Triple(TT).getArch() == TargetArchType)
841226584Sdim        return 20;
842226584Sdim      return 0;
843226584Sdim    }
844226584Sdim  };
845226584Sdim
846226584Sdim  /// RegisterMCAsmInfo - Helper template for registering a target assembly info
847226584Sdim  /// implementation.  This invokes the static "Create" method on the class to
848226584Sdim  /// actually do the construction.  Usage:
849226584Sdim  ///
850226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
851226584Sdim  ///   extern Target TheFooTarget;
852226584Sdim  ///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
853226584Sdim  /// }
854226584Sdim  template<class MCAsmInfoImpl>
855226584Sdim  struct RegisterMCAsmInfo {
856226584Sdim    RegisterMCAsmInfo(Target &T) {
857226584Sdim      TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
858226584Sdim    }
859226584Sdim  private:
860263509Sdim    static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) {
861263509Sdim      return new MCAsmInfoImpl(TT);
862226584Sdim    }
863226584Sdim
864226584Sdim  };
865226584Sdim
866226584Sdim  /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
867226584Sdim  /// implementation.  This invokes the specified function to do the
868226584Sdim  /// construction.  Usage:
869226584Sdim  ///
870226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
871226584Sdim  ///   extern Target TheFooTarget;
872226584Sdim  ///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
873226584Sdim  /// }
874226584Sdim  struct RegisterMCAsmInfoFn {
875226584Sdim    RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
876226584Sdim      TargetRegistry::RegisterMCAsmInfo(T, Fn);
877226584Sdim    }
878226584Sdim  };
879226584Sdim
880226584Sdim  /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
881226584Sdim  /// implementation.  This invokes the static "Create" method on the class
882226584Sdim  /// to actually do the construction.  Usage:
883226584Sdim  ///
884226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
885226584Sdim  ///   extern Target TheFooTarget;
886226584Sdim  ///   RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
887226584Sdim  /// }
888226584Sdim  template<class MCCodeGenInfoImpl>
889226584Sdim  struct RegisterMCCodeGenInfo {
890226584Sdim    RegisterMCCodeGenInfo(Target &T) {
891226584Sdim      TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
892226584Sdim    }
893226584Sdim  private:
894263509Sdim    static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
895263509Sdim                                    CodeModel::Model /*CM*/,
896263509Sdim                                    CodeGenOpt::Level /*OL*/) {
897226584Sdim      return new MCCodeGenInfoImpl();
898226584Sdim    }
899226584Sdim  };
900226584Sdim
901226584Sdim  /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
902226584Sdim  /// info implementation.  This invokes the specified function to do the
903226584Sdim  /// construction.  Usage:
904226584Sdim  ///
905226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
906226584Sdim  ///   extern Target TheFooTarget;
907226584Sdim  ///   RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
908226584Sdim  /// }
909226584Sdim  struct RegisterMCCodeGenInfoFn {
910226584Sdim    RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
911226584Sdim      TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
912226584Sdim    }
913226584Sdim  };
914226584Sdim
915226584Sdim  /// RegisterMCInstrInfo - Helper template for registering a target instruction
916226584Sdim  /// info implementation.  This invokes the static "Create" method on the class
917226584Sdim  /// to actually do the construction.  Usage:
918226584Sdim  ///
919226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
920226584Sdim  ///   extern Target TheFooTarget;
921226584Sdim  ///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
922226584Sdim  /// }
923226584Sdim  template<class MCInstrInfoImpl>
924226584Sdim  struct RegisterMCInstrInfo {
925226584Sdim    RegisterMCInstrInfo(Target &T) {
926226584Sdim      TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
927226584Sdim    }
928226584Sdim  private:
929226584Sdim    static MCInstrInfo *Allocator() {
930226584Sdim      return new MCInstrInfoImpl();
931226584Sdim    }
932226584Sdim  };
933226584Sdim
934226584Sdim  /// RegisterMCInstrInfoFn - Helper template for registering a target
935226584Sdim  /// instruction info implementation.  This invokes the specified function to
936226584Sdim  /// do the construction.  Usage:
937226584Sdim  ///
938226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
939226584Sdim  ///   extern Target TheFooTarget;
940226584Sdim  ///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
941226584Sdim  /// }
942226584Sdim  struct RegisterMCInstrInfoFn {
943226584Sdim    RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
944226584Sdim      TargetRegistry::RegisterMCInstrInfo(T, Fn);
945226584Sdim    }
946226584Sdim  };
947226584Sdim
948226584Sdim  /// RegisterMCInstrAnalysis - Helper template for registering a target
949226584Sdim  /// instruction analyzer implementation.  This invokes the static "Create"
950226584Sdim  /// method on the class to actually do the construction.  Usage:
951226584Sdim  ///
952226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
953226584Sdim  ///   extern Target TheFooTarget;
954226584Sdim  ///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
955226584Sdim  /// }
956226584Sdim  template<class MCInstrAnalysisImpl>
957226584Sdim  struct RegisterMCInstrAnalysis {
958226584Sdim    RegisterMCInstrAnalysis(Target &T) {
959226584Sdim      TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
960226584Sdim    }
961226584Sdim  private:
962226584Sdim    static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
963226584Sdim      return new MCInstrAnalysisImpl(Info);
964226584Sdim    }
965226584Sdim  };
966226584Sdim
967226584Sdim  /// RegisterMCInstrAnalysisFn - Helper template for registering a target
968226584Sdim  /// instruction analyzer implementation.  This invokes the specified function
969226584Sdim  /// to do the construction.  Usage:
970226584Sdim  ///
971226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
972226584Sdim  ///   extern Target TheFooTarget;
973226584Sdim  ///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
974226584Sdim  /// }
975226584Sdim  struct RegisterMCInstrAnalysisFn {
976226584Sdim    RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
977226584Sdim      TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
978226584Sdim    }
979226584Sdim  };
980226584Sdim
981226584Sdim  /// RegisterMCRegInfo - Helper template for registering a target register info
982226584Sdim  /// implementation.  This invokes the static "Create" method on the class to
983226584Sdim  /// actually do the construction.  Usage:
984226584Sdim  ///
985226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
986226584Sdim  ///   extern Target TheFooTarget;
987226584Sdim  ///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
988226584Sdim  /// }
989226584Sdim  template<class MCRegisterInfoImpl>
990226584Sdim  struct RegisterMCRegInfo {
991226584Sdim    RegisterMCRegInfo(Target &T) {
992226584Sdim      TargetRegistry::RegisterMCRegInfo(T, &Allocator);
993226584Sdim    }
994226584Sdim  private:
995263509Sdim    static MCRegisterInfo *Allocator(StringRef /*TT*/) {
996226584Sdim      return new MCRegisterInfoImpl();
997226584Sdim    }
998226584Sdim  };
999226584Sdim
1000226584Sdim  /// RegisterMCRegInfoFn - Helper template for registering a target register
1001226584Sdim  /// info implementation.  This invokes the specified function to do the
1002226584Sdim  /// construction.  Usage:
1003226584Sdim  ///
1004226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
1005226584Sdim  ///   extern Target TheFooTarget;
1006226584Sdim  ///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
1007226584Sdim  /// }
1008226584Sdim  struct RegisterMCRegInfoFn {
1009226584Sdim    RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
1010226584Sdim      TargetRegistry::RegisterMCRegInfo(T, Fn);
1011226584Sdim    }
1012226584Sdim  };
1013226584Sdim
1014226584Sdim  /// RegisterMCSubtargetInfo - Helper template for registering a target
1015226584Sdim  /// subtarget info implementation.  This invokes the static "Create" method
1016226584Sdim  /// on the class to actually do the construction.  Usage:
1017226584Sdim  ///
1018226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
1019226584Sdim  ///   extern Target TheFooTarget;
1020226584Sdim  ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
1021226584Sdim  /// }
1022226584Sdim  template<class MCSubtargetInfoImpl>
1023226584Sdim  struct RegisterMCSubtargetInfo {
1024226584Sdim    RegisterMCSubtargetInfo(Target &T) {
1025226584Sdim      TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
1026226584Sdim    }
1027226584Sdim  private:
1028263509Sdim    static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
1029263509Sdim                                      StringRef /*FS*/) {
1030226584Sdim      return new MCSubtargetInfoImpl();
1031226584Sdim    }
1032226584Sdim  };
1033226584Sdim
1034226584Sdim  /// RegisterMCSubtargetInfoFn - Helper template for registering a target
1035226584Sdim  /// subtarget info implementation.  This invokes the specified function to
1036226584Sdim  /// do the construction.  Usage:
1037226584Sdim  ///
1038226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
1039226584Sdim  ///   extern Target TheFooTarget;
1040226584Sdim  ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
1041226584Sdim  /// }
1042226584Sdim  struct RegisterMCSubtargetInfoFn {
1043226584Sdim    RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
1044226584Sdim      TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
1045226584Sdim    }
1046226584Sdim  };
1047226584Sdim
1048226584Sdim  /// RegisterTargetMachine - Helper template for registering a target machine
1049226584Sdim  /// implementation, for use in the target machine initialization
1050226584Sdim  /// function. Usage:
1051226584Sdim  ///
1052226584Sdim  /// extern "C" void LLVMInitializeFooTarget() {
1053226584Sdim  ///   extern Target TheFooTarget;
1054226584Sdim  ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
1055226584Sdim  /// }
1056226584Sdim  template<class TargetMachineImpl>
1057226584Sdim  struct RegisterTargetMachine {
1058226584Sdim    RegisterTargetMachine(Target &T) {
1059226584Sdim      TargetRegistry::RegisterTargetMachine(T, &Allocator);
1060226584Sdim    }
1061226584Sdim
1062226584Sdim  private:
1063226584Sdim    static TargetMachine *Allocator(const Target &T, StringRef TT,
1064226584Sdim                                    StringRef CPU, StringRef FS,
1065235633Sdim                                    const TargetOptions &Options,
1066226584Sdim                                    Reloc::Model RM,
1067235633Sdim                                    CodeModel::Model CM,
1068235633Sdim                                    CodeGenOpt::Level OL) {
1069235633Sdim      return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
1070226584Sdim    }
1071226584Sdim  };
1072226584Sdim
1073226584Sdim  /// RegisterMCAsmBackend - Helper template for registering a target specific
1074226584Sdim  /// assembler backend. Usage:
1075226584Sdim  ///
1076226584Sdim  /// extern "C" void LLVMInitializeFooMCAsmBackend() {
1077226584Sdim  ///   extern Target TheFooTarget;
1078226584Sdim  ///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
1079226584Sdim  /// }
1080226584Sdim  template<class MCAsmBackendImpl>
1081226584Sdim  struct RegisterMCAsmBackend {
1082226584Sdim    RegisterMCAsmBackend(Target &T) {
1083226584Sdim      TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
1084226584Sdim    }
1085226584Sdim
1086226584Sdim  private:
1087263509Sdim    static MCAsmBackend *Allocator(const Target &T,
1088263509Sdim                                   const MCRegisterInfo &MRI,
1089263509Sdim                                   StringRef Triple, StringRef CPU) {
1090263509Sdim      return new MCAsmBackendImpl(T, MRI, Triple, CPU);
1091226584Sdim    }
1092226584Sdim  };
1093226584Sdim
1094226584Sdim  /// RegisterMCAsmParser - Helper template for registering a target specific
1095226584Sdim  /// assembly parser, for use in the target machine initialization
1096226584Sdim  /// function. Usage:
1097226584Sdim  ///
1098226584Sdim  /// extern "C" void LLVMInitializeFooMCAsmParser() {
1099226584Sdim  ///   extern Target TheFooTarget;
1100226584Sdim  ///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
1101226584Sdim  /// }
1102226584Sdim  template<class MCAsmParserImpl>
1103226584Sdim  struct RegisterMCAsmParser {
1104226584Sdim    RegisterMCAsmParser(Target &T) {
1105226584Sdim      TargetRegistry::RegisterMCAsmParser(T, &Allocator);
1106226584Sdim    }
1107226584Sdim
1108226584Sdim  private:
1109263509Sdim    static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
1110263509Sdim                                        const MCInstrInfo &MII) {
1111263509Sdim      return new MCAsmParserImpl(STI, P, MII);
1112226584Sdim    }
1113226584Sdim  };
1114226584Sdim
1115226584Sdim  /// RegisterAsmPrinter - Helper template for registering a target specific
1116226584Sdim  /// assembly printer, for use in the target machine initialization
1117226584Sdim  /// function. Usage:
1118226584Sdim  ///
1119226584Sdim  /// extern "C" void LLVMInitializeFooAsmPrinter() {
1120226584Sdim  ///   extern Target TheFooTarget;
1121226584Sdim  ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
1122226584Sdim  /// }
1123226584Sdim  template<class AsmPrinterImpl>
1124226584Sdim  struct RegisterAsmPrinter {
1125226584Sdim    RegisterAsmPrinter(Target &T) {
1126226584Sdim      TargetRegistry::RegisterAsmPrinter(T, &Allocator);
1127226584Sdim    }
1128226584Sdim
1129226584Sdim  private:
1130226584Sdim    static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) {
1131226584Sdim      return new AsmPrinterImpl(TM, Streamer);
1132226584Sdim    }
1133226584Sdim  };
1134226584Sdim
1135226584Sdim  /// RegisterMCCodeEmitter - Helper template for registering a target specific
1136226584Sdim  /// machine code emitter, for use in the target initialization
1137226584Sdim  /// function. Usage:
1138226584Sdim  ///
1139226584Sdim  /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
1140226584Sdim  ///   extern Target TheFooTarget;
1141226584Sdim  ///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
1142226584Sdim  /// }
1143226584Sdim  template<class MCCodeEmitterImpl>
1144226584Sdim  struct RegisterMCCodeEmitter {
1145226584Sdim    RegisterMCCodeEmitter(Target &T) {
1146226584Sdim      TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
1147226584Sdim    }
1148226584Sdim
1149226584Sdim  private:
1150263509Sdim    static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/,
1151263509Sdim                                    const MCRegisterInfo &/*MRI*/,
1152263509Sdim                                    const MCSubtargetInfo &/*STI*/,
1153263509Sdim                                    MCContext &/*Ctx*/) {
1154226584Sdim      return new MCCodeEmitterImpl();
1155226584Sdim    }
1156226584Sdim  };
1157226584Sdim
1158226584Sdim}
1159226584Sdim
1160226584Sdim#endif
1161