1 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
13 #include "ARMTargetMachine.h"
14 #include "ARMFrameLowering.h"
16 #include "llvm/PassManager.h"
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/Support/CommandLine.h"
19 #include "llvm/Support/FormattedStream.h"
20 #include "llvm/Target/TargetOptions.h"
21 #include "llvm/Target/TargetRegistry.h"
24 // This is duplicated code. Refactor this.
25 static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
26 MCContext &Ctx, TargetAsmBackend &TAB,
28 MCCodeEmitter *Emitter,
33 if (TheTriple.isOSDarwin())
34 return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
36 if (TheTriple.isOSWindows()) {
37 llvm_unreachable("ARM does not support Windows COFF format");
41 return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
44 extern "C" void LLVMInitializeARMTarget() {
45 // Register the target.
46 RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
47 RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
49 // Register the MC Code Emitter
50 TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter);
51 TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter);
53 // Register the asm backend.
54 TargetRegistry::RegisterAsmBackend(TheARMTarget, createARMAsmBackend);
55 TargetRegistry::RegisterAsmBackend(TheThumbTarget, createARMAsmBackend);
57 // Register the object streamer.
58 TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer);
59 TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer);
63 /// TargetMachine ctor - Create an ARM architecture model.
65 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
66 const std::string &TT,
67 const std::string &CPU,
68 const std::string &FS)
69 : LLVMTargetMachine(T, TT, CPU, FS),
70 Subtarget(TT, CPU, FS),
72 InstrItins(Subtarget.getInstrItineraryData()) {
73 DefRelocModel = getRelocationModel();
75 // Default to soft float ABI
76 if (FloatABIType == FloatABI::Default)
77 FloatABIType = FloatABI::Soft;
80 ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
81 const std::string &CPU,
82 const std::string &FS)
83 : ARMBaseTargetMachine(T, TT, CPU, FS), InstrInfo(Subtarget),
84 DataLayout(Subtarget.isAPCS_ABI() ?
85 std::string("e-p:32:32-f64:32:64-i64:32:64-"
86 "v128:32:128-v64:32:64-n32") :
87 std::string("e-p:32:32-f64:64:64-i64:64:64-"
88 "v128:64:128-v64:64:64-n32")),
92 FrameLowering(Subtarget) {
93 if (!Subtarget.hasARMOps())
94 report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
95 "support ARM mode execution!");
98 ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
99 const std::string &CPU,
100 const std::string &FS)
101 : ARMBaseTargetMachine(T, TT, CPU, FS),
102 InstrInfo(Subtarget.hasThumb2()
103 ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
104 : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
105 DataLayout(Subtarget.isAPCS_ABI() ?
106 std::string("e-p:32:32-f64:32:64-i64:32:64-"
107 "i16:16:32-i8:8:32-i1:8:32-"
108 "v128:32:128-v64:32:64-a:0:32-n32") :
109 std::string("e-p:32:32-f64:64:64-i64:64:64-"
110 "i16:16:32-i8:8:32-i1:8:32-"
111 "v128:64:128-v64:64:64-a:0:32-n32")),
112 ELFWriterInfo(*this),
115 FrameLowering(Subtarget.hasThumb2()
116 ? new ARMFrameLowering(Subtarget)
117 : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
120 // Pass Pipeline Configuration
121 bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM,
122 CodeGenOpt::Level OptLevel) {
123 if (OptLevel != CodeGenOpt::None)
124 PM.add(createARMGlobalMergePass(getTargetLowering()));
129 bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
130 CodeGenOpt::Level OptLevel) {
131 PM.add(createARMISelDag(*this, OptLevel));
135 bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
136 CodeGenOpt::Level OptLevel) {
137 // FIXME: temporarily disabling load / store optimization pass for Thumb1.
138 if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
139 PM.add(createARMLoadStoreOptimizationPass(true));
140 if (OptLevel != CodeGenOpt::None && Subtarget.isCortexA9())
141 PM.add(createMLxExpansionPass());
146 bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
147 CodeGenOpt::Level OptLevel) {
148 // FIXME: temporarily disabling load / store optimization pass for Thumb1.
149 if (OptLevel != CodeGenOpt::None) {
150 if (!Subtarget.isThumb1Only())
151 PM.add(createARMLoadStoreOptimizationPass());
152 if (Subtarget.hasNEON())
153 PM.add(createNEONMoveFixPass());
156 // Expand some pseudo instructions into multiple instructions to allow
157 // proper scheduling.
158 PM.add(createARMExpandPseudoPass());
160 if (OptLevel != CodeGenOpt::None) {
161 if (!Subtarget.isThumb1Only())
162 PM.add(createIfConverterPass());
164 if (Subtarget.isThumb2())
165 PM.add(createThumb2ITBlockPass());
170 bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
171 CodeGenOpt::Level OptLevel) {
172 if (Subtarget.isThumb2() && !Subtarget.prefers32BitThumb())
173 PM.add(createThumb2SizeReductionPass());
175 PM.add(createARMConstantIslandPass());
179 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
180 CodeGenOpt::Level OptLevel,
181 JITCodeEmitter &JCE) {
182 // FIXME: Move this to TargetJITInfo!
183 if (DefRelocModel == Reloc::Default)
184 setRelocationModel(Reloc::Static);
186 // Machine code emitter pass for ARM.
187 PM.add(createARMJITCodeEmitterPass(*this, JCE));