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 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
24 
25 using namespace llvm;
26 
27 #ifndef LLVM_BUILD_GLOBAL_ISEL
28 #error "You shouldn't build this"
29 #endif
30 
31 namespace {
32 
33 #define GET_GLOBALISEL_PREDICATE_BITSET
34 #include "ARMGenGlobalISel.inc"
35 #undef GET_GLOBALISEL_PREDICATE_BITSET
36 
37 class ARMInstructionSelector : public InstructionSelector {
38 public:
39   ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
40                          const ARMRegisterBankInfo &RBI);
41 
42   bool select(MachineInstr &I) const override;
43 
44 private:
45   bool selectImpl(MachineInstr &I) const;
46 
47   template <typename T> struct CmpHelper;
48 
49   template <typename T>
50   bool selectCmp(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
51                  MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
52                  const RegisterBankInfo &RBI) const;
53 
54   bool selectSelect(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
55                     MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
56                     const RegisterBankInfo &RBI) const;
57 
58   const ARMBaseInstrInfo &TII;
59   const ARMBaseRegisterInfo &TRI;
60   const ARMBaseTargetMachine &TM;
61   const ARMRegisterBankInfo &RBI;
62   const ARMSubtarget &STI;
63 
64 #define GET_GLOBALISEL_PREDICATES_DECL
65 #include "ARMGenGlobalISel.inc"
66 #undef GET_GLOBALISEL_PREDICATES_DECL
67 
68 // We declare the temporaries used by selectImpl() in the class to minimize the
69 // cost of constructing placeholder values.
70 #define GET_GLOBALISEL_TEMPORARIES_DECL
71 #include "ARMGenGlobalISel.inc"
72 #undef GET_GLOBALISEL_TEMPORARIES_DECL
73 };
74 } // end anonymous namespace
75 
76 namespace llvm {
77 InstructionSelector *
78 createARMInstructionSelector(const ARMBaseTargetMachine &TM,
79                              const ARMSubtarget &STI,
80                              const ARMRegisterBankInfo &RBI) {
81   return new ARMInstructionSelector(TM, STI, RBI);
82 }
83 }
84 
85 unsigned zero_reg = 0;
86 
87 #define GET_GLOBALISEL_IMPL
88 #include "ARMGenGlobalISel.inc"
89 #undef GET_GLOBALISEL_IMPL
90 
91 ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
92                                                const ARMSubtarget &STI,
93                                                const ARMRegisterBankInfo &RBI)
94     : InstructionSelector(), TII(*STI.getInstrInfo()),
95       TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI),
96 #define GET_GLOBALISEL_PREDICATES_INIT
97 #include "ARMGenGlobalISel.inc"
98 #undef GET_GLOBALISEL_PREDICATES_INIT
99 #define GET_GLOBALISEL_TEMPORARIES_INIT
100 #include "ARMGenGlobalISel.inc"
101 #undef GET_GLOBALISEL_TEMPORARIES_INIT
102 {
103 }
104 
105 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
106                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
107                        const RegisterBankInfo &RBI) {
108   unsigned DstReg = I.getOperand(0).getReg();
109   if (TargetRegisterInfo::isPhysicalRegister(DstReg))
110     return true;
111 
112   const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
113   (void)RegBank;
114   assert(RegBank && "Can't get reg bank for virtual register");
115 
116   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
117   assert((RegBank->getID() == ARM::GPRRegBankID ||
118           RegBank->getID() == ARM::FPRRegBankID) &&
119          "Unsupported reg bank");
120 
121   const TargetRegisterClass *RC = &ARM::GPRRegClass;
122 
123   if (RegBank->getID() == ARM::FPRRegBankID) {
124     if (DstSize == 32)
125       RC = &ARM::SPRRegClass;
126     else if (DstSize == 64)
127       RC = &ARM::DPRRegClass;
128     else
129       llvm_unreachable("Unsupported destination size");
130   }
131 
132   // No need to constrain SrcReg. It will get constrained when
133   // we hit another of its uses or its defs.
134   // Copies do not have constraints.
135   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
136     DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
137                  << " operand\n");
138     return false;
139   }
140   return true;
141 }
142 
143 static bool selectMergeValues(MachineInstrBuilder &MIB,
144                               const ARMBaseInstrInfo &TII,
145                               MachineRegisterInfo &MRI,
146                               const TargetRegisterInfo &TRI,
147                               const RegisterBankInfo &RBI) {
148   assert(TII.getSubtarget().hasVFP2() && "Can't select merge without VFP");
149 
150   // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
151   // into one DPR.
152   unsigned VReg0 = MIB->getOperand(0).getReg();
153   (void)VReg0;
154   assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
155          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
156          "Unsupported operand for G_MERGE_VALUES");
157   unsigned VReg1 = MIB->getOperand(1).getReg();
158   (void)VReg1;
159   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
160          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
161          "Unsupported operand for G_MERGE_VALUES");
162   unsigned VReg2 = MIB->getOperand(2).getReg();
163   (void)VReg2;
164   assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
165          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
166          "Unsupported operand for G_MERGE_VALUES");
167 
168   MIB->setDesc(TII.get(ARM::VMOVDRR));
169   MIB.add(predOps(ARMCC::AL));
170 
171   return true;
172 }
173 
174 static bool selectUnmergeValues(MachineInstrBuilder &MIB,
175                                 const ARMBaseInstrInfo &TII,
176                                 MachineRegisterInfo &MRI,
177                                 const TargetRegisterInfo &TRI,
178                                 const RegisterBankInfo &RBI) {
179   assert(TII.getSubtarget().hasVFP2() && "Can't select unmerge without VFP");
180 
181   // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
182   // GPRs.
183   unsigned VReg0 = MIB->getOperand(0).getReg();
184   (void)VReg0;
185   assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
186          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
187          "Unsupported operand for G_UNMERGE_VALUES");
188   unsigned VReg1 = MIB->getOperand(1).getReg();
189   (void)VReg1;
190   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
191          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
192          "Unsupported operand for G_UNMERGE_VALUES");
193   unsigned VReg2 = MIB->getOperand(2).getReg();
194   (void)VReg2;
195   assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
196          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
197          "Unsupported operand for G_UNMERGE_VALUES");
198 
199   MIB->setDesc(TII.get(ARM::VMOVRRD));
200   MIB.add(predOps(ARMCC::AL));
201 
202   return true;
203 }
204 
205 /// Select the opcode for simple extensions (that translate to a single SXT/UXT
206 /// instruction). Extension operations more complicated than that should not
207 /// invoke this. Returns the original opcode if it doesn't know how to select a
208 /// better one.
209 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
210   using namespace TargetOpcode;
211 
212   if (Size != 8 && Size != 16)
213     return Opc;
214 
215   if (Opc == G_SEXT)
216     return Size == 8 ? ARM::SXTB : ARM::SXTH;
217 
218   if (Opc == G_ZEXT)
219     return Size == 8 ? ARM::UXTB : ARM::UXTH;
220 
221   return Opc;
222 }
223 
224 /// Select the opcode for simple loads and stores. For types smaller than 32
225 /// bits, the value will be zero extended. Returns the original opcode if it
226 /// doesn't know how to select a better one.
227 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
228                                       unsigned Size) {
229   bool isStore = Opc == TargetOpcode::G_STORE;
230 
231   if (RegBank == ARM::GPRRegBankID) {
232     switch (Size) {
233     case 1:
234     case 8:
235       return isStore ? ARM::STRBi12 : ARM::LDRBi12;
236     case 16:
237       return isStore ? ARM::STRH : ARM::LDRH;
238     case 32:
239       return isStore ? ARM::STRi12 : ARM::LDRi12;
240     default:
241       return Opc;
242     }
243   }
244 
245   if (RegBank == ARM::FPRRegBankID) {
246     switch (Size) {
247     case 32:
248       return isStore ? ARM::VSTRS : ARM::VLDRS;
249     case 64:
250       return isStore ? ARM::VSTRD : ARM::VLDRD;
251     default:
252       return Opc;
253     }
254   }
255 
256   return Opc;
257 }
258 
259 // When lowering comparisons, we sometimes need to perform two compares instead
260 // of just one. Get the condition codes for both comparisons. If only one is
261 // needed, the second member of the pair is ARMCC::AL.
262 static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
263 getComparePreds(CmpInst::Predicate Pred) {
264   std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
265   switch (Pred) {
266   case CmpInst::FCMP_ONE:
267     Preds = {ARMCC::GT, ARMCC::MI};
268     break;
269   case CmpInst::FCMP_UEQ:
270     Preds = {ARMCC::EQ, ARMCC::VS};
271     break;
272   case CmpInst::ICMP_EQ:
273   case CmpInst::FCMP_OEQ:
274     Preds.first = ARMCC::EQ;
275     break;
276   case CmpInst::ICMP_SGT:
277   case CmpInst::FCMP_OGT:
278     Preds.first = ARMCC::GT;
279     break;
280   case CmpInst::ICMP_SGE:
281   case CmpInst::FCMP_OGE:
282     Preds.first = ARMCC::GE;
283     break;
284   case CmpInst::ICMP_UGT:
285   case CmpInst::FCMP_UGT:
286     Preds.first = ARMCC::HI;
287     break;
288   case CmpInst::FCMP_OLT:
289     Preds.first = ARMCC::MI;
290     break;
291   case CmpInst::ICMP_ULE:
292   case CmpInst::FCMP_OLE:
293     Preds.first = ARMCC::LS;
294     break;
295   case CmpInst::FCMP_ORD:
296     Preds.first = ARMCC::VC;
297     break;
298   case CmpInst::FCMP_UNO:
299     Preds.first = ARMCC::VS;
300     break;
301   case CmpInst::FCMP_UGE:
302     Preds.first = ARMCC::PL;
303     break;
304   case CmpInst::ICMP_SLT:
305   case CmpInst::FCMP_ULT:
306     Preds.first = ARMCC::LT;
307     break;
308   case CmpInst::ICMP_SLE:
309   case CmpInst::FCMP_ULE:
310     Preds.first = ARMCC::LE;
311     break;
312   case CmpInst::FCMP_UNE:
313   case CmpInst::ICMP_NE:
314     Preds.first = ARMCC::NE;
315     break;
316   case CmpInst::ICMP_UGE:
317     Preds.first = ARMCC::HS;
318     break;
319   case CmpInst::ICMP_ULT:
320     Preds.first = ARMCC::LO;
321     break;
322   default:
323     break;
324   }
325   assert(Preds.first != ARMCC::AL && "No comparisons needed?");
326   return Preds;
327 }
328 
329 template <typename T> struct ARMInstructionSelector::CmpHelper {
330   CmpHelper(const ARMInstructionSelector &Selector, MachineInstrBuilder &MIB,
331             const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI,
332             const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
333       : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())),
334         DbgLoc(MIB->getDebugLoc()), TII(TII), MRI(MRI), TRI(TRI), RBI(RBI),
335         Selector(Selector) {}
336 
337   // The opcode used for performing the comparison.
338   static const unsigned ComparisonOpcode;
339 
340   // The opcode used for reading the flags set by the comparison. May be
341   // ARM::INSTRUCTION_LIST_END if we don't need to read the flags.
342   static const unsigned ReadFlagsOpcode;
343 
344   // The opcode used for selecting the result register, based on the value
345   // of the flags.
346   static const unsigned SetResultOpcode = ARM::MOVCCi;
347 
348   // The assumed register bank ID for the operands.
349   static const unsigned OperandRegBankID;
350 
351   // The assumed register bank ID for the result.
352   static const unsigned ResultRegBankID = ARM::GPRRegBankID;
353 
354   unsigned getZeroRegister() {
355     unsigned Reg = MRI.createVirtualRegister(&ARM::GPRRegClass);
356     putConstant(Reg, 0);
357     return Reg;
358   }
359 
360   void putConstant(unsigned DestReg, unsigned Constant) {
361     (void)BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVi))
362         .addDef(DestReg)
363         .addImm(Constant)
364         .add(predOps(ARMCC::AL))
365         .add(condCodeOp());
366   }
367 
368   bool insertComparison(unsigned ResReg, ARMCC::CondCodes Cond, unsigned LHSReg,
369                         unsigned RHSReg, unsigned PrevRes) {
370 
371     // Perform the comparison.
372     auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ComparisonOpcode))
373                     .addUse(LHSReg)
374                     .addUse(RHSReg)
375                     .add(predOps(ARMCC::AL));
376     if (!Selector.constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
377       return false;
378 
379     // Read the comparison flags (if necessary).
380     if (ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
381       auto ReadI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ReadFlagsOpcode))
382                        .add(predOps(ARMCC::AL));
383       if (!Selector.constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
384         return false;
385     }
386 
387     // Select either 1 or the previous result based on the value of the flags.
388     auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(SetResultOpcode))
389                      .addDef(ResReg)
390                      .addUse(PrevRes)
391                      .addImm(1)
392                      .add(predOps(Cond, ARM::CPSR));
393     if (!Selector.constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
394       return false;
395 
396     return true;
397   }
398 
399   bool validateOpRegs(unsigned LHSReg, unsigned RHSReg) {
400     return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
401            validateOpReg(LHSReg, MRI, TRI, RBI) &&
402            validateOpReg(RHSReg, MRI, TRI, RBI);
403   }
404 
405   bool validateResReg(unsigned ResReg) {
406     if (MRI.getType(ResReg).getSizeInBits() != 1) {
407       DEBUG(dbgs() << "Unsupported size for comparison operand");
408       return false;
409     }
410 
411     if (RBI.getRegBank(ResReg, MRI, TRI)->getID() != ResultRegBankID) {
412       DEBUG(dbgs() << "Unsupported register bank for comparison operand");
413       return false;
414     }
415 
416     return true;
417   }
418 
419 private:
420   bool validateOpReg(unsigned OpReg, MachineRegisterInfo &MRI,
421                      const TargetRegisterInfo &TRI,
422                      const RegisterBankInfo &RBI) {
423     if (MRI.getType(OpReg).getSizeInBits() != 32) {
424       DEBUG(dbgs() << "Unsupported size for comparison operand");
425       return false;
426     }
427 
428     if (RBI.getRegBank(OpReg, MRI, TRI)->getID() != OperandRegBankID) {
429       DEBUG(dbgs() << "Unsupported register bank for comparison operand");
430       return false;
431     }
432 
433     return true;
434   }
435 
436   MachineBasicBlock &MBB;
437   MachineBasicBlock::instr_iterator InsertBefore;
438   const DebugLoc &DbgLoc;
439 
440   const ARMBaseInstrInfo &TII;
441   MachineRegisterInfo &MRI;
442   const TargetRegisterInfo &TRI;
443   const RegisterBankInfo &RBI;
444 
445   const ARMInstructionSelector &Selector;
446 };
447 
448 // Specialize the opcode to be used for comparing different types of operands.
449 template <>
450 const unsigned ARMInstructionSelector::CmpHelper<int>::ComparisonOpcode =
451     ARM::CMPrr;
452 template <>
453 const unsigned ARMInstructionSelector::CmpHelper<float>::ComparisonOpcode =
454     ARM::VCMPS;
455 
456 // Specialize the opcode to be used for reading the comparison flags for
457 // different types of operands.
458 template <>
459 const unsigned ARMInstructionSelector::CmpHelper<int>::ReadFlagsOpcode =
460     ARM::INSTRUCTION_LIST_END;
461 template <>
462 const unsigned ARMInstructionSelector::CmpHelper<float>::ReadFlagsOpcode =
463     ARM::FMSTAT;
464 
465 // Specialize the register bank where the operands of the comparison are assumed
466 // to live.
467 template <>
468 const unsigned ARMInstructionSelector::CmpHelper<int>::OperandRegBankID =
469     ARM::GPRRegBankID;
470 template <>
471 const unsigned ARMInstructionSelector::CmpHelper<float>::OperandRegBankID =
472     ARM::FPRRegBankID;
473 
474 template <typename T>
475 bool ARMInstructionSelector::selectCmp(MachineInstrBuilder &MIB,
476                                        const ARMBaseInstrInfo &TII,
477                                        MachineRegisterInfo &MRI,
478                                        const TargetRegisterInfo &TRI,
479                                        const RegisterBankInfo &RBI) const {
480   auto Helper = CmpHelper<T>(*this, MIB, TII, MRI, TRI, RBI);
481 
482   auto ResReg = MIB->getOperand(0).getReg();
483   if (!Helper.validateResReg(ResReg))
484     return false;
485 
486   auto Cond =
487       static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
488   if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) {
489     Helper.putConstant(ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0);
490     MIB->eraseFromParent();
491     return true;
492   }
493 
494   auto LHSReg = MIB->getOperand(2).getReg();
495   auto RHSReg = MIB->getOperand(3).getReg();
496   if (!Helper.validateOpRegs(LHSReg, RHSReg))
497     return false;
498 
499   auto ARMConds = getComparePreds(Cond);
500   auto ZeroReg = Helper.getZeroRegister();
501 
502   if (ARMConds.second == ARMCC::AL) {
503     // Simple case, we only need one comparison and we're done.
504     if (!Helper.insertComparison(ResReg, ARMConds.first, LHSReg, RHSReg,
505                                  ZeroReg))
506       return false;
507   } else {
508     // Not so simple, we need two successive comparisons.
509     auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
510     if (!Helper.insertComparison(IntermediateRes, ARMConds.first, LHSReg,
511                                  RHSReg, ZeroReg))
512       return false;
513     if (!Helper.insertComparison(ResReg, ARMConds.second, LHSReg, RHSReg,
514                                  IntermediateRes))
515       return false;
516   }
517 
518   MIB->eraseFromParent();
519   return true;
520 }
521 
522 bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
523                                           const ARMBaseInstrInfo &TII,
524                                           MachineRegisterInfo &MRI,
525                                           const TargetRegisterInfo &TRI,
526                                           const RegisterBankInfo &RBI) const {
527   auto &MBB = *MIB->getParent();
528   auto InsertBefore = std::next(MIB->getIterator());
529   auto &DbgLoc = MIB->getDebugLoc();
530 
531   // Compare the condition to 0.
532   auto CondReg = MIB->getOperand(1).getReg();
533   assert(MRI.getType(CondReg).getSizeInBits() == 1 &&
534          RBI.getRegBank(CondReg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
535          "Unsupported types for select operation");
536   auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri))
537                   .addUse(CondReg)
538                   .addImm(0)
539                   .add(predOps(ARMCC::AL));
540   if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
541     return false;
542 
543   // Move a value into the result register based on the result of the
544   // comparison.
545   auto ResReg = MIB->getOperand(0).getReg();
546   auto TrueReg = MIB->getOperand(2).getReg();
547   auto FalseReg = MIB->getOperand(3).getReg();
548   assert(MRI.getType(ResReg) == MRI.getType(TrueReg) &&
549          MRI.getType(TrueReg) == MRI.getType(FalseReg) &&
550          MRI.getType(FalseReg).getSizeInBits() == 32 &&
551          RBI.getRegBank(TrueReg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
552          RBI.getRegBank(FalseReg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
553          "Unsupported types for select operation");
554   auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr))
555                    .addDef(ResReg)
556                    .addUse(TrueReg)
557                    .addUse(FalseReg)
558                    .add(predOps(ARMCC::EQ, ARM::CPSR));
559   if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
560     return false;
561 
562   MIB->eraseFromParent();
563   return true;
564 }
565 
566 bool ARMInstructionSelector::select(MachineInstr &I) const {
567   assert(I.getParent() && "Instruction should be in a basic block!");
568   assert(I.getParent()->getParent() && "Instruction should be in a function!");
569 
570   auto &MBB = *I.getParent();
571   auto &MF = *MBB.getParent();
572   auto &MRI = MF.getRegInfo();
573 
574   if (!isPreISelGenericOpcode(I.getOpcode())) {
575     if (I.isCopy())
576       return selectCopy(I, TII, MRI, TRI, RBI);
577 
578     return true;
579   }
580 
581   if (selectImpl(I))
582     return true;
583 
584   MachineInstrBuilder MIB{MF, I};
585   bool isSExt = false;
586 
587   using namespace TargetOpcode;
588   switch (I.getOpcode()) {
589   case G_SEXT:
590     isSExt = true;
591     LLVM_FALLTHROUGH;
592   case G_ZEXT: {
593     LLT DstTy = MRI.getType(I.getOperand(0).getReg());
594     // FIXME: Smaller destination sizes coming soon!
595     if (DstTy.getSizeInBits() != 32) {
596       DEBUG(dbgs() << "Unsupported destination size for extension");
597       return false;
598     }
599 
600     LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
601     unsigned SrcSize = SrcTy.getSizeInBits();
602     switch (SrcSize) {
603     case 1: {
604       // ZExt boils down to & 0x1; for SExt we also subtract that from 0
605       I.setDesc(TII.get(ARM::ANDri));
606       MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
607 
608       if (isSExt) {
609         unsigned SExtResult = I.getOperand(0).getReg();
610 
611         // Use a new virtual register for the result of the AND
612         unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
613         I.getOperand(0).setReg(AndResult);
614 
615         auto InsertBefore = std::next(I.getIterator());
616         auto SubI =
617             BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
618                 .addDef(SExtResult)
619                 .addUse(AndResult)
620                 .addImm(0)
621                 .add(predOps(ARMCC::AL))
622                 .add(condCodeOp());
623         if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
624           return false;
625       }
626       break;
627     }
628     case 8:
629     case 16: {
630       unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
631       if (NewOpc == I.getOpcode())
632         return false;
633       I.setDesc(TII.get(NewOpc));
634       MIB.addImm(0).add(predOps(ARMCC::AL));
635       break;
636     }
637     default:
638       DEBUG(dbgs() << "Unsupported source size for extension");
639       return false;
640     }
641     break;
642   }
643   case G_ANYEXT:
644   case G_TRUNC: {
645     // The high bits are undefined, so there's nothing special to do, just
646     // treat it as a copy.
647     auto SrcReg = I.getOperand(1).getReg();
648     auto DstReg = I.getOperand(0).getReg();
649 
650     const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
651     const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
652 
653     if (SrcRegBank.getID() != DstRegBank.getID()) {
654       DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
655       return false;
656     }
657 
658     if (SrcRegBank.getID() != ARM::GPRRegBankID) {
659       DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
660       return false;
661     }
662 
663     I.setDesc(TII.get(COPY));
664     return selectCopy(I, TII, MRI, TRI, RBI);
665   }
666   case G_SELECT:
667     return selectSelect(MIB, TII, MRI, TRI, RBI);
668   case G_ICMP:
669     return selectCmp<int>(MIB, TII, MRI, TRI, RBI);
670   case G_FCMP:
671     assert(TII.getSubtarget().hasVFP2() && "Can't select fcmp without VFP");
672     return selectCmp<float>(MIB, TII, MRI, TRI, RBI);
673   case G_GEP:
674     I.setDesc(TII.get(ARM::ADDrr));
675     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
676     break;
677   case G_FRAME_INDEX:
678     // Add 0 to the given frame index and hope it will eventually be folded into
679     // the user(s).
680     I.setDesc(TII.get(ARM::ADDri));
681     MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
682     break;
683   case G_CONSTANT: {
684     unsigned Reg = I.getOperand(0).getReg();
685     if (MRI.getType(Reg).getSizeInBits() != 32)
686       return false;
687 
688     assert(RBI.getRegBank(Reg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
689            "Expected constant to live in a GPR");
690     I.setDesc(TII.get(ARM::MOVi));
691     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
692 
693     auto &Val = I.getOperand(1);
694     if (Val.isCImm()) {
695       if (Val.getCImm()->getBitWidth() > 32)
696         return false;
697       Val.ChangeToImmediate(Val.getCImm()->getZExtValue());
698     }
699 
700     if (!Val.isImm()) {
701       return false;
702     }
703 
704     break;
705   }
706   case G_STORE:
707   case G_LOAD: {
708     const auto &MemOp = **I.memoperands_begin();
709     if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
710       DEBUG(dbgs() << "Atomic load/store not supported yet\n");
711       return false;
712     }
713 
714     unsigned Reg = I.getOperand(0).getReg();
715     unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
716 
717     LLT ValTy = MRI.getType(Reg);
718     const auto ValSize = ValTy.getSizeInBits();
719 
720     assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) &&
721            "Don't know how to load/store 64-bit value without VFP");
722 
723     const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
724     if (NewOpc == G_LOAD || NewOpc == G_STORE)
725       return false;
726 
727     I.setDesc(TII.get(NewOpc));
728 
729     if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
730       // LDRH has a funny addressing mode (there's already a FIXME for it).
731       MIB.addReg(0);
732     MIB.addImm(0).add(predOps(ARMCC::AL));
733     break;
734   }
735   case G_MERGE_VALUES: {
736     if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
737       return false;
738     break;
739   }
740   case G_UNMERGE_VALUES: {
741     if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
742       return false;
743     break;
744   }
745   default:
746     return false;
747   }
748 
749   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
750 }
751