80 column cleanup.
[oota-llvm.git] / lib / Target / ARM / ARMFastISel.cpp
1 //===-- 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"
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"
42 using namespace llvm;
43
44 static cl::opt<bool>
45 EnableARMFastISel("arm-fast-isel",
46                   cl::desc("Turn on experimental ARM fast-isel support"),
47                   cl::init(false), cl::Hidden);
48
49 namespace {
50
51 class 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;
56   const TargetMachine &TM;
57   const TargetInstrInfo &TII;
58   const TargetLowering &TLI;
59
60   public:
61     explicit ARMFastISel(FunctionLoweringInfo &funcInfo) 
62     : FastISel(funcInfo),
63       TM(funcInfo.MF->getTarget()),
64       TII(*TM.getInstrInfo()),
65       TLI(*TM.getTargetLowering()) {
66       Subtarget = &TM.getSubtarget<ARMSubtarget>();
67     }
68
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,
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);
97     virtual bool TargetSelectInstruction(const Instruction *I);
98
99   #include "ARMGenFastISel.inc"
100
101   };
102
103 } // end anonymous namespace
104
105 // #include "ARMGenCallingConv.inc"
106
107 unsigned 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
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);
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
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);
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
157 unsigned 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
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);
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
201 unsigned 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
226 unsigned 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
245 unsigned 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
257 bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
258   switch (I->getOpcode()) {
259     default: break;
260   }
261   return false;
262 }
263
264 namespace llvm {
265   llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
266     if (EnableARMFastISel) return new ARMFastISel(funcInfo);
267     return 0;
268   }
269 }