blob: cbab21a3e1b3d5044b9a949557f3108e841485c7 [file] [log] [blame]
Diana Picus22274932016-11-11 08:27:37 +00001//===- 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
Diana Picus22274932016-11-11 08:27:37 +000014#include "ARMRegisterBankInfo.h"
15#include "ARMSubtarget.h"
16#include "ARMTargetMachine.h"
Diana Picus674888d2017-04-28 09:10:38 +000017#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
Diana Picus812caee2016-12-16 12:54:46 +000018#include "llvm/CodeGen/MachineRegisterInfo.h"
Diana Picus22274932016-11-11 08:27:37 +000019#include "llvm/Support/Debug.h"
20
21#define DEBUG_TYPE "arm-isel"
22
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000023#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
24
Diana Picus22274932016-11-11 08:27:37 +000025using namespace llvm;
26
27#ifndef LLVM_BUILD_GLOBAL_ISEL
28#error "You shouldn't build this"
29#endif
30
Diana Picus674888d2017-04-28 09:10:38 +000031namespace {
Diana Picus8abcbbb2017-05-02 09:40:49 +000032
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "ARMGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
36
Diana Picus674888d2017-04-28 09:10:38 +000037class ARMInstructionSelector : public InstructionSelector {
38public:
Diana Picus8abcbbb2017-05-02 09:40:49 +000039 ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
Diana Picus674888d2017-04-28 09:10:38 +000040 const ARMRegisterBankInfo &RBI);
41
42 bool select(MachineInstr &I) const override;
43
44private:
Diana Picus8abcbbb2017-05-02 09:40:49 +000045 bool selectImpl(MachineInstr &I) const;
46
Diana Picus5b916532017-07-07 08:39:04 +000047 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;
Diana Picus621894a2017-06-19 09:40:51 +000053
Diana Picus7145d222017-06-27 09:19:51 +000054 bool selectSelect(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
55 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
56 const RegisterBankInfo &RBI) const;
57
Diana Picus674888d2017-04-28 09:10:38 +000058 const ARMBaseInstrInfo &TII;
59 const ARMBaseRegisterInfo &TRI;
Diana Picus8abcbbb2017-05-02 09:40:49 +000060 const ARMBaseTargetMachine &TM;
Diana Picus674888d2017-04-28 09:10:38 +000061 const ARMRegisterBankInfo &RBI;
Diana Picus8abcbbb2017-05-02 09:40:49 +000062 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
Diana Picus674888d2017-04-28 09:10:38 +000073};
74} // end anonymous namespace
75
76namespace llvm {
77InstructionSelector *
Diana Picus8abcbbb2017-05-02 09:40:49 +000078createARMInstructionSelector(const ARMBaseTargetMachine &TM,
79 const ARMSubtarget &STI,
Diana Picus674888d2017-04-28 09:10:38 +000080 const ARMRegisterBankInfo &RBI) {
Diana Picus8abcbbb2017-05-02 09:40:49 +000081 return new ARMInstructionSelector(TM, STI, RBI);
Diana Picus674888d2017-04-28 09:10:38 +000082}
83}
84
Diana Picus8abcbbb2017-05-02 09:40:49 +000085unsigned zero_reg = 0;
86
87#define GET_GLOBALISEL_IMPL
88#include "ARMGenGlobalISel.inc"
89#undef GET_GLOBALISEL_IMPL
90
91ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
92 const ARMSubtarget &STI,
Diana Picus22274932016-11-11 08:27:37 +000093 const ARMRegisterBankInfo &RBI)
Diana Picus895c6aa2016-11-15 16:42:10 +000094 : InstructionSelector(), TII(*STI.getInstrInfo()),
Diana Picus8abcbbb2017-05-02 09:40:49 +000095 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}
Diana Picus22274932016-11-11 08:27:37 +0000104
Diana Picus812caee2016-12-16 12:54:46 +0000105static 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);
Benjamin Kramer24bf8682016-12-16 13:13:03 +0000113 (void)RegBank;
Diana Picus812caee2016-12-16 12:54:46 +0000114 assert(RegBank && "Can't get reg bank for virtual register");
115
Diana Picus36aa09f2016-12-19 14:07:50 +0000116 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
Diana Picus4fa83c02017-02-08 13:23:04 +0000117 assert((RegBank->getID() == ARM::GPRRegBankID ||
118 RegBank->getID() == ARM::FPRRegBankID) &&
119 "Unsupported reg bank");
120
Diana Picus812caee2016-12-16 12:54:46 +0000121 const TargetRegisterClass *RC = &ARM::GPRRegClass;
122
Diana Picus4fa83c02017-02-08 13:23:04 +0000123 if (RegBank->getID() == ARM::FPRRegBankID) {
Diana Picus6beef3c2017-02-16 12:19:52 +0000124 if (DstSize == 32)
125 RC = &ARM::SPRRegClass;
126 else if (DstSize == 64)
127 RC = &ARM::DPRRegClass;
128 else
129 llvm_unreachable("Unsupported destination size");
Diana Picus4fa83c02017-02-08 13:23:04 +0000130 }
131
Diana Picus812caee2016-12-16 12:54:46 +0000132 // 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
Diana Picus0b4190a2017-06-07 12:35:05 +0000143static 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");
Diana Picusb1701e02017-02-16 12:19:57 +0000149
Diana Picus0b4190a2017-06-07 12:35:05 +0000150 // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
Diana Picusb1701e02017-02-16 12:19:57 +0000151 // 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 &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000156 "Unsupported operand for G_MERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000157 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 &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000161 "Unsupported operand for G_MERGE_VALUES");
162 unsigned VReg2 = MIB->getOperand(2).getReg();
Diana Picusb1701e02017-02-16 12:19:57 +0000163 (void)VReg2;
164 assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
165 RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000166 "Unsupported operand for G_MERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000167
168 MIB->setDesc(TII.get(ARM::VMOVDRR));
169 MIB.add(predOps(ARMCC::AL));
170
171 return true;
172}
173
Diana Picus0b4190a2017-06-07 12:35:05 +0000174static 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");
Diana Picusb1701e02017-02-16 12:19:57 +0000180
Diana Picus0b4190a2017-06-07 12:35:05 +0000181 // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
182 // GPRs.
Diana Picusb1701e02017-02-16 12:19:57 +0000183 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 &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000187 "Unsupported operand for G_UNMERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000188 unsigned VReg1 = MIB->getOperand(1).getReg();
189 (void)VReg1;
Diana Picus0b4190a2017-06-07 12:35:05 +0000190 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");
Diana Picusb1701e02017-02-16 12:19:57 +0000198
Diana Picus0b4190a2017-06-07 12:35:05 +0000199 MIB->setDesc(TII.get(ARM::VMOVRRD));
Diana Picusb1701e02017-02-16 12:19:57 +0000200 MIB.add(predOps(ARMCC::AL));
201
202 return true;
203}
204
Diana Picus8b6c6be2017-01-25 08:10:40 +0000205/// Select the opcode for simple extensions (that translate to a single SXT/UXT
206/// instruction). Extension operations more complicated than that should not
Diana Picuse8368782017-02-17 13:44:19 +0000207/// invoke this. Returns the original opcode if it doesn't know how to select a
208/// better one.
Diana Picus8b6c6be2017-01-25 08:10:40 +0000209static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
210 using namespace TargetOpcode;
211
Diana Picuse8368782017-02-17 13:44:19 +0000212 if (Size != 8 && Size != 16)
213 return Opc;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000214
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
Diana Picuse8368782017-02-17 13:44:19 +0000221 return Opc;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000222}
223
Diana Picus3b99c642017-02-24 14:01:27 +0000224/// 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.
227static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
228 unsigned Size) {
229 bool isStore = Opc == TargetOpcode::G_STORE;
230
Diana Picus1540b062017-02-16 14:10:50 +0000231 if (RegBank == ARM::GPRRegBankID) {
232 switch (Size) {
233 case 1:
234 case 8:
Diana Picus3b99c642017-02-24 14:01:27 +0000235 return isStore ? ARM::STRBi12 : ARM::LDRBi12;
Diana Picus1540b062017-02-16 14:10:50 +0000236 case 16:
Diana Picus3b99c642017-02-24 14:01:27 +0000237 return isStore ? ARM::STRH : ARM::LDRH;
Diana Picus1540b062017-02-16 14:10:50 +0000238 case 32:
Diana Picus3b99c642017-02-24 14:01:27 +0000239 return isStore ? ARM::STRi12 : ARM::LDRi12;
Diana Picuse8368782017-02-17 13:44:19 +0000240 default:
Diana Picus3b99c642017-02-24 14:01:27 +0000241 return Opc;
Diana Picus1540b062017-02-16 14:10:50 +0000242 }
Diana Picus1540b062017-02-16 14:10:50 +0000243 }
244
Diana Picuse8368782017-02-17 13:44:19 +0000245 if (RegBank == ARM::FPRRegBankID) {
246 switch (Size) {
247 case 32:
Diana Picus3b99c642017-02-24 14:01:27 +0000248 return isStore ? ARM::VSTRS : ARM::VLDRS;
Diana Picuse8368782017-02-17 13:44:19 +0000249 case 64:
Diana Picus3b99c642017-02-24 14:01:27 +0000250 return isStore ? ARM::VSTRD : ARM::VLDRD;
Diana Picuse8368782017-02-17 13:44:19 +0000251 default:
Diana Picus3b99c642017-02-24 14:01:27 +0000252 return Opc;
Diana Picuse8368782017-02-17 13:44:19 +0000253 }
Diana Picus278c7222017-01-26 09:20:47 +0000254 }
255
Diana Picus3b99c642017-02-24 14:01:27 +0000256 return Opc;
Diana Picus278c7222017-01-26 09:20:47 +0000257}
258
Diana Picus5b916532017-07-07 08:39:04 +0000259// 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.
262static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
263getComparePreds(CmpInst::Predicate Pred) {
264 std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
Diana Picus621894a2017-06-19 09:40:51 +0000265 switch (Pred) {
Diana Picus621894a2017-06-19 09:40:51 +0000266 case CmpInst::FCMP_ONE:
Diana Picus5b916532017-07-07 08:39:04 +0000267 Preds = {ARMCC::GT, ARMCC::MI};
268 break;
Diana Picus621894a2017-06-19 09:40:51 +0000269 case CmpInst::FCMP_UEQ:
Diana Picus5b916532017-07-07 08:39:04 +0000270 Preds = {ARMCC::EQ, ARMCC::VS};
271 break;
Diana Picus621894a2017-06-19 09:40:51 +0000272 case CmpInst::ICMP_EQ:
273 case CmpInst::FCMP_OEQ:
Diana Picus5b916532017-07-07 08:39:04 +0000274 Preds.first = ARMCC::EQ;
275 break;
Diana Picus621894a2017-06-19 09:40:51 +0000276 case CmpInst::ICMP_SGT:
277 case CmpInst::FCMP_OGT:
Diana Picus5b916532017-07-07 08:39:04 +0000278 Preds.first = ARMCC::GT;
279 break;
Diana Picus621894a2017-06-19 09:40:51 +0000280 case CmpInst::ICMP_SGE:
281 case CmpInst::FCMP_OGE:
Diana Picus5b916532017-07-07 08:39:04 +0000282 Preds.first = ARMCC::GE;
283 break;
Diana Picus621894a2017-06-19 09:40:51 +0000284 case CmpInst::ICMP_UGT:
285 case CmpInst::FCMP_UGT:
Diana Picus5b916532017-07-07 08:39:04 +0000286 Preds.first = ARMCC::HI;
287 break;
Diana Picus621894a2017-06-19 09:40:51 +0000288 case CmpInst::FCMP_OLT:
Diana Picus5b916532017-07-07 08:39:04 +0000289 Preds.first = ARMCC::MI;
290 break;
Diana Picus621894a2017-06-19 09:40:51 +0000291 case CmpInst::ICMP_ULE:
292 case CmpInst::FCMP_OLE:
Diana Picus5b916532017-07-07 08:39:04 +0000293 Preds.first = ARMCC::LS;
294 break;
Diana Picus621894a2017-06-19 09:40:51 +0000295 case CmpInst::FCMP_ORD:
Diana Picus5b916532017-07-07 08:39:04 +0000296 Preds.first = ARMCC::VC;
297 break;
Diana Picus621894a2017-06-19 09:40:51 +0000298 case CmpInst::FCMP_UNO:
Diana Picus5b916532017-07-07 08:39:04 +0000299 Preds.first = ARMCC::VS;
300 break;
Diana Picus621894a2017-06-19 09:40:51 +0000301 case CmpInst::FCMP_UGE:
Diana Picus5b916532017-07-07 08:39:04 +0000302 Preds.first = ARMCC::PL;
303 break;
Diana Picus621894a2017-06-19 09:40:51 +0000304 case CmpInst::ICMP_SLT:
305 case CmpInst::FCMP_ULT:
Diana Picus5b916532017-07-07 08:39:04 +0000306 Preds.first = ARMCC::LT;
307 break;
Diana Picus621894a2017-06-19 09:40:51 +0000308 case CmpInst::ICMP_SLE:
309 case CmpInst::FCMP_ULE:
Diana Picus5b916532017-07-07 08:39:04 +0000310 Preds.first = ARMCC::LE;
311 break;
Diana Picus621894a2017-06-19 09:40:51 +0000312 case CmpInst::FCMP_UNE:
313 case CmpInst::ICMP_NE:
Diana Picus5b916532017-07-07 08:39:04 +0000314 Preds.first = ARMCC::NE;
315 break;
Diana Picus621894a2017-06-19 09:40:51 +0000316 case CmpInst::ICMP_UGE:
Diana Picus5b916532017-07-07 08:39:04 +0000317 Preds.first = ARMCC::HS;
318 break;
Diana Picus621894a2017-06-19 09:40:51 +0000319 case CmpInst::ICMP_ULT:
Diana Picus5b916532017-07-07 08:39:04 +0000320 Preds.first = ARMCC::LO;
321 break;
322 default:
323 break;
Diana Picus621894a2017-06-19 09:40:51 +0000324 }
Diana Picus5b916532017-07-07 08:39:04 +0000325 assert(Preds.first != ARMCC::AL && "No comparisons needed?");
326 return Preds;
Diana Picus621894a2017-06-19 09:40:51 +0000327}
328
Diana Picus5b916532017-07-07 08:39:04 +0000329template <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())),
Diana Picus77367372017-07-07 08:53:27 +0000334 DbgLoc(MIB->getDebugLoc()), TII(TII), MRI(MRI), TRI(TRI), RBI(RBI),
Diana Picus5b916532017-07-07 08:39:04 +0000335 Selector(Selector) {}
Diana Picus621894a2017-06-19 09:40:51 +0000336
Diana Picus5b916532017-07-07 08:39:04 +0000337 // The opcode used for performing the comparison.
338 static const unsigned ComparisonOpcode;
Diana Picus621894a2017-06-19 09:40:51 +0000339
Diana Picus5b916532017-07-07 08:39:04 +0000340 // 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;
Diana Picus621894a2017-06-19 09:40:51 +0000343
Diana Picus5b916532017-07-07 08:39:04 +0000344 // 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) {
Diana Picus77367372017-07-07 08:53:27 +0000361 (void)BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVi))
Diana Picus5b916532017-07-07 08:39:04 +0000362 .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.
Diana Picus77367372017-07-07 08:53:27 +0000372 auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ComparisonOpcode))
Diana Picus5b916532017-07-07 08:39:04 +0000373 .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) {
Diana Picus77367372017-07-07 08:53:27 +0000381 auto ReadI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ReadFlagsOpcode))
382 .add(predOps(ARMCC::AL));
Diana Picus5b916532017-07-07 08:39:04 +0000383 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.
Diana Picus77367372017-07-07 08:53:27 +0000388 auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(SetResultOpcode))
Diana Picus5b916532017-07-07 08:39:04 +0000389 .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
419private:
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;
Diana Picus77367372017-07-07 08:53:27 +0000438 const DebugLoc &DbgLoc;
Diana Picus5b916532017-07-07 08:39:04 +0000439
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.
449template <>
450const unsigned ARMInstructionSelector::CmpHelper<int>::ComparisonOpcode =
451 ARM::CMPrr;
452template <>
453const 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.
458template <>
459const unsigned ARMInstructionSelector::CmpHelper<int>::ReadFlagsOpcode =
460 ARM::INSTRUCTION_LIST_END;
461template <>
462const 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.
467template <>
468const unsigned ARMInstructionSelector::CmpHelper<int>::OperandRegBankID =
469 ARM::GPRRegBankID;
470template <>
471const unsigned ARMInstructionSelector::CmpHelper<float>::OperandRegBankID =
472 ARM::FPRRegBankID;
473
474template <typename T>
475bool 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
Diana Picus621894a2017-06-19 09:40:51 +0000482 auto ResReg = MIB->getOperand(0).getReg();
Diana Picus5b916532017-07-07 08:39:04 +0000483 if (!Helper.validateResReg(ResReg))
484 return false;
485
Diana Picus621894a2017-06-19 09:40:51 +0000486 auto Cond =
487 static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
Diana Picus5b916532017-07-07 08:39:04 +0000488 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))
Diana Picus621894a2017-06-19 09:40:51 +0000497 return false;
498
Diana Picus5b916532017-07-07 08:39:04 +0000499 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 }
Diana Picus621894a2017-06-19 09:40:51 +0000517
518 MIB->eraseFromParent();
519 return true;
520}
521
Diana Picus7145d222017-06-27 09:19:51 +0000522bool 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());
Diana Picus77367372017-07-07 08:53:27 +0000529 auto &DbgLoc = MIB->getDebugLoc();
Diana Picus7145d222017-06-27 09:19:51 +0000530
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");
Diana Picus77367372017-07-07 08:53:27 +0000536 auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri))
Diana Picus7145d222017-06-27 09:19:51 +0000537 .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");
Diana Picus77367372017-07-07 08:53:27 +0000554 auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr))
Diana Picus7145d222017-06-27 09:19:51 +0000555 .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
Diana Picus812caee2016-12-16 12:54:46 +0000566bool 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
Diana Picus8abcbbb2017-05-02 09:40:49 +0000581 if (selectImpl(I))
582 return true;
583
Diana Picus519807f2016-12-19 11:26:31 +0000584 MachineInstrBuilder MIB{MF, I};
Diana Picusd83df5d2017-01-25 08:47:40 +0000585 bool isSExt = false;
Diana Picus519807f2016-12-19 11:26:31 +0000586
587 using namespace TargetOpcode;
588 switch (I.getOpcode()) {
Diana Picus8b6c6be2017-01-25 08:10:40 +0000589 case G_SEXT:
Diana Picusd83df5d2017-01-25 08:47:40 +0000590 isSExt = true;
591 LLVM_FALLTHROUGH;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000592 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) {
Diana Picusd83df5d2017-01-25 08:47:40 +0000603 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());
Martin Bohme8396e142017-01-25 14:28:19 +0000616 auto SubI =
Diana Picusd83df5d2017-01-25 08:47:40 +0000617 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 }
Diana Picus8b6c6be2017-01-25 08:10:40 +0000628 case 8:
629 case 16: {
630 unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
Diana Picuse8368782017-02-17 13:44:19 +0000631 if (NewOpc == I.getOpcode())
632 return false;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000633 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 }
Diana Picus657bfd32017-05-11 08:28:31 +0000643 case G_ANYEXT:
Diana Picus64a33432017-04-21 13:16:50 +0000644 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()) {
Diana Picus657bfd32017-05-11 08:28:31 +0000654 DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
Diana Picus64a33432017-04-21 13:16:50 +0000655 return false;
656 }
657
658 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
Diana Picus657bfd32017-05-11 08:28:31 +0000659 DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
Diana Picus64a33432017-04-21 13:16:50 +0000660 return false;
661 }
662
663 I.setDesc(TII.get(COPY));
664 return selectCopy(I, TII, MRI, TRI, RBI);
665 }
Diana Picus7145d222017-06-27 09:19:51 +0000666 case G_SELECT:
667 return selectSelect(MIB, TII, MRI, TRI, RBI);
Diana Picus5b916532017-07-07 08:39:04 +0000668 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);
Diana Picus9d070942017-02-28 10:14:38 +0000673 case G_GEP:
Diana Picus812caee2016-12-16 12:54:46 +0000674 I.setDesc(TII.get(ARM::ADDrr));
Diana Picus8a73f552017-01-13 10:18:01 +0000675 MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus519807f2016-12-19 11:26:31 +0000676 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));
Diana Picus8a73f552017-01-13 10:18:01 +0000681 MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus519807f2016-12-19 11:26:31 +0000682 break;
Diana Picus5a7203a2017-02-28 13:05:42 +0000683 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());
Diana Picus95a8aa92017-04-24 06:30:56 +0000692
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
Diana Picus5a7203a2017-02-28 13:05:42 +0000704 break;
705 }
Diana Picus3b99c642017-02-24 14:01:27 +0000706 case G_STORE:
Diana Picus278c7222017-01-26 09:20:47 +0000707 case G_LOAD: {
Diana Picus1c33c9f2017-02-20 14:45:58 +0000708 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
Diana Picus1540b062017-02-16 14:10:50 +0000714 unsigned Reg = I.getOperand(0).getReg();
715 unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
716
717 LLT ValTy = MRI.getType(Reg);
Diana Picus278c7222017-01-26 09:20:47 +0000718 const auto ValSize = ValTy.getSizeInBits();
719
Diana Picus1540b062017-02-16 14:10:50 +0000720 assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) &&
Diana Picus3b99c642017-02-24 14:01:27 +0000721 "Don't know how to load/store 64-bit value without VFP");
Diana Picus1540b062017-02-16 14:10:50 +0000722
Diana Picus3b99c642017-02-24 14:01:27 +0000723 const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
724 if (NewOpc == G_LOAD || NewOpc == G_STORE)
Diana Picuse8368782017-02-17 13:44:19 +0000725 return false;
726
Diana Picus278c7222017-01-26 09:20:47 +0000727 I.setDesc(TII.get(NewOpc));
728
Diana Picus3b99c642017-02-24 14:01:27 +0000729 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
Diana Picus278c7222017-01-26 09:20:47 +0000730 // LDRH has a funny addressing mode (there's already a FIXME for it).
731 MIB.addReg(0);
Diana Picus4f8c3e12017-01-13 09:37:56 +0000732 MIB.addImm(0).add(predOps(ARMCC::AL));
Diana Picus519807f2016-12-19 11:26:31 +0000733 break;
Diana Picus278c7222017-01-26 09:20:47 +0000734 }
Diana Picus0b4190a2017-06-07 12:35:05 +0000735 case G_MERGE_VALUES: {
736 if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
Diana Picusb1701e02017-02-16 12:19:57 +0000737 return false;
738 break;
739 }
Diana Picus0b4190a2017-06-07 12:35:05 +0000740 case G_UNMERGE_VALUES: {
741 if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
Diana Picusb1701e02017-02-16 12:19:57 +0000742 return false;
743 break;
744 }
Diana Picus519807f2016-12-19 11:26:31 +0000745 default:
746 return false;
Diana Picus812caee2016-12-16 12:54:46 +0000747 }
748
Diana Picus519807f2016-12-19 11:26:31 +0000749 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Diana Picus22274932016-11-11 08:27:37 +0000750}