ARMTargetMachine.cpp revision 200581
16179Srobm//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
26179Srobm//
36179Srobm//                     The LLVM Compiler Infrastructure
46179Srobm//
56179Srobm// This file is distributed under the University of Illinois Open Source
66179Srobm// License. See LICENSE.TXT for details.
76179Srobm//
86179Srobm//===----------------------------------------------------------------------===//
96179Srobm//
106179Srobm//
116179Srobm//===----------------------------------------------------------------------===//
126179Srobm
136179Srobm#include "ARMTargetMachine.h"
146179Srobm#include "ARMMCAsmInfo.h"
156179Srobm#include "ARMFrameInfo.h"
166179Srobm#include "ARM.h"
176179Srobm#include "llvm/PassManager.h"
186179Srobm#include "llvm/CodeGen/Passes.h"
196179Srobm#include "llvm/Support/FormattedStream.h"
206179Srobm#include "llvm/Target/TargetOptions.h"
216179Srobm#include "llvm/Target/TargetRegistry.h"
226179Srobmusing namespace llvm;
236179Srobm
246179Srobmstatic const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
256179Srobm  Triple TheTriple(TT);
266179Srobm  switch (TheTriple.getOS()) {
276179Srobm  case Triple::Darwin:
286179Srobm    return new ARMMCAsmInfoDarwin();
296179Srobm  default:
306179Srobm    return new ARMELFMCAsmInfo();
316179Srobm  }
326179Srobm}
336179Srobm
346179Srobm
356179Srobmextern "C" void LLVMInitializeARMTarget() {
366179Srobm  // Register the target.
376179Srobm  RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
386179Srobm  RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
396179Srobm
406179Srobm  // Register the target asm info.
416179Srobm  RegisterAsmInfoFn A(TheARMTarget, createMCAsmInfo);
426179Srobm  RegisterAsmInfoFn B(TheThumbTarget, createMCAsmInfo);
436179Srobm}
446179Srobm
456179Srobm/// TargetMachine ctor - Create an ARM architecture model.
466179Srobm///
476179SrobmARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
486179Srobm                                           const std::string &TT,
496179Srobm                                           const std::string &FS,
506179Srobm                                           bool isThumb)
516179Srobm  : LLVMTargetMachine(T, TT),
526179Srobm    Subtarget(TT, FS, isThumb),
536179Srobm    FrameInfo(Subtarget),
546179Srobm    JITInfo(),
556179Srobm    InstrItins(Subtarget.getInstrItineraryData()) {
566179Srobm  DefRelocModel = getRelocationModel();
576179Srobm}
586179Srobm
59ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
60                                   const std::string &FS)
61  : ARMBaseTargetMachine(T, TT, FS, false), InstrInfo(Subtarget),
62    DataLayout(Subtarget.isAPCS_ABI() ?
63               std::string("e-p:32:32-f64:32:32-i64:32:32-n32") :
64               std::string("e-p:32:32-f64:64:64-i64:64:64-n32")),
65    TLInfo(*this) {
66}
67
68ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
69                                       const std::string &FS)
70  : ARMBaseTargetMachine(T, TT, FS, true),
71    InstrInfo(Subtarget.hasThumb2()
72              ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
73              : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
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-n32") :
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-n32")),
79    TLInfo(*this) {
80}
81
82
83
84// Pass Pipeline Configuration
85bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
86                                           CodeGenOpt::Level OptLevel) {
87  PM.add(createARMISelDag(*this, OptLevel));
88  return false;
89}
90
91bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
92                                          CodeGenOpt::Level OptLevel) {
93  if (Subtarget.hasNEON())
94    PM.add(createNEONPreAllocPass());
95
96  // Calculate and set max stack object alignment early, so we can decide
97  // whether we will need stack realignment (and thus FP).
98  PM.add(createMaxStackAlignmentCalculatorPass());
99
100  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
101  if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
102    PM.add(createARMLoadStoreOptimizationPass(true));
103  return true;
104}
105
106bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
107                                        CodeGenOpt::Level OptLevel) {
108  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
109  if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
110    PM.add(createARMLoadStoreOptimizationPass());
111
112  // Expand some pseudo instructions into multiple instructions to allow
113  // proper scheduling.
114  PM.add(createARMExpandPseudoPass());
115
116  return true;
117}
118
119bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
120                                          CodeGenOpt::Level OptLevel) {
121  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
122  if (OptLevel != CodeGenOpt::None) {
123    if (!Subtarget.isThumb1Only())
124      PM.add(createIfConverterPass());
125    if (Subtarget.hasNEON())
126      PM.add(createNEONMoveFixPass());
127  }
128
129  if (Subtarget.isThumb2()) {
130    PM.add(createThumb2ITBlockPass());
131    PM.add(createThumb2SizeReductionPass());
132  }
133
134  PM.add(createARMConstantIslandPass());
135  return true;
136}
137
138bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
139                                          CodeGenOpt::Level OptLevel,
140                                          MachineCodeEmitter &MCE) {
141  // FIXME: Move this to TargetJITInfo!
142  if (DefRelocModel == Reloc::Default)
143    setRelocationModel(Reloc::Static);
144
145  // Machine code emitter pass for ARM.
146  PM.add(createARMCodeEmitterPass(*this, MCE));
147  return false;
148}
149
150bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
151                                          CodeGenOpt::Level OptLevel,
152                                          JITCodeEmitter &JCE) {
153  // FIXME: Move this to TargetJITInfo!
154  if (DefRelocModel == Reloc::Default)
155    setRelocationModel(Reloc::Static);
156
157  // Machine code emitter pass for ARM.
158  PM.add(createARMJITCodeEmitterPass(*this, JCE));
159  return false;
160}
161
162bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
163                                          CodeGenOpt::Level OptLevel,
164                                          ObjectCodeEmitter &OCE) {
165  // FIXME: Move this to TargetJITInfo!
166  if (DefRelocModel == Reloc::Default)
167    setRelocationModel(Reloc::Static);
168
169  // Machine code emitter pass for ARM.
170  PM.add(createARMObjectCodeEmitterPass(*this, OCE));
171  return false;
172}
173
174bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
175                                                CodeGenOpt::Level OptLevel,
176                                                MachineCodeEmitter &MCE) {
177  // Machine code emitter pass for ARM.
178  PM.add(createARMCodeEmitterPass(*this, MCE));
179  return false;
180}
181
182bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
183                                                CodeGenOpt::Level OptLevel,
184                                                JITCodeEmitter &JCE) {
185  // Machine code emitter pass for ARM.
186  PM.add(createARMJITCodeEmitterPass(*this, JCE));
187  return false;
188}
189
190bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
191                                            CodeGenOpt::Level OptLevel,
192                                            ObjectCodeEmitter &OCE) {
193  // Machine code emitter pass for ARM.
194  PM.add(createARMObjectCodeEmitterPass(*this, OCE));
195  return false;
196}
197
198