1 //===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===//
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 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
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"
28 #include "llvm/CodeGen/MachineInstrBuilder.h"
29 #include "llvm/CodeGen/MachineModuleInfo.h"
30 #include "llvm/CodeGen/MachineConstantPool.h"
31 #include "llvm/CodeGen/MachineFrameInfo.h"
32 #include "llvm/CodeGen/MachineRegisterInfo.h"
33 #include "llvm/Support/CallSite.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/ErrorHandling.h"
36 #include "llvm/Support/GetElementPtrTypeIterator.h"
37 #include "llvm/Target/TargetData.h"
38 #include "llvm/Target/TargetInstrInfo.h"
39 #include "llvm/Target/TargetLowering.h"
40 #include "llvm/Target/TargetMachine.h"
41 #include "llvm/Target/TargetOptions.h"
45 EnableARMFastISel("arm-fast-isel",
46 cl::desc("Turn on experimental ARM fast-isel support"),
47 cl::init(false), cl::Hidden);
51 class ARMFastISel : public FastISel {
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;
56 const TargetMachine &TM;
57 const TargetInstrInfo &TII;
58 const TargetLowering &TLI;
61 explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
63 TM(funcInfo.MF->getTarget()),
64 TII(*TM.getInstrInfo()),
65 TLI(*TM.getTargetLowering()) {
66 Subtarget = &TM.getSubtarget<ARMSubtarget>();
69 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,
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,
89 virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
90 const TargetRegisterClass *RC,
91 unsigned Op0, bool Op0IsKill,
92 unsigned Op1, bool Op1IsKill,
94 virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
95 unsigned Op0, bool Op0IsKill,
97 virtual bool TargetSelectInstruction(const Instruction *I);
99 #include "ARMGenFastISel.inc"
103 } // end anonymous namespace
105 // #include "ARMGenCallingConv.inc"
107 unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
108 const TargetRegisterClass* RC) {
109 unsigned ResultReg = createResultReg(RC);
110 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
112 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
116 unsigned 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);
122 if (II.getNumDefs() >= 1)
123 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
124 .addReg(Op0, Op0IsKill * RegState::Kill));
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]));
135 unsigned 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);
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));
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]));
157 unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
158 const TargetRegisterClass *RC,
159 unsigned Op0, bool Op0IsKill,
161 unsigned ResultReg = createResultReg(RC);
162 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
164 if (II.getNumDefs() >= 1)
165 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
166 .addReg(Op0, Op0IsKill * RegState::Kill)
169 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
170 .addReg(Op0, Op0IsKill * RegState::Kill)
172 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
173 TII.get(TargetOpcode::COPY), ResultReg)
174 .addReg(II.ImplicitDefs[0]));
179 unsigned 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);
186 if (II.getNumDefs() >= 1)
187 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
188 .addReg(Op0, Op0IsKill * RegState::Kill)
191 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
192 .addReg(Op0, Op0IsKill * RegState::Kill)
194 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
195 TII.get(TargetOpcode::COPY), ResultReg)
196 .addReg(II.ImplicitDefs[0]));
201 unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
202 const TargetRegisterClass *RC,
203 unsigned Op0, bool Op0IsKill,
204 unsigned Op1, bool Op1IsKill,
206 unsigned ResultReg = createResultReg(RC);
207 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
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)
215 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
216 .addReg(Op0, Op0IsKill * RegState::Kill)
217 .addReg(Op1, Op1IsKill * RegState::Kill)
219 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
220 TII.get(TargetOpcode::COPY), ResultReg)
221 .addReg(II.ImplicitDefs[0]));
226 unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
227 const TargetRegisterClass *RC,
229 unsigned ResultReg = createResultReg(RC);
230 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
232 if (II.getNumDefs() >= 1)
233 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
236 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
238 AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
239 TII.get(TargetOpcode::COPY), ResultReg)
240 .addReg(II.ImplicitDefs[0]));
245 unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
246 unsigned Op0, bool Op0IsKill,
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));
257 bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
258 switch (I->getOpcode()) {
265 llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
266 if (EnableARMFastISel) return new ARMFastISel(funcInfo);