]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
Merge ^/head r311314 through r311459.
[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 "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     AddDefaultCC(AddDefaultPred(MIB));
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     AddDefaultCC(AddDefaultPred(MIB.addImm(0)));
99     break;
100   case G_LOAD:
101     I.setDesc(TII.get(ARM::LDRi12));
102     AddDefaultPred(MIB.addImm(0));
103     break;
104   default:
105     return false;
106   }
107
108   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
109 }