ARMTargetMachine.cpp revision 2286f8dc4cec0625f7d7a14e2570926cf8599646
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"
24using namespace llvm;
25
26static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden,
27                              cl::desc("Disable load store optimization pass"));
28static 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.
35extern "C" int ARMTargetMachineModule;
36int ARMTargetMachineModule = 0;
37
38// Register the target.
39static RegisterTarget<ARMTargetMachine>   X("arm",   "ARM");
40static RegisterTarget<ThumbTargetMachine> Y("thumb", "Thumb");
41
42// Force static initialization.
43extern "C" void LLVMInitializeARMTarget() { }
44
45// No assembler printer by default
46ARMBaseTargetMachine::AsmPrinterCtorFn ARMBaseTargetMachine::AsmPrinterCtor = 0;
47
48/// ThumbTargetMachine - Create an Thumb architecture model.
49///
50unsigned ThumbTargetMachine::getJITMatchQuality() {
51#if defined(__thumb__)
52  return 10;
53#endif
54  return 0;
55}
56
57unsigned ThumbTargetMachine::getModuleMatchQuality(const Module &M) {
58  std::string TT = M.getTargetTriple();
59  // Match thumb-foo-bar, as well as things like thumbv5blah-*
60  if (TT.size() >= 6 &&
61      (TT.substr(0, 6) == "thumb-" || TT.substr(0, 6) == "thumbv"))
62    return 20;
63
64  // If the target triple is something non-thumb, we don't match.
65  if (!TT.empty()) return 0;
66
67  if (M.getEndianness()  == Module::LittleEndian &&
68      M.getPointerSize() == Module::Pointer32)
69    return 10;                                   // Weak match
70  else if (M.getEndianness() != Module::AnyEndianness ||
71           M.getPointerSize() != Module::AnyPointerSize)
72    return 0;                                    // Match for some other target
73
74  return getJITMatchQuality()/2;
75}
76
77/// TargetMachine ctor - Create an ARM architecture model.
78///
79ARMBaseTargetMachine::ARMBaseTargetMachine(const Module &M,
80                                           const std::string &FS,
81                                           bool isThumb)
82  : Subtarget(M, FS, isThumb),
83    FrameInfo(Subtarget),
84    JITInfo(),
85    InstrItins(Subtarget.getInstrItineraryData()) {
86  DefRelocModel = getRelocationModel();
87}
88
89ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
90  : ARMBaseTargetMachine(M, FS, false), InstrInfo(Subtarget),
91    DataLayout(Subtarget.isAPCS_ABI() ?
92               std::string("e-p:32:32-f64:32:32-i64:32:32") :
93               std::string("e-p:32:32-f64:64:64-i64:64:64")),
94    TLInfo(*this) {
95}
96
97ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS)
98  : ARMBaseTargetMachine(M, FS, true),
99    DataLayout(Subtarget.isAPCS_ABI() ?
100               std::string("e-p:32:32-f64:32:32-i64:32:32-"
101                           "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
102               std::string("e-p:32:32-f64:64:64-i64:64:64-"
103                           "i16:16:32-i8:8:32-i1:8:32-a:0:32")),
104    TLInfo(*this) {
105  // Create the approriate type of Thumb InstrInfo
106  if (Subtarget.hasThumb2())
107    InstrInfo = new Thumb2InstrInfo(Subtarget);
108  else
109    InstrInfo = new Thumb1InstrInfo(Subtarget);
110}
111
112unsigned ARMTargetMachine::getJITMatchQuality() {
113#if defined(__arm__)
114  return 10;
115#endif
116  return 0;
117}
118
119unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
120  std::string TT = M.getTargetTriple();
121  // Match arm-foo-bar, as well as things like armv5blah-*
122  if (TT.size() >= 4 &&
123      (TT.substr(0, 4) == "arm-" || TT.substr(0, 4) == "armv"))
124    return 20;
125  // If the target triple is something non-arm, we don't match.
126  if (!TT.empty()) return 0;
127
128  if (M.getEndianness()  == Module::LittleEndian &&
129      M.getPointerSize() == Module::Pointer32)
130    return 10;                                   // Weak match
131  else if (M.getEndianness() != Module::AnyEndianness ||
132           M.getPointerSize() != Module::AnyPointerSize)
133    return 0;                                    // Match for some other target
134
135  return getJITMatchQuality()/2;
136}
137
138
139const TargetAsmInfo *ARMBaseTargetMachine::createTargetAsmInfo() const {
140  switch (Subtarget.TargetType) {
141   case ARMSubtarget::isDarwin:
142    return new ARMDarwinTargetAsmInfo(*this);
143   case ARMSubtarget::isELF:
144    return new ARMELFTargetAsmInfo(*this);
145   default:
146    return new ARMGenericTargetAsmInfo(*this);
147  }
148}
149
150
151// Pass Pipeline Configuration
152bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
153                                           CodeGenOpt::Level OptLevel) {
154  PM.add(createARMISelDag(*this));
155  return false;
156}
157
158bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
159                                          CodeGenOpt::Level OptLevel) {
160  // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
161  if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
162    PM.add(createARMLoadStoreOptimizationPass(true));
163  return true;
164}
165
166bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
167                                          CodeGenOpt::Level OptLevel) {
168  // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
169  if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
170    PM.add(createARMLoadStoreOptimizationPass());
171
172  if (OptLevel != CodeGenOpt::None &&
173      !DisableIfConversion && !Subtarget.isThumb())
174    PM.add(createIfConverterPass());
175
176  if (Subtarget.isThumb2())
177    PM.add(createThumb2ITBlockPass());
178
179  PM.add(createARMConstantIslandPass());
180  return true;
181}
182
183bool ARMBaseTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
184                                              CodeGenOpt::Level OptLevel,
185                                              bool Verbose,
186                                              formatted_raw_ostream &Out) {
187  // Output assembly language.
188  assert(AsmPrinterCtor && "AsmPrinter was not linked in");
189  if (AsmPrinterCtor)
190    PM.add(AsmPrinterCtor(Out, *this, Verbose));
191
192  return false;
193}
194
195
196bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
197                                          CodeGenOpt::Level OptLevel,
198                                          bool DumpAsm,
199                                          MachineCodeEmitter &MCE) {
200  // FIXME: Move this to TargetJITInfo!
201  if (DefRelocModel == Reloc::Default)
202    setRelocationModel(Reloc::Static);
203
204  // Machine code emitter pass for ARM.
205  PM.add(createARMCodeEmitterPass(*this, MCE));
206  if (DumpAsm)
207    addAssemblyEmitter(PM, OptLevel, true, ferrs());
208
209  return false;
210}
211
212bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
213                                          CodeGenOpt::Level OptLevel,
214                                          bool DumpAsm,
215                                          JITCodeEmitter &JCE) {
216  // FIXME: Move this to TargetJITInfo!
217  if (DefRelocModel == Reloc::Default)
218    setRelocationModel(Reloc::Static);
219
220  // Machine code emitter pass for ARM.
221  PM.add(createARMJITCodeEmitterPass(*this, JCE));
222  if (DumpAsm)
223    addAssemblyEmitter(PM, OptLevel, true, ferrs());
224
225  return false;
226}
227
228bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
229                                          CodeGenOpt::Level OptLevel,
230                                          bool DumpAsm,
231                                          ObjectCodeEmitter &OCE) {
232  // FIXME: Move this to TargetJITInfo!
233  if (DefRelocModel == Reloc::Default)
234    setRelocationModel(Reloc::Static);
235
236  // Machine code emitter pass for ARM.
237  PM.add(createARMObjectCodeEmitterPass(*this, OCE));
238  if (DumpAsm)
239    addAssemblyEmitter(PM, OptLevel, true, ferrs());
240
241  return false;
242}
243
244bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
245                                                CodeGenOpt::Level OptLevel,
246                                                bool DumpAsm,
247                                                MachineCodeEmitter &MCE) {
248  // Machine code emitter pass for ARM.
249  PM.add(createARMCodeEmitterPass(*this, MCE));
250  if (DumpAsm)
251    addAssemblyEmitter(PM, OptLevel, true, ferrs());
252
253  return false;
254}
255
256bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
257                                                CodeGenOpt::Level OptLevel,
258                                                bool DumpAsm,
259                                                JITCodeEmitter &JCE) {
260  // Machine code emitter pass for ARM.
261  PM.add(createARMJITCodeEmitterPass(*this, JCE));
262  if (DumpAsm)
263    addAssemblyEmitter(PM, OptLevel, true, ferrs());
264
265  return false;
266}
267
268bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
269                                            CodeGenOpt::Level OptLevel,
270                                            bool DumpAsm,
271                                            ObjectCodeEmitter &OCE) {
272  // Machine code emitter pass for ARM.
273  PM.add(createARMObjectCodeEmitterPass(*this, OCE));
274  if (DumpAsm)
275    addAssemblyEmitter(PM, OptLevel, true, ferrs());
276
277  return false;
278}
279
280