Lift DumpAsm / -print-emitted-asm functionality into LLVMTargetMachine.
[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                                           MachineCodeEmitter &MCE) {
147   // FIXME: Move this to TargetJITInfo!
148   if (DefRelocModel == Reloc::Default)
149     setRelocationModel(Reloc::Static);
150
151   // Machine code emitter pass for ARM.
152   PM.add(createARMCodeEmitterPass(*this, MCE));
153   return false;
154 }
155
156 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
157                                           CodeGenOpt::Level OptLevel,
158                                           JITCodeEmitter &JCE) {
159   // FIXME: Move this to TargetJITInfo!
160   if (DefRelocModel == Reloc::Default)
161     setRelocationModel(Reloc::Static);
162
163   // Machine code emitter pass for ARM.
164   PM.add(createARMJITCodeEmitterPass(*this, JCE));
165   return false;
166 }
167
168 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
169                                           CodeGenOpt::Level OptLevel,
170                                           ObjectCodeEmitter &OCE) {
171   // FIXME: Move this to TargetJITInfo!
172   if (DefRelocModel == Reloc::Default)
173     setRelocationModel(Reloc::Static);
174
175   // Machine code emitter pass for ARM.
176   PM.add(createARMObjectCodeEmitterPass(*this, OCE));
177   return false;
178 }
179
180 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
181                                                 CodeGenOpt::Level OptLevel,
182                                                 MachineCodeEmitter &MCE) {
183   // Machine code emitter pass for ARM.
184   PM.add(createARMCodeEmitterPass(*this, MCE));
185   return false;
186 }
187
188 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
189                                                 CodeGenOpt::Level OptLevel,
190                                                 JITCodeEmitter &JCE) {
191   // Machine code emitter pass for ARM.
192   PM.add(createARMJITCodeEmitterPass(*this, JCE));
193   return false;
194 }
195
196 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
197                                             CodeGenOpt::Level OptLevel,
198                                             ObjectCodeEmitter &OCE) {
199   // Machine code emitter pass for ARM.
200   PM.add(createARMObjectCodeEmitterPass(*this, OCE));
201   return false;
202 }
203