ARMTargetMachine.cpp revision be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2b
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/raw_ostream.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// No assembler printer by default
43ARMTargetMachine::AsmPrinterCtorFn ARMTargetMachine::AsmPrinterCtor = 0;
44
45/// ThumbTargetMachine - Create an Thumb architecture model.
46///
47unsigned ThumbTargetMachine::getJITMatchQuality() {
48#if defined(__thumb__)
49  return 10;
50#endif
51  return 0;
52}
53
54unsigned ThumbTargetMachine::getModuleMatchQuality(const Module &M) {
55  std::string TT = M.getTargetTriple();
56  // Match thumb-foo-bar, as well as things like thumbv5blah-*
57  if (TT.size() >= 6 &&
58      (TT.substr(0, 6) == "thumb-" || TT.substr(0, 6) == "thumbv"))
59    return 20;
60
61  // If the target triple is something non-thumb, we don't match.
62  if (!TT.empty()) return 0;
63
64  if (M.getEndianness()  == Module::LittleEndian &&
65      M.getPointerSize() == Module::Pointer32)
66    return 10;                                   // Weak match
67  else if (M.getEndianness() != Module::AnyEndianness ||
68           M.getPointerSize() != Module::AnyPointerSize)
69    return 0;                                    // Match for some other target
70
71  return getJITMatchQuality()/2;
72}
73
74ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS)
75  : ARMTargetMachine(M, FS, true) {
76}
77
78/// TargetMachine ctor - Create an ARM architecture model.
79///
80ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS,
81                                   bool isThumb)
82  : Subtarget(M, FS, isThumb),
83    DataLayout(Subtarget.isAPCS_ABI() ?
84               // APCS ABI
85          (isThumb ?
86           std::string("e-p:32:32-f64:32:32-i64:32:32-"
87                       "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
88           std::string("e-p:32:32-f64:32:32-i64:32:32")) :
89               // AAPCS ABI
90          (isThumb ?
91           std::string("e-p:32:32-f64:64:64-i64:64:64-"
92                       "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
93           std::string("e-p:32:32-f64:64:64-i64:64:64"))),
94    InstrInfo(Subtarget),
95    FrameInfo(Subtarget),
96    JITInfo(),
97    TLInfo(*this) {
98  DefRelocModel = getRelocationModel();
99}
100
101unsigned ARMTargetMachine::getJITMatchQuality() {
102#if defined(__arm__)
103  return 10;
104#endif
105  return 0;
106}
107
108unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
109  std::string TT = M.getTargetTriple();
110  // Match arm-foo-bar, as well as things like armv5blah-*
111  if (TT.size() >= 4 &&
112      (TT.substr(0, 4) == "arm-" || TT.substr(0, 4) == "armv"))
113    return 20;
114  // If the target triple is something non-arm, we don't match.
115  if (!TT.empty()) return 0;
116
117  if (M.getEndianness()  == Module::LittleEndian &&
118      M.getPointerSize() == Module::Pointer32)
119    return 10;                                   // Weak match
120  else if (M.getEndianness() != Module::AnyEndianness ||
121           M.getPointerSize() != Module::AnyPointerSize)
122    return 0;                                    // Match for some other target
123
124  return getJITMatchQuality()/2;
125}
126
127
128const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const {
129  switch (Subtarget.TargetType) {
130   case ARMSubtarget::isDarwin:
131    return new ARMDarwinTargetAsmInfo(*this);
132   case ARMSubtarget::isELF:
133    return new ARMELFTargetAsmInfo(*this);
134   default:
135    return new ARMGenericTargetAsmInfo(*this);
136  }
137}
138
139
140// Pass Pipeline Configuration
141bool ARMTargetMachine::addInstSelector(PassManagerBase &PM, unsigned OptLevel) {
142  PM.add(createARMISelDag(*this));
143  return false;
144}
145
146bool ARMTargetMachine::addPreEmitPass(PassManagerBase &PM, unsigned OptLevel) {
147  // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
148  if (OptLevel != 0 && !DisableLdStOpti && !Subtarget.isThumb())
149    PM.add(createARMLoadStoreOptimizationPass());
150
151  if (OptLevel != 0 && !DisableIfConversion && !Subtarget.isThumb())
152    PM.add(createIfConverterPass());
153
154  PM.add(createARMConstantIslandPass());
155  return true;
156}
157
158bool ARMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
159                                          unsigned OptLevel,
160                                          bool Verbose,
161                                          raw_ostream &Out) {
162  // Output assembly language.
163  assert(AsmPrinterCtor && "AsmPrinter was not linked in");
164  if (AsmPrinterCtor)
165    PM.add(AsmPrinterCtor(Out, *this, OptLevel, Verbose));
166
167  return false;
168}
169
170
171bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM, unsigned OptLevel,
172                                      bool DumpAsm, MachineCodeEmitter &MCE) {
173  // FIXME: Move this to TargetJITInfo!
174  if (DefRelocModel == Reloc::Default)
175    setRelocationModel(Reloc::Static);
176
177  // Machine code emitter pass for ARM.
178  PM.add(createARMCodeEmitterPass(*this, MCE));
179  if (DumpAsm) {
180    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
181    if (AsmPrinterCtor)
182      PM.add(AsmPrinterCtor(errs(), *this, OptLevel, true));
183  }
184
185  return false;
186}
187
188bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
189                                            unsigned OptLevel,
190                                            bool DumpAsm,
191                                            MachineCodeEmitter &MCE) {
192  // Machine code emitter pass for ARM.
193  PM.add(createARMCodeEmitterPass(*this, MCE));
194  if (DumpAsm) {
195    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
196    if (AsmPrinterCtor)
197      PM.add(AsmPrinterCtor(errs(), *this, OptLevel, true));
198  }
199
200  return false;
201}
202