Duh. Most 16-bit Thumb rr instructions are two-address. Fix table.
[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/PassManager.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/FormattedStream.h"
21 #include "llvm/Target/TargetOptions.h"
22 #include "llvm/Target/TargetRegistry.h"
23 using namespace llvm;
24
25 static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden,
26                               cl::desc("Disable load store optimization pass"));
27 static cl::opt<bool> DisableIfConversion("disable-arm-if-conversion",cl::Hidden,
28                               cl::desc("Disable if-conversion pass"));
29 static cl::opt<bool> Thumb2Shrink("shrink-thumb2-instructions", cl::Hidden,
30                   cl::desc("Shrink 32-bit Thumb2 instructions to 16-bit ones"));
31
32 extern "C" void LLVMInitializeARMTarget() { 
33   // Register the target.
34   RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
35   RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
36 }
37
38 /// TargetMachine ctor - Create an ARM architecture model.
39 ///
40 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
41                                            const std::string &TT,
42                                            const std::string &FS,
43                                            bool isThumb)
44   : LLVMTargetMachine(T),
45     Subtarget(TT, FS, isThumb),
46     FrameInfo(Subtarget),
47     JITInfo(),
48     InstrItins(Subtarget.getInstrItineraryData()) {
49   DefRelocModel = getRelocationModel();
50 }
51
52 ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
53                                    const std::string &FS)
54   : ARMBaseTargetMachine(T, TT, FS, false), InstrInfo(Subtarget),
55     DataLayout(Subtarget.isAPCS_ABI() ?
56                std::string("e-p:32:32-f64:32:32-i64:32:32") :
57                std::string("e-p:32:32-f64:64:64-i64:64:64")),
58     TLInfo(*this) {
59 }
60
61 ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
62                                        const std::string &FS)
63   : ARMBaseTargetMachine(T, TT, FS, true),
64     DataLayout(Subtarget.isAPCS_ABI() ?
65                std::string("e-p:32:32-f64:32:32-i64:32:32-"
66                            "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
67                std::string("e-p:32:32-f64:64:64-i64:64:64-"
68                            "i16:16:32-i8:8:32-i1:8:32-a:0:32")),
69     TLInfo(*this) {
70   // Create the approriate type of Thumb InstrInfo
71   if (Subtarget.hasThumb2())
72     InstrInfo = new Thumb2InstrInfo(Subtarget);
73   else
74     InstrInfo = new Thumb1InstrInfo(Subtarget);
75 }
76
77
78 const TargetAsmInfo *ARMBaseTargetMachine::createTargetAsmInfo() const {
79   switch (Subtarget.TargetType) {
80   default: llvm_unreachable("Unknown ARM subtarget kind");
81   case ARMSubtarget::isDarwin:
82     return new ARMDarwinTargetAsmInfo();
83   case ARMSubtarget::isELF:
84     return new ARMELFTargetAsmInfo();
85   }
86 }
87
88
89 // Pass Pipeline Configuration
90 bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
91                                            CodeGenOpt::Level OptLevel) {
92   PM.add(createARMISelDag(*this));
93   return false;
94 }
95
96 bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
97                                           CodeGenOpt::Level OptLevel) {
98   if (Subtarget.hasNEON())
99     PM.add(createNEONPreAllocPass());
100
101   // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
102   if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb())
103     PM.add(createARMLoadStoreOptimizationPass(true));
104   return true;
105 }
106
107 bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
108                                           CodeGenOpt::Level OptLevel) {
109   // FIXME: temporarily disabling load / store optimization pass for Thumb1 mode.
110   if (OptLevel != CodeGenOpt::None && !DisableLdStOpti &&
111       !Subtarget.isThumb1Only())
112     PM.add(createARMLoadStoreOptimizationPass());
113
114   if (OptLevel != CodeGenOpt::None &&
115       !DisableIfConversion && !Subtarget.isThumb())
116     PM.add(createIfConverterPass());
117
118   if (Subtarget.isThumb2()) {
119     PM.add(createThumb2ITBlockPass());
120     if (Thumb2Shrink)
121       PM.add(createThumb2SizeReductionPass());
122   }
123
124   PM.add(createARMConstantIslandPass());
125   return true;
126 }
127
128 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
129                                           CodeGenOpt::Level OptLevel,
130                                           MachineCodeEmitter &MCE) {
131   // FIXME: Move this to TargetJITInfo!
132   if (DefRelocModel == Reloc::Default)
133     setRelocationModel(Reloc::Static);
134
135   // Machine code emitter pass for ARM.
136   PM.add(createARMCodeEmitterPass(*this, MCE));
137   return false;
138 }
139
140 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
141                                           CodeGenOpt::Level OptLevel,
142                                           JITCodeEmitter &JCE) {
143   // FIXME: Move this to TargetJITInfo!
144   if (DefRelocModel == Reloc::Default)
145     setRelocationModel(Reloc::Static);
146
147   // Machine code emitter pass for ARM.
148   PM.add(createARMJITCodeEmitterPass(*this, JCE));
149   return false;
150 }
151
152 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
153                                           CodeGenOpt::Level OptLevel,
154                                           ObjectCodeEmitter &OCE) {
155   // FIXME: Move this to TargetJITInfo!
156   if (DefRelocModel == Reloc::Default)
157     setRelocationModel(Reloc::Static);
158
159   // Machine code emitter pass for ARM.
160   PM.add(createARMObjectCodeEmitterPass(*this, OCE));
161   return false;
162 }
163
164 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
165                                                 CodeGenOpt::Level OptLevel,
166                                                 MachineCodeEmitter &MCE) {
167   // Machine code emitter pass for ARM.
168   PM.add(createARMCodeEmitterPass(*this, MCE));
169   return false;
170 }
171
172 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
173                                                 CodeGenOpt::Level OptLevel,
174                                                 JITCodeEmitter &JCE) {
175   // Machine code emitter pass for ARM.
176   PM.add(createARMJITCodeEmitterPass(*this, JCE));
177   return false;
178 }
179
180 bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
181                                             CodeGenOpt::Level OptLevel,
182                                             ObjectCodeEmitter &OCE) {
183   // Machine code emitter pass for ARM.
184   PM.add(createARMObjectCodeEmitterPass(*this, OCE));
185   return false;
186 }
187