OSDN Git Service

[ARM] GlobalISel: Select 32-bit G_CONSTANT
[android-x86/external-llvm.git] / lib / Target / ARM / ARMInstructionSelector.cpp
1 //===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==//
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 /// \file
10 /// This file implements the targeting of the InstructionSelector class for ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13
14 #include "ARMInstructionSelector.h"
15 #include "ARMRegisterBankInfo.h"
16 #include "ARMSubtarget.h"
17 #include "ARMTargetMachine.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/Support/Debug.h"
20
21 #define DEBUG_TYPE "arm-isel"
22
23 using namespace llvm;
24
25 #ifndef LLVM_BUILD_GLOBAL_ISEL
26 #error "You shouldn't build this"
27 #endif
28
29 ARMInstructionSelector::ARMInstructionSelector(const ARMSubtarget &STI,
30                                                const ARMRegisterBankInfo &RBI)
31     : InstructionSelector(), TII(*STI.getInstrInfo()),
32       TRI(*STI.getRegisterInfo()), RBI(RBI) {}
33
34 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
35                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
36                        const RegisterBankInfo &RBI) {
37   unsigned DstReg = I.getOperand(0).getReg();
38   if (TargetRegisterInfo::isPhysicalRegister(DstReg))
39     return true;
40
41   const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
42   (void)RegBank;
43   assert(RegBank && "Can't get reg bank for virtual register");
44
45   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
46   (void)DstSize;
47   unsigned SrcReg = I.getOperand(1).getReg();
48   const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
49   (void)SrcSize;
50   assert((DstSize == SrcSize ||
51           // Copies are a means to setup initial types, the number of
52           // bits may not exactly match.
53           (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
54            DstSize <= SrcSize)) &&
55          "Copy with different width?!");
56
57   assert((RegBank->getID() == ARM::GPRRegBankID ||
58           RegBank->getID() == ARM::FPRRegBankID) &&
59          "Unsupported reg bank");
60
61   const TargetRegisterClass *RC = &ARM::GPRRegClass;
62
63   if (RegBank->getID() == ARM::FPRRegBankID) {
64     if (DstSize == 32)
65       RC = &ARM::SPRRegClass;
66     else if (DstSize == 64)
67       RC = &ARM::DPRRegClass;
68     else
69       llvm_unreachable("Unsupported destination size");
70   }
71
72   // No need to constrain SrcReg. It will get constrained when
73   // we hit another of its uses or its defs.
74   // Copies do not have constraints.
75   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
76     DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
77                  << " operand\n");
78     return false;
79   }
80   return true;
81 }
82
83 static bool selectFAdd(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
84                        MachineRegisterInfo &MRI) {
85   assert(TII.getSubtarget().hasVFP2() && "Can't select fp add without vfp");
86
87   LLT Ty = MRI.getType(MIB->getOperand(0).getReg());
88   unsigned ValSize = Ty.getSizeInBits();
89
90   if (ValSize == 32) {
91     if (TII.getSubtarget().useNEONForSinglePrecisionFP())
92       return false;
93     MIB->setDesc(TII.get(ARM::VADDS));
94   } else {
95     assert(ValSize == 64 && "Unsupported size for floating point value");
96     if (TII.getSubtarget().isFPOnlySP())
97       return false;
98     MIB->setDesc(TII.get(ARM::VADDD));
99   }
100   MIB.add(predOps(ARMCC::AL));
101
102   return true;
103 }
104
105 static bool selectSequence(MachineInstrBuilder &MIB,
106                            const ARMBaseInstrInfo &TII,
107                            MachineRegisterInfo &MRI,
108                            const TargetRegisterInfo &TRI,
109                            const RegisterBankInfo &RBI) {
110   assert(TII.getSubtarget().hasVFP2() && "Can't select sequence without VFP");
111
112   // We only support G_SEQUENCE as a way to stick together two scalar GPRs
113   // into one DPR.
114   unsigned VReg0 = MIB->getOperand(0).getReg();
115   (void)VReg0;
116   assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
117          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
118          "Unsupported operand for G_SEQUENCE");
119   unsigned VReg1 = MIB->getOperand(1).getReg();
120   (void)VReg1;
121   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
122          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
123          "Unsupported operand for G_SEQUENCE");
124   unsigned VReg2 = MIB->getOperand(3).getReg();
125   (void)VReg2;
126   assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
127          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
128          "Unsupported operand for G_SEQUENCE");
129
130   // Remove the operands corresponding to the offsets.
131   MIB->RemoveOperand(4);
132   MIB->RemoveOperand(2);
133
134   MIB->setDesc(TII.get(ARM::VMOVDRR));
135   MIB.add(predOps(ARMCC::AL));
136
137   return true;
138 }
139
140 static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
141                           MachineRegisterInfo &MRI,
142                           const TargetRegisterInfo &TRI,
143                           const RegisterBankInfo &RBI) {
144   assert(TII.getSubtarget().hasVFP2() && "Can't select extract without VFP");
145
146   // We only support G_EXTRACT as a way to break up one DPR into two GPRs.
147   unsigned VReg0 = MIB->getOperand(0).getReg();
148   (void)VReg0;
149   assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
150          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
151          "Unsupported operand for G_SEQUENCE");
152   unsigned VReg1 = MIB->getOperand(1).getReg();
153   (void)VReg1;
154   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
155          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
156          "Unsupported operand for G_SEQUENCE");
157   unsigned VReg2 = MIB->getOperand(2).getReg();
158   (void)VReg2;
159   assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
160          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
161          "Unsupported operand for G_SEQUENCE");
162
163   // Remove the operands corresponding to the offsets.
164   MIB->RemoveOperand(4);
165   MIB->RemoveOperand(3);
166
167   MIB->setDesc(TII.get(ARM::VMOVRRD));
168   MIB.add(predOps(ARMCC::AL));
169
170   return true;
171 }
172
173 /// Select the opcode for simple extensions (that translate to a single SXT/UXT
174 /// instruction). Extension operations more complicated than that should not
175 /// invoke this. Returns the original opcode if it doesn't know how to select a
176 /// better one.
177 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
178   using namespace TargetOpcode;
179
180   if (Size != 8 && Size != 16)
181     return Opc;
182
183   if (Opc == G_SEXT)
184     return Size == 8 ? ARM::SXTB : ARM::SXTH;
185
186   if (Opc == G_ZEXT)
187     return Size == 8 ? ARM::UXTB : ARM::UXTH;
188
189   return Opc;
190 }
191
192 /// Select the opcode for simple loads and stores. For types smaller than 32
193 /// bits, the value will be zero extended. Returns the original opcode if it
194 /// doesn't know how to select a better one.
195 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
196                                       unsigned Size) {
197   bool isStore = Opc == TargetOpcode::G_STORE;
198
199   if (RegBank == ARM::GPRRegBankID) {
200     switch (Size) {
201     case 1:
202     case 8:
203       return isStore ? ARM::STRBi12 : ARM::LDRBi12;
204     case 16:
205       return isStore ? ARM::STRH : ARM::LDRH;
206     case 32:
207       return isStore ? ARM::STRi12 : ARM::LDRi12;
208     default:
209       return Opc;
210     }
211   }
212
213   if (RegBank == ARM::FPRRegBankID) {
214     switch (Size) {
215     case 32:
216       return isStore ? ARM::VSTRS : ARM::VLDRS;
217     case 64:
218       return isStore ? ARM::VSTRD : ARM::VLDRD;
219     default:
220       return Opc;
221     }
222   }
223
224   return Opc;
225 }
226
227 bool ARMInstructionSelector::select(MachineInstr &I) const {
228   assert(I.getParent() && "Instruction should be in a basic block!");
229   assert(I.getParent()->getParent() && "Instruction should be in a function!");
230
231   auto &MBB = *I.getParent();
232   auto &MF = *MBB.getParent();
233   auto &MRI = MF.getRegInfo();
234
235   if (!isPreISelGenericOpcode(I.getOpcode())) {
236     if (I.isCopy())
237       return selectCopy(I, TII, MRI, TRI, RBI);
238
239     return true;
240   }
241
242   MachineInstrBuilder MIB{MF, I};
243   bool isSExt = false;
244
245   using namespace TargetOpcode;
246   switch (I.getOpcode()) {
247   case G_SEXT:
248     isSExt = true;
249     LLVM_FALLTHROUGH;
250   case G_ZEXT: {
251     LLT DstTy = MRI.getType(I.getOperand(0).getReg());
252     // FIXME: Smaller destination sizes coming soon!
253     if (DstTy.getSizeInBits() != 32) {
254       DEBUG(dbgs() << "Unsupported destination size for extension");
255       return false;
256     }
257
258     LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
259     unsigned SrcSize = SrcTy.getSizeInBits();
260     switch (SrcSize) {
261     case 1: {
262       // ZExt boils down to & 0x1; for SExt we also subtract that from 0
263       I.setDesc(TII.get(ARM::ANDri));
264       MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
265
266       if (isSExt) {
267         unsigned SExtResult = I.getOperand(0).getReg();
268
269         // Use a new virtual register for the result of the AND
270         unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
271         I.getOperand(0).setReg(AndResult);
272
273         auto InsertBefore = std::next(I.getIterator());
274         auto SubI =
275             BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
276                 .addDef(SExtResult)
277                 .addUse(AndResult)
278                 .addImm(0)
279                 .add(predOps(ARMCC::AL))
280                 .add(condCodeOp());
281         if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
282           return false;
283       }
284       break;
285     }
286     case 8:
287     case 16: {
288       unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
289       if (NewOpc == I.getOpcode())
290         return false;
291       I.setDesc(TII.get(NewOpc));
292       MIB.addImm(0).add(predOps(ARMCC::AL));
293       break;
294     }
295     default:
296       DEBUG(dbgs() << "Unsupported source size for extension");
297       return false;
298     }
299     break;
300   }
301   case G_ADD:
302   case G_GEP:
303     I.setDesc(TII.get(ARM::ADDrr));
304     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
305     break;
306   case G_FADD:
307     if (!selectFAdd(MIB, TII, MRI))
308       return false;
309     break;
310   case G_FRAME_INDEX:
311     // Add 0 to the given frame index and hope it will eventually be folded into
312     // the user(s).
313     I.setDesc(TII.get(ARM::ADDri));
314     MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
315     break;
316   case G_CONSTANT: {
317     unsigned Reg = I.getOperand(0).getReg();
318     if (MRI.getType(Reg).getSizeInBits() != 32)
319       return false;
320
321     assert(RBI.getRegBank(Reg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
322            "Expected constant to live in a GPR");
323     I.setDesc(TII.get(ARM::MOVi));
324     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
325     break;
326   }
327   case G_STORE:
328   case G_LOAD: {
329     const auto &MemOp = **I.memoperands_begin();
330     if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
331       DEBUG(dbgs() << "Atomic load/store not supported yet\n");
332       return false;
333     }
334
335     unsigned Reg = I.getOperand(0).getReg();
336     unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
337
338     LLT ValTy = MRI.getType(Reg);
339     const auto ValSize = ValTy.getSizeInBits();
340
341     assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) &&
342            "Don't know how to load/store 64-bit value without VFP");
343
344     const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
345     if (NewOpc == G_LOAD || NewOpc == G_STORE)
346       return false;
347
348     I.setDesc(TII.get(NewOpc));
349
350     if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
351       // LDRH has a funny addressing mode (there's already a FIXME for it).
352       MIB.addReg(0);
353     MIB.addImm(0).add(predOps(ARMCC::AL));
354     break;
355   }
356   case G_SEQUENCE: {
357     if (!selectSequence(MIB, TII, MRI, TRI, RBI))
358       return false;
359     break;
360   }
361   case G_EXTRACT: {
362     if (!selectExtract(MIB, TII, MRI, TRI, RBI))
363       return false;
364     break;
365   }
366   default:
367     return false;
368   }
369
370   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
371 }