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 && "Unsupported reg bank");
58   const TargetRegisterClass *RC = &ARM::GPRRegClass;
59 
60   // No need to constrain SrcReg. It will get constrained when
61   // we hit another of its uses or its defs.
62   // Copies do not have constraints.
63   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
64     DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
65                  << " operand\n");
66     return false;
67   }
68   return true;
69 }
70 
71 bool ARMInstructionSelector::select(MachineInstr &I) const {
72   assert(I.getParent() && "Instruction should be in a basic block!");
73   assert(I.getParent()->getParent() && "Instruction should be in a function!");
74 
75   auto &MBB = *I.getParent();
76   auto &MF = *MBB.getParent();
77   auto &MRI = MF.getRegInfo();
78 
79   if (!isPreISelGenericOpcode(I.getOpcode())) {
80     if (I.isCopy())
81       return selectCopy(I, TII, MRI, TRI, RBI);
82 
83     return true;
84   }
85 
86   MachineInstrBuilder MIB{MF, I};
87 
88   using namespace TargetOpcode;
89   switch (I.getOpcode()) {
90   case G_ADD:
91     I.setDesc(TII.get(ARM::ADDrr));
92     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
93     break;
94   case G_FRAME_INDEX:
95     // Add 0 to the given frame index and hope it will eventually be folded into
96     // the user(s).
97     I.setDesc(TII.get(ARM::ADDri));
98     MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
99     break;
100   case G_LOAD:
101     I.setDesc(TII.get(ARM::LDRi12));
102     MIB.addImm(0).add(predOps(ARMCC::AL));
103     break;
104   default:
105     return false;
106   }
107 
108   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
109 }
110