Remove old style hacks to register AsmPrinter into TargetMachine.
[oota-llvm.git] / lib / Target / ARM / ARMTargetMachine.cpp
1 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
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 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARMTargetMachine.h"
14 #include "ARMTargetAsmInfo.h"
15 #include "ARMFrameInfo.h"
16 #include "ARM.h"
17 #include "llvm/Module.h"
18 #include "llvm/PassManager.h"
19 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/FormattedStream.h"
22 #include "llvm/Target/TargetMachineRegistry.h"
23 #include "llvm/Target/TargetOptions.h"
24 using namespace llvm;
25
26 static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden,
27                               cl::desc("Disable load store optimization pass"));
28 static cl::opt<bool> DisableIfConversion("disable-arm-if-conversion",cl::Hidden,
29                               cl::desc("Disable if-conversion pass"));
30
31 /// ARMTargetMachineModule - Note that this is used on hosts that cannot link
32 /// in a library unless there are references into the library.  In particular,
33 /// it seems that it is not possible to get things to work on Win32 without
34 /// this.  Though it is unused, do not remove it.
35 extern "C" int ARMTargetMachineModule;
36 int ARMTargetMachineModule = 0;
37
38 // Register the target.
39 extern Target TheARMTarget;
40 static RegisterTarget<ARMTargetMachine>   X(TheARMTarget, "arm",   "ARM");
41
42 extern Target TheThumbTarget;
43 static RegisterTarget<ThumbTargetMachine> Y(TheThumbTarget, "thumb", "Thumb");
44
45 // Force static initialization.
46 extern "C" void LLVMInitializeARMTarget() { }
47
48 /// TargetMachine ctor - Create an ARM architecture model.
49 ///
50 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
51                                            const Module &M,
52                                            const std::string &FS,
53                                            bool isThumb)
54   : LLVMTargetMachine(T),
55     Subtarget(M, FS, isThumb),
56     FrameInfo(Subtarget),
57     JITInfo(),
58     InstrItins(Subtarget.getInstrItineraryData()) {
59   DefRelocModel = getRelocationModel();
60 }
61
62 ARMTargetMachine::ARMTargetMachine(const Target &T, const Module &M, 
63                                    const std::string &FS)
64   : ARMBaseTargetMachine(T, M, FS, false), InstrInfo(Subtarget),
65     DataLayout(Subtarget.isAPCS_ABI() ?
66                std::string("e-p:32:32-f64:32:32-i64:32:32") :
67                std::string("e-p:32:32-f64:64:64-i64:64:64")),
68     TLInfo(*this) {
69 }
70
71 ThumbTargetMachine::ThumbTargetMachine(const Target &T, const Module &M, 
72                                        const std::string &FS)
73   : ARMBaseTargetMachine(T, M, FS, true),
74     DataLayout(Subtarget.isAPCS_ABI() ?
75                std::string("e-p:32:32-f64:32:32-i64:32:32-"
76                            "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
77                std::string("e-p:32:32-f64:64:64-i64:64:64-"
78                            "i16:16:32-i8:8:32-i1:8:32-a:0:32")),
79     TLInfo(*this) {
80   // Create the approriate type of Thumb InstrInfo
81   if (Subtarget.hasThumb2())
82     InstrInfo = new Thumb2InstrInfo(Subtarget);
83   else
84     InstrInfo = new Thumb1InstrInfo(Subtarget);
85 }
86
87
88 const TargetAsmInfo *ARMBaseTargetMachine::createTargetAsmInfo() const {
89   switch (Subtarget.TargetType) {
90    case ARMSubtarget::isDarwin:
91     return new ARMDarwinTargetAsmInfo(*this);
92    case ARMSubtarget::isELF:
93     return new ARMELFTargetAsmInfo(*this);
94    default:
95     return new ARMGenericTargetAsmInfo(*this);
96   }
97 }
98
99
100 // Pass Pipeline Configuration
101 bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
102                                            CodeGenOpt::Level OptLevel) {
103   PM.add(createARMISelDag(*this));
104   return false;
105 }
106
107 bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
108                                           CodeGenOpt::Level OptLevel) {
109   // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
110   if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
111     PM.add(createARMLoadStoreOptimizationPass(true));
112   return true;
113 }
114
115 bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
116                                           CodeGenOpt::Level OptLevel) {
117   // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
118   if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
119     PM.add(createARMLoadStoreOptimizationPass());
120
121   if (OptLevel != CodeGenOpt::None &&
122       !DisableIfConversion && !Subtarget.isThumb())
123     PM.add(createIfConverterPass());
124
125   if (Subtarget.isThumb2())
126     PM.add(createThumb2ITBlockPass());
127
128   PM.add(createARMConstantIslandPass());
129   return true;
130 }
131
132 bool ARMBaseTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
133                                               CodeGenOpt::Level OptLevel,
134                                               bool Verbose,
135                                               formatted_raw_ostream &Out) {
136   FunctionPass *Printer = getTarget().createAsmPrinter(Out, *this, Verbose);
137   if (!Printer)
138     llvm_report_error("unable to create assembly printer");
139   PM.add(Printer);
140   return false;
141 }
142
143
144 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
145                                           CodeGenOpt::Level OptLevel,
146                                           bool DumpAsm,
147                                           MachineCodeEmitter &MCE) {
148   // FIXME: Move this to TargetJITInfo!
149   if (DefRelocModel == Reloc::Default)
150     setRelocationModel(Reloc::Static);
151
152   // Machine code emitter pass for ARM.
153   PM.add(createARMCodeEmitterPass(*this, MCE));
154   if (DumpAsm)
155     addAssemblyEmitter(PM, OptLevel, true, ferrs());
156
157   return false;
158 }
159
160 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
161                                           CodeGenOpt::Level OptLevel,
162                                           bool DumpAsm,
163                                           JITCodeEmitter &JCE) {
164   // FIXME: Move this to TargetJITInfo!
165   if (DefRelocModel == Reloc::Default)
166     setRelocationModel(Reloc::Static);
167
168   // Machine code emitter pass for ARM.
169   PM.add(createARMJITCodeEmitterPass(*this, JCE));
170   if (DumpAsm)
171     addAssemblyEmitter(PM, OptLevel, true, ferrs());
172
173   return false;
174 }
175
176 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
177                                           CodeGenOpt::Level OptLevel,
178                                           bool DumpAsm,
179                                           ObjectCodeEmitter &OCE) {
180   // FIXME: Move this to TargetJITInfo!
181   if (DefRelocModel == Reloc::Default)
182     setRelocationModel(Reloc::Static);
183
184   // Machine code emitter pass for ARM.
185   PM.add(createARMObjectCodeEmitterPass(*this, OCE));
186   if (DumpAsm)
187     addAssemblyEmitter(PM, OptLevel, true, ferrs());
188
189   return false;
190 }
191
192 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
193                                                 CodeGenOpt::Level OptLevel,
194                                                 bool DumpAsm,
195                                                 MachineCodeEmitter &MCE) {
196   // Machine code emitter pass for ARM.
197   PM.add(createARMCodeEmitterPass(*this, MCE));
198   if (DumpAsm)
199     addAssemblyEmitter(PM, OptLevel, true, ferrs());
200
201   return false;
202 }
203
204 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
205                                                 CodeGenOpt::Level OptLevel,
206                                                 bool DumpAsm,
207                                                 JITCodeEmitter &JCE) {
208   // Machine code emitter pass for ARM.
209   PM.add(createARMJITCodeEmitterPass(*this, JCE));
210   if (DumpAsm)
211     addAssemblyEmitter(PM, OptLevel, true, ferrs());
212
213   return false;
214 }
215
216 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
217                                             CodeGenOpt::Level OptLevel,
218                                             bool DumpAsm,
219                                             ObjectCodeEmitter &OCE) {
220   // Machine code emitter pass for ARM.
221   PM.add(createARMObjectCodeEmitterPass(*this, OCE));
222   if (DumpAsm)
223     addAssemblyEmitter(PM, OptLevel, true, ferrs());
224
225   return false;
226 }
227