]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302069, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / 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 "ARMRegisterBankInfo.h"
15 #include "ARMSubtarget.h"
16 #include "ARMTargetMachine.h"
17 #include "llvm/CodeGen/GlobalISel/InstructionSelector.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 namespace {
30
31 #define GET_GLOBALISEL_PREDICATE_BITSET
32 #include "ARMGenGlobalISel.inc"
33 #undef GET_GLOBALISEL_PREDICATE_BITSET
34
35 class ARMInstructionSelector : public InstructionSelector {
36 public:
37   ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
38                          const ARMRegisterBankInfo &RBI);
39
40   bool select(MachineInstr &I) const override;
41
42 private:
43   bool selectImpl(MachineInstr &I) const;
44
45   const ARMBaseInstrInfo &TII;
46   const ARMBaseRegisterInfo &TRI;
47   const ARMBaseTargetMachine &TM;
48   const ARMRegisterBankInfo &RBI;
49   const ARMSubtarget &STI;
50
51 #define GET_GLOBALISEL_PREDICATES_DECL
52 #include "ARMGenGlobalISel.inc"
53 #undef GET_GLOBALISEL_PREDICATES_DECL
54
55 // We declare the temporaries used by selectImpl() in the class to minimize the
56 // cost of constructing placeholder values.
57 #define GET_GLOBALISEL_TEMPORARIES_DECL
58 #include "ARMGenGlobalISel.inc"
59 #undef GET_GLOBALISEL_TEMPORARIES_DECL
60 };
61 } // end anonymous namespace
62
63 namespace llvm {
64 InstructionSelector *
65 createARMInstructionSelector(const ARMBaseTargetMachine &TM,
66                              const ARMSubtarget &STI,
67                              const ARMRegisterBankInfo &RBI) {
68   return new ARMInstructionSelector(TM, STI, RBI);
69 }
70 }
71
72 unsigned zero_reg = 0;
73
74 #define GET_GLOBALISEL_IMPL
75 #include "ARMGenGlobalISel.inc"
76 #undef GET_GLOBALISEL_IMPL
77
78 ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
79                                                const ARMSubtarget &STI,
80                                                const ARMRegisterBankInfo &RBI)
81     : InstructionSelector(), TII(*STI.getInstrInfo()),
82       TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI),
83 #define GET_GLOBALISEL_PREDICATES_INIT
84 #include "ARMGenGlobalISel.inc"
85 #undef GET_GLOBALISEL_PREDICATES_INIT
86 #define GET_GLOBALISEL_TEMPORARIES_INIT
87 #include "ARMGenGlobalISel.inc"
88 #undef GET_GLOBALISEL_TEMPORARIES_INIT
89 {
90 }
91
92 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
93                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
94                        const RegisterBankInfo &RBI) {
95   unsigned DstReg = I.getOperand(0).getReg();
96   if (TargetRegisterInfo::isPhysicalRegister(DstReg))
97     return true;
98
99   const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
100   (void)RegBank;
101   assert(RegBank && "Can't get reg bank for virtual register");
102
103   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
104   (void)DstSize;
105   unsigned SrcReg = I.getOperand(1).getReg();
106   const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
107   (void)SrcSize;
108   // We use copies for trunc, so it's ok for the size of the destination to be
109   // smaller (the higher bits will just be undefined).
110   assert(DstSize <= SrcSize && "Copy with different width?!");
111
112   assert((RegBank->getID() == ARM::GPRRegBankID ||
113           RegBank->getID() == ARM::FPRRegBankID) &&
114          "Unsupported reg bank");
115
116   const TargetRegisterClass *RC = &ARM::GPRRegClass;
117
118   if (RegBank->getID() == ARM::FPRRegBankID) {
119     if (DstSize == 32)
120       RC = &ARM::SPRRegClass;
121     else if (DstSize == 64)
122       RC = &ARM::DPRRegClass;
123     else
124       llvm_unreachable("Unsupported destination size");
125   }
126
127   // No need to constrain SrcReg. It will get constrained when
128   // we hit another of its uses or its defs.
129   // Copies do not have constraints.
130   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
131     DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
132                  << " operand\n");
133     return false;
134   }
135   return true;
136 }
137
138 static bool selectFAdd(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
139                        MachineRegisterInfo &MRI) {
140   assert(TII.getSubtarget().hasVFP2() && "Can't select fp add without vfp");
141
142   LLT Ty = MRI.getType(MIB->getOperand(0).getReg());
143   unsigned ValSize = Ty.getSizeInBits();
144
145   if (ValSize == 32) {
146     if (TII.getSubtarget().useNEONForSinglePrecisionFP())
147       return false;
148     MIB->setDesc(TII.get(ARM::VADDS));
149   } else {
150     assert(ValSize == 64 && "Unsupported size for floating point value");
151     if (TII.getSubtarget().isFPOnlySP())
152       return false;
153     MIB->setDesc(TII.get(ARM::VADDD));
154   }
155   MIB.add(predOps(ARMCC::AL));
156
157   return true;
158 }
159
160 static bool selectSequence(MachineInstrBuilder &MIB,
161                            const ARMBaseInstrInfo &TII,
162                            MachineRegisterInfo &MRI,
163                            const TargetRegisterInfo &TRI,
164                            const RegisterBankInfo &RBI) {
165   assert(TII.getSubtarget().hasVFP2() && "Can't select sequence without VFP");
166
167   // We only support G_SEQUENCE as a way to stick together two scalar GPRs
168   // into one DPR.
169   unsigned VReg0 = MIB->getOperand(0).getReg();
170   (void)VReg0;
171   assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
172          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
173          "Unsupported operand for G_SEQUENCE");
174   unsigned VReg1 = MIB->getOperand(1).getReg();
175   (void)VReg1;
176   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
177          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
178          "Unsupported operand for G_SEQUENCE");
179   unsigned VReg2 = MIB->getOperand(3).getReg();
180   (void)VReg2;
181   assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
182          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
183          "Unsupported operand for G_SEQUENCE");
184
185   // Remove the operands corresponding to the offsets.
186   MIB->RemoveOperand(4);
187   MIB->RemoveOperand(2);
188
189   MIB->setDesc(TII.get(ARM::VMOVDRR));
190   MIB.add(predOps(ARMCC::AL));
191
192   return true;
193 }
194
195 static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
196                           MachineRegisterInfo &MRI,
197                           const TargetRegisterInfo &TRI,
198                           const RegisterBankInfo &RBI) {
199   assert(TII.getSubtarget().hasVFP2() && "Can't select extract without VFP");
200
201   // We only support G_EXTRACT as a way to break up one DPR into two GPRs.
202   unsigned VReg0 = MIB->getOperand(0).getReg();
203   (void)VReg0;
204   assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
205          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
206          "Unsupported operand for G_EXTRACT");
207   unsigned VReg1 = MIB->getOperand(1).getReg();
208   (void)VReg1;
209   assert(MRI.getType(VReg1).getSizeInBits() == 64 &&
210          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::FPRRegBankID &&
211          "Unsupported operand for G_EXTRACT");
212   assert(MIB->getOperand(2).getImm() % 32 == 0 &&
213          "Unsupported operand for G_EXTRACT");
214
215   // Remove the operands corresponding to the offsets.
216   MIB->getOperand(2).setImm(MIB->getOperand(2).getImm() / 32);
217
218   MIB->setDesc(TII.get(ARM::VGETLNi32));
219   MIB.add(predOps(ARMCC::AL));
220
221   return true;
222 }
223
224 /// Select the opcode for simple extensions (that translate to a single SXT/UXT
225 /// instruction). Extension operations more complicated than that should not
226 /// invoke this. Returns the original opcode if it doesn't know how to select a
227 /// better one.
228 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
229   using namespace TargetOpcode;
230
231   if (Size != 8 && Size != 16)
232     return Opc;
233
234   if (Opc == G_SEXT)
235     return Size == 8 ? ARM::SXTB : ARM::SXTH;
236
237   if (Opc == G_ZEXT)
238     return Size == 8 ? ARM::UXTB : ARM::UXTH;
239
240   return Opc;
241 }
242
243 /// Select the opcode for simple loads and stores. For types smaller than 32
244 /// bits, the value will be zero extended. Returns the original opcode if it
245 /// doesn't know how to select a better one.
246 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
247                                       unsigned Size) {
248   bool isStore = Opc == TargetOpcode::G_STORE;
249
250   if (RegBank == ARM::GPRRegBankID) {
251     switch (Size) {
252     case 1:
253     case 8:
254       return isStore ? ARM::STRBi12 : ARM::LDRBi12;
255     case 16:
256       return isStore ? ARM::STRH : ARM::LDRH;
257     case 32:
258       return isStore ? ARM::STRi12 : ARM::LDRi12;
259     default:
260       return Opc;
261     }
262   }
263
264   if (RegBank == ARM::FPRRegBankID) {
265     switch (Size) {
266     case 32:
267       return isStore ? ARM::VSTRS : ARM::VLDRS;
268     case 64:
269       return isStore ? ARM::VSTRD : ARM::VLDRD;
270     default:
271       return Opc;
272     }
273   }
274
275   return Opc;
276 }
277
278 bool ARMInstructionSelector::select(MachineInstr &I) const {
279   assert(I.getParent() && "Instruction should be in a basic block!");
280   assert(I.getParent()->getParent() && "Instruction should be in a function!");
281
282   auto &MBB = *I.getParent();
283   auto &MF = *MBB.getParent();
284   auto &MRI = MF.getRegInfo();
285
286   if (!isPreISelGenericOpcode(I.getOpcode())) {
287     if (I.isCopy())
288       return selectCopy(I, TII, MRI, TRI, RBI);
289
290     return true;
291   }
292
293   if (selectImpl(I))
294     return true;
295
296   MachineInstrBuilder MIB{MF, I};
297   bool isSExt = false;
298
299   using namespace TargetOpcode;
300   switch (I.getOpcode()) {
301   case G_SEXT:
302     isSExt = true;
303     LLVM_FALLTHROUGH;
304   case G_ZEXT: {
305     LLT DstTy = MRI.getType(I.getOperand(0).getReg());
306     // FIXME: Smaller destination sizes coming soon!
307     if (DstTy.getSizeInBits() != 32) {
308       DEBUG(dbgs() << "Unsupported destination size for extension");
309       return false;
310     }
311
312     LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
313     unsigned SrcSize = SrcTy.getSizeInBits();
314     switch (SrcSize) {
315     case 1: {
316       // ZExt boils down to & 0x1; for SExt we also subtract that from 0
317       I.setDesc(TII.get(ARM::ANDri));
318       MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
319
320       if (isSExt) {
321         unsigned SExtResult = I.getOperand(0).getReg();
322
323         // Use a new virtual register for the result of the AND
324         unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
325         I.getOperand(0).setReg(AndResult);
326
327         auto InsertBefore = std::next(I.getIterator());
328         auto SubI =
329             BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
330                 .addDef(SExtResult)
331                 .addUse(AndResult)
332                 .addImm(0)
333                 .add(predOps(ARMCC::AL))
334                 .add(condCodeOp());
335         if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
336           return false;
337       }
338       break;
339     }
340     case 8:
341     case 16: {
342       unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
343       if (NewOpc == I.getOpcode())
344         return false;
345       I.setDesc(TII.get(NewOpc));
346       MIB.addImm(0).add(predOps(ARMCC::AL));
347       break;
348     }
349     default:
350       DEBUG(dbgs() << "Unsupported source size for extension");
351       return false;
352     }
353     break;
354   }
355   case G_TRUNC: {
356     // The high bits are undefined, so there's nothing special to do, just
357     // treat it as a copy.
358     auto SrcReg = I.getOperand(1).getReg();
359     auto DstReg = I.getOperand(0).getReg();
360
361     const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
362     const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
363
364     if (SrcRegBank.getID() != DstRegBank.getID()) {
365       DEBUG(dbgs() << "G_TRUNC operands on different register banks\n");
366       return false;
367     }
368
369     if (SrcRegBank.getID() != ARM::GPRRegBankID) {
370       DEBUG(dbgs() << "G_TRUNC on non-GPR not supported yet\n");
371       return false;
372     }
373
374     I.setDesc(TII.get(COPY));
375     return selectCopy(I, TII, MRI, TRI, RBI);
376   }
377   case G_ADD:
378   case G_GEP:
379     I.setDesc(TII.get(ARM::ADDrr));
380     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
381     break;
382   case G_SUB:
383     I.setDesc(TII.get(ARM::SUBrr));
384     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
385     break;
386   case G_MUL:
387     if (TII.getSubtarget().hasV6Ops()) {
388       I.setDesc(TII.get(ARM::MUL));
389     } else {
390       assert(TII.getSubtarget().useMulOps() && "Unsupported target");
391       I.setDesc(TII.get(ARM::MULv5));
392       MIB->getOperand(0).setIsEarlyClobber(true);
393     }
394     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
395     break;
396   case G_FADD:
397     if (!selectFAdd(MIB, TII, MRI))
398       return false;
399     break;
400   case G_FRAME_INDEX:
401     // Add 0 to the given frame index and hope it will eventually be folded into
402     // the user(s).
403     I.setDesc(TII.get(ARM::ADDri));
404     MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
405     break;
406   case G_CONSTANT: {
407     unsigned Reg = I.getOperand(0).getReg();
408     if (MRI.getType(Reg).getSizeInBits() != 32)
409       return false;
410
411     assert(RBI.getRegBank(Reg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
412            "Expected constant to live in a GPR");
413     I.setDesc(TII.get(ARM::MOVi));
414     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
415
416     auto &Val = I.getOperand(1);
417     if (Val.isCImm()) {
418       if (Val.getCImm()->getBitWidth() > 32)
419         return false;
420       Val.ChangeToImmediate(Val.getCImm()->getZExtValue());
421     }
422
423     if (!Val.isImm()) {
424       return false;
425     }
426
427     break;
428   }
429   case G_STORE:
430   case G_LOAD: {
431     const auto &MemOp = **I.memoperands_begin();
432     if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
433       DEBUG(dbgs() << "Atomic load/store not supported yet\n");
434       return false;
435     }
436
437     unsigned Reg = I.getOperand(0).getReg();
438     unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
439
440     LLT ValTy = MRI.getType(Reg);
441     const auto ValSize = ValTy.getSizeInBits();
442
443     assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) &&
444            "Don't know how to load/store 64-bit value without VFP");
445
446     const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
447     if (NewOpc == G_LOAD || NewOpc == G_STORE)
448       return false;
449
450     I.setDesc(TII.get(NewOpc));
451
452     if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
453       // LDRH has a funny addressing mode (there's already a FIXME for it).
454       MIB.addReg(0);
455     MIB.addImm(0).add(predOps(ARMCC::AL));
456     break;
457   }
458   case G_SEQUENCE: {
459     if (!selectSequence(MIB, TII, MRI, TRI, RBI))
460       return false;
461     break;
462   }
463   case G_EXTRACT: {
464     if (!selectExtract(MIB, TII, MRI, TRI, RBI))
465       return false;
466     break;
467   }
468   default:
469     return false;
470   }
471
472   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
473 }