blob: a1fc89a47281bdab0e65d5d7822310f5fc9411f9 [file] [log] [blame]
Eric Christopherab695882010-07-21 22:26:11 +00001//===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===//
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// This file defines the ARM-specific support for the FastISel class. Some
11// of the target-specific code is generated by tablegen in the file
12// ARMGenFastISel.inc, which is #included here.
13//
14//===----------------------------------------------------------------------===//
15
16#include "ARM.h"
17#include "ARMRegisterInfo.h"
18#include "ARMTargetMachine.h"
19#include "ARMSubtarget.h"
20#include "llvm/CallingConv.h"
21#include "llvm/DerivedTypes.h"
22#include "llvm/GlobalVariable.h"
23#include "llvm/Instructions.h"
24#include "llvm/IntrinsicInst.h"
25#include "llvm/CodeGen/Analysis.h"
26#include "llvm/CodeGen/FastISel.h"
27#include "llvm/CodeGen/FunctionLoweringInfo.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000028#include "llvm/CodeGen/MachineInstrBuilder.h"
29#include "llvm/CodeGen/MachineModuleInfo.h"
Eric Christopherab695882010-07-21 22:26:11 +000030#include "llvm/CodeGen/MachineConstantPool.h"
31#include "llvm/CodeGen/MachineFrameInfo.h"
32#include "llvm/CodeGen/MachineRegisterInfo.h"
33#include "llvm/Support/CallSite.h"
Eric Christopher038fea52010-08-17 00:46:57 +000034#include "llvm/Support/CommandLine.h"
Eric Christopherab695882010-07-21 22:26:11 +000035#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/GetElementPtrTypeIterator.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000037#include "llvm/Target/TargetData.h"
38#include "llvm/Target/TargetInstrInfo.h"
39#include "llvm/Target/TargetLowering.h"
40#include "llvm/Target/TargetMachine.h"
Eric Christopherab695882010-07-21 22:26:11 +000041#include "llvm/Target/TargetOptions.h"
42using namespace llvm;
43
Eric Christopher038fea52010-08-17 00:46:57 +000044static cl::opt<bool>
45EnableARMFastISel("arm-fast-isel",
46 cl::desc("Turn on experimental ARM fast-isel support"),
47 cl::init(false), cl::Hidden);
48
Eric Christopherab695882010-07-21 22:26:11 +000049namespace {
50
51class ARMFastISel : public FastISel {
52
53 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
54 /// make the right decision when generating code for different targets.
55 const ARMSubtarget *Subtarget;
Eric Christopher0fe7d542010-08-17 01:25:29 +000056 const TargetMachine &TM;
57 const TargetInstrInfo &TII;
58 const TargetLowering &TLI;
Eric Christopherab695882010-07-21 22:26:11 +000059
60 public:
Eric Christopher0fe7d542010-08-17 01:25:29 +000061 explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
62 : FastISel(funcInfo),
63 TM(funcInfo.MF->getTarget()),
64 TII(*TM.getInstrInfo()),
65 TLI(*TM.getTargetLowering()) {
Eric Christopherab695882010-07-21 22:26:11 +000066 Subtarget = &TM.getSubtarget<ARMSubtarget>();
67 }
68
Eric Christopher0fe7d542010-08-17 01:25:29 +000069 virtual unsigned FastEmitInst_(unsigned MachineInstOpcode,
70 const TargetRegisterClass *RC);
71 virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode,
72 const TargetRegisterClass *RC,
73 unsigned Op0, bool Op0IsKill);
74 virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
75 const TargetRegisterClass *RC,
76 unsigned Op0, bool Op0IsKill,
77 unsigned Op1, bool Op1IsKill);
78 virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
79 const TargetRegisterClass *RC,
80 unsigned Op0, bool Op0IsKill,
81 uint64_t Imm);
82 virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
83 const TargetRegisterClass *RC,
84 unsigned Op0, bool Op0IsKill,
85 const ConstantFP *FPImm);
86 virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode,
87 const TargetRegisterClass *RC,
88 uint64_t Imm);
89 virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
90 const TargetRegisterClass *RC,
91 unsigned Op0, bool Op0IsKill,
92 unsigned Op1, bool Op1IsKill,
93 uint64_t Imm);
94 virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
95 unsigned Op0, bool Op0IsKill,
96 uint32_t Idx);
Eric Christopherab695882010-07-21 22:26:11 +000097 virtual bool TargetSelectInstruction(const Instruction *I);
98
99 #include "ARMGenFastISel.inc"
100
101 };
102
103} // end anonymous namespace
104
105// #include "ARMGenCallingConv.inc"
106
Eric Christopher0fe7d542010-08-17 01:25:29 +0000107unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
108 const TargetRegisterClass* RC) {
109 unsigned ResultReg = createResultReg(RC);
110 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
111
112 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
113 return ResultReg;
114}
115
116unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
117 const TargetRegisterClass *RC,
118 unsigned Op0, bool Op0IsKill) {
119 unsigned ResultReg = createResultReg(RC);
120 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
121
122 if (II.getNumDefs() >= 1)
123 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
124 .addReg(Op0, Op0IsKill * RegState::Kill));
125 else {
126 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
127 .addReg(Op0, Op0IsKill * RegState::Kill));
128 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
129 TII.get(TargetOpcode::COPY), ResultReg)
130 .addReg(II.ImplicitDefs[0]));
131 }
132 return ResultReg;
133}
134
135unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
136 const TargetRegisterClass *RC,
137 unsigned Op0, bool Op0IsKill,
138 unsigned Op1, bool Op1IsKill) {
139 unsigned ResultReg = createResultReg(RC);
140 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
141
142 if (II.getNumDefs() >= 1)
143 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
144 .addReg(Op0, Op0IsKill * RegState::Kill)
145 .addReg(Op1, Op1IsKill * RegState::Kill));
146 else {
147 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
148 .addReg(Op0, Op0IsKill * RegState::Kill)
149 .addReg(Op1, Op1IsKill * RegState::Kill));
150 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
151 TII.get(TargetOpcode::COPY), ResultReg)
152 .addReg(II.ImplicitDefs[0]));
153 }
154 return ResultReg;
155}
156
157unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
158 const TargetRegisterClass *RC,
159 unsigned Op0, bool Op0IsKill,
160 uint64_t Imm) {
161 unsigned ResultReg = createResultReg(RC);
162 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
163
164 if (II.getNumDefs() >= 1)
165 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
166 .addReg(Op0, Op0IsKill * RegState::Kill)
167 .addImm(Imm));
168 else {
169 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
170 .addReg(Op0, Op0IsKill * RegState::Kill)
171 .addImm(Imm));
172 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
173 TII.get(TargetOpcode::COPY), ResultReg)
174 .addReg(II.ImplicitDefs[0]));
175 }
176 return ResultReg;
177}
178
179unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
180 const TargetRegisterClass *RC,
181 unsigned Op0, bool Op0IsKill,
182 const ConstantFP *FPImm) {
183 unsigned ResultReg = createResultReg(RC);
184 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
185
186 if (II.getNumDefs() >= 1)
187 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
188 .addReg(Op0, Op0IsKill * RegState::Kill)
189 .addFPImm(FPImm));
190 else {
191 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
192 .addReg(Op0, Op0IsKill * RegState::Kill)
193 .addFPImm(FPImm));
194 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
195 TII.get(TargetOpcode::COPY), ResultReg)
196 .addReg(II.ImplicitDefs[0]));
197 }
198 return ResultReg;
199}
200
201unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
202 const TargetRegisterClass *RC,
203 unsigned Op0, bool Op0IsKill,
204 unsigned Op1, bool Op1IsKill,
205 uint64_t Imm) {
206 unsigned ResultReg = createResultReg(RC);
207 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
208
209 if (II.getNumDefs() >= 1)
210 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
211 .addReg(Op0, Op0IsKill * RegState::Kill)
212 .addReg(Op1, Op1IsKill * RegState::Kill)
213 .addImm(Imm));
214 else {
215 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
216 .addReg(Op0, Op0IsKill * RegState::Kill)
217 .addReg(Op1, Op1IsKill * RegState::Kill)
218 .addImm(Imm));
219 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
220 TII.get(TargetOpcode::COPY), ResultReg)
221 .addReg(II.ImplicitDefs[0]));
222 }
223 return ResultReg;
224}
225
226unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
227 const TargetRegisterClass *RC,
228 uint64_t Imm) {
229 unsigned ResultReg = createResultReg(RC);
230 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
231
232 if (II.getNumDefs() >= 1)
233 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
234 .addImm(Imm));
235 else {
236 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
237 .addImm(Imm));
238 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
239 TII.get(TargetOpcode::COPY), ResultReg)
240 .addReg(II.ImplicitDefs[0]));
241 }
242 return ResultReg;
243}
244
245unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
246 unsigned Op0, bool Op0IsKill,
247 uint32_t Idx) {
248 unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
249 assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
250 "Cannot yet extract from physregs");
251 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
252 DL, TII.get(TargetOpcode::COPY), ResultReg)
253 .addReg(Op0, getKillRegState(Op0IsKill), Idx));
254 return ResultReg;
255}
256
Eric Christopherab695882010-07-21 22:26:11 +0000257bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
258 switch (I->getOpcode()) {
259 default: break;
260 }
261 return false;
262}
263
264namespace llvm {
265 llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
Eric Christopher038fea52010-08-17 00:46:57 +0000266 if (EnableARMFastISel) return new ARMFastISel(funcInfo);
Evan Cheng09447952010-07-26 18:32:55 +0000267 return 0;
Eric Christopherab695882010-07-21 22:26:11 +0000268 }
269}