blob: c318c9c60a5c878747825414c01dbfa74a2305cb [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
Diana Picus21014df2017-07-12 09:01:54 +0000351 // The assumed size in bits for the operands.
352 static const unsigned OperandSize;
353
Diana Picus5b916532017-07-07 08:39:04 +0000354 // The assumed register bank ID for the result.
355 static const unsigned ResultRegBankID = ARM::GPRRegBankID;
356
357 unsigned getZeroRegister() {
358 unsigned Reg = MRI.createVirtualRegister(&ARM::GPRRegClass);
359 putConstant(Reg, 0);
360 return Reg;
361 }
362
363 void putConstant(unsigned DestReg, unsigned Constant) {
Diana Picus77367372017-07-07 08:53:27 +0000364 (void)BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVi))
Diana Picus5b916532017-07-07 08:39:04 +0000365 .addDef(DestReg)
366 .addImm(Constant)
367 .add(predOps(ARMCC::AL))
368 .add(condCodeOp());
369 }
370
371 bool insertComparison(unsigned ResReg, ARMCC::CondCodes Cond, unsigned LHSReg,
372 unsigned RHSReg, unsigned PrevRes) {
373
374 // Perform the comparison.
Diana Picus77367372017-07-07 08:53:27 +0000375 auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ComparisonOpcode))
Diana Picus5b916532017-07-07 08:39:04 +0000376 .addUse(LHSReg)
377 .addUse(RHSReg)
378 .add(predOps(ARMCC::AL));
379 if (!Selector.constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
380 return false;
381
382 // Read the comparison flags (if necessary).
383 if (ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
Diana Picus77367372017-07-07 08:53:27 +0000384 auto ReadI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ReadFlagsOpcode))
385 .add(predOps(ARMCC::AL));
Diana Picus5b916532017-07-07 08:39:04 +0000386 if (!Selector.constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
387 return false;
388 }
389
390 // Select either 1 or the previous result based on the value of the flags.
Diana Picus77367372017-07-07 08:53:27 +0000391 auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(SetResultOpcode))
Diana Picus5b916532017-07-07 08:39:04 +0000392 .addDef(ResReg)
393 .addUse(PrevRes)
394 .addImm(1)
395 .add(predOps(Cond, ARM::CPSR));
396 if (!Selector.constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
397 return false;
398
399 return true;
400 }
401
402 bool validateOpRegs(unsigned LHSReg, unsigned RHSReg) {
403 return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
404 validateOpReg(LHSReg, MRI, TRI, RBI) &&
405 validateOpReg(RHSReg, MRI, TRI, RBI);
406 }
407
408 bool validateResReg(unsigned ResReg) {
409 if (MRI.getType(ResReg).getSizeInBits() != 1) {
410 DEBUG(dbgs() << "Unsupported size for comparison operand");
411 return false;
412 }
413
414 if (RBI.getRegBank(ResReg, MRI, TRI)->getID() != ResultRegBankID) {
415 DEBUG(dbgs() << "Unsupported register bank for comparison operand");
416 return false;
417 }
418
419 return true;
420 }
421
422private:
423 bool validateOpReg(unsigned OpReg, MachineRegisterInfo &MRI,
424 const TargetRegisterInfo &TRI,
425 const RegisterBankInfo &RBI) {
Diana Picus21014df2017-07-12 09:01:54 +0000426 if (MRI.getType(OpReg).getSizeInBits() != OperandSize) {
Diana Picus5b916532017-07-07 08:39:04 +0000427 DEBUG(dbgs() << "Unsupported size for comparison operand");
428 return false;
429 }
430
431 if (RBI.getRegBank(OpReg, MRI, TRI)->getID() != OperandRegBankID) {
432 DEBUG(dbgs() << "Unsupported register bank for comparison operand");
433 return false;
434 }
435
436 return true;
437 }
438
439 MachineBasicBlock &MBB;
440 MachineBasicBlock::instr_iterator InsertBefore;
Diana Picus77367372017-07-07 08:53:27 +0000441 const DebugLoc &DbgLoc;
Diana Picus5b916532017-07-07 08:39:04 +0000442
443 const ARMBaseInstrInfo &TII;
444 MachineRegisterInfo &MRI;
445 const TargetRegisterInfo &TRI;
446 const RegisterBankInfo &RBI;
447
448 const ARMInstructionSelector &Selector;
449};
450
451// Specialize the opcode to be used for comparing different types of operands.
452template <>
453const unsigned ARMInstructionSelector::CmpHelper<int>::ComparisonOpcode =
454 ARM::CMPrr;
455template <>
456const unsigned ARMInstructionSelector::CmpHelper<float>::ComparisonOpcode =
457 ARM::VCMPS;
Diana Picus21014df2017-07-12 09:01:54 +0000458template <>
459const unsigned ARMInstructionSelector::CmpHelper<double>::ComparisonOpcode =
460 ARM::VCMPD;
Diana Picus5b916532017-07-07 08:39:04 +0000461
462// Specialize the opcode to be used for reading the comparison flags for
463// different types of operands.
464template <>
465const unsigned ARMInstructionSelector::CmpHelper<int>::ReadFlagsOpcode =
466 ARM::INSTRUCTION_LIST_END;
467template <>
468const unsigned ARMInstructionSelector::CmpHelper<float>::ReadFlagsOpcode =
469 ARM::FMSTAT;
Diana Picus21014df2017-07-12 09:01:54 +0000470template <>
471const unsigned ARMInstructionSelector::CmpHelper<double>::ReadFlagsOpcode =
472 ARM::FMSTAT;
Diana Picus5b916532017-07-07 08:39:04 +0000473
474// Specialize the register bank where the operands of the comparison are assumed
475// to live.
476template <>
477const unsigned ARMInstructionSelector::CmpHelper<int>::OperandRegBankID =
478 ARM::GPRRegBankID;
479template <>
480const unsigned ARMInstructionSelector::CmpHelper<float>::OperandRegBankID =
481 ARM::FPRRegBankID;
Diana Picus21014df2017-07-12 09:01:54 +0000482template <>
483const unsigned ARMInstructionSelector::CmpHelper<double>::OperandRegBankID =
484 ARM::FPRRegBankID;
485
486// Specialize the size that the operands of the comparison are assumed to have.
487template <>
488const unsigned ARMInstructionSelector::CmpHelper<int>::OperandSize = 32;
489template <>
490const unsigned ARMInstructionSelector::CmpHelper<float>::OperandSize = 32;
491template <>
492const unsigned ARMInstructionSelector::CmpHelper<double>::OperandSize = 64;
Diana Picus5b916532017-07-07 08:39:04 +0000493
494template <typename T>
495bool ARMInstructionSelector::selectCmp(MachineInstrBuilder &MIB,
496 const ARMBaseInstrInfo &TII,
497 MachineRegisterInfo &MRI,
498 const TargetRegisterInfo &TRI,
499 const RegisterBankInfo &RBI) const {
500 auto Helper = CmpHelper<T>(*this, MIB, TII, MRI, TRI, RBI);
501
Diana Picus621894a2017-06-19 09:40:51 +0000502 auto ResReg = MIB->getOperand(0).getReg();
Diana Picus5b916532017-07-07 08:39:04 +0000503 if (!Helper.validateResReg(ResReg))
504 return false;
505
Diana Picus621894a2017-06-19 09:40:51 +0000506 auto Cond =
507 static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
Diana Picus5b916532017-07-07 08:39:04 +0000508 if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) {
509 Helper.putConstant(ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0);
510 MIB->eraseFromParent();
511 return true;
512 }
513
514 auto LHSReg = MIB->getOperand(2).getReg();
515 auto RHSReg = MIB->getOperand(3).getReg();
516 if (!Helper.validateOpRegs(LHSReg, RHSReg))
Diana Picus621894a2017-06-19 09:40:51 +0000517 return false;
518
Diana Picus5b916532017-07-07 08:39:04 +0000519 auto ARMConds = getComparePreds(Cond);
520 auto ZeroReg = Helper.getZeroRegister();
521
522 if (ARMConds.second == ARMCC::AL) {
523 // Simple case, we only need one comparison and we're done.
524 if (!Helper.insertComparison(ResReg, ARMConds.first, LHSReg, RHSReg,
525 ZeroReg))
526 return false;
527 } else {
528 // Not so simple, we need two successive comparisons.
529 auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
530 if (!Helper.insertComparison(IntermediateRes, ARMConds.first, LHSReg,
531 RHSReg, ZeroReg))
532 return false;
533 if (!Helper.insertComparison(ResReg, ARMConds.second, LHSReg, RHSReg,
534 IntermediateRes))
535 return false;
536 }
Diana Picus621894a2017-06-19 09:40:51 +0000537
538 MIB->eraseFromParent();
539 return true;
540}
541
Diana Picus7145d222017-06-27 09:19:51 +0000542bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
543 const ARMBaseInstrInfo &TII,
544 MachineRegisterInfo &MRI,
545 const TargetRegisterInfo &TRI,
546 const RegisterBankInfo &RBI) const {
547 auto &MBB = *MIB->getParent();
548 auto InsertBefore = std::next(MIB->getIterator());
Diana Picus77367372017-07-07 08:53:27 +0000549 auto &DbgLoc = MIB->getDebugLoc();
Diana Picus7145d222017-06-27 09:19:51 +0000550
551 // Compare the condition to 0.
552 auto CondReg = MIB->getOperand(1).getReg();
553 assert(MRI.getType(CondReg).getSizeInBits() == 1 &&
554 RBI.getRegBank(CondReg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
555 "Unsupported types for select operation");
Diana Picus77367372017-07-07 08:53:27 +0000556 auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri))
Diana Picus7145d222017-06-27 09:19:51 +0000557 .addUse(CondReg)
558 .addImm(0)
559 .add(predOps(ARMCC::AL));
560 if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
561 return false;
562
563 // Move a value into the result register based on the result of the
564 // comparison.
565 auto ResReg = MIB->getOperand(0).getReg();
566 auto TrueReg = MIB->getOperand(2).getReg();
567 auto FalseReg = MIB->getOperand(3).getReg();
568 assert(MRI.getType(ResReg) == MRI.getType(TrueReg) &&
569 MRI.getType(TrueReg) == MRI.getType(FalseReg) &&
570 MRI.getType(FalseReg).getSizeInBits() == 32 &&
571 RBI.getRegBank(TrueReg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
572 RBI.getRegBank(FalseReg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
573 "Unsupported types for select operation");
Diana Picus77367372017-07-07 08:53:27 +0000574 auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr))
Diana Picus7145d222017-06-27 09:19:51 +0000575 .addDef(ResReg)
576 .addUse(TrueReg)
577 .addUse(FalseReg)
578 .add(predOps(ARMCC::EQ, ARM::CPSR));
579 if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
580 return false;
581
582 MIB->eraseFromParent();
583 return true;
584}
585
Diana Picus812caee2016-12-16 12:54:46 +0000586bool ARMInstructionSelector::select(MachineInstr &I) const {
587 assert(I.getParent() && "Instruction should be in a basic block!");
588 assert(I.getParent()->getParent() && "Instruction should be in a function!");
589
590 auto &MBB = *I.getParent();
591 auto &MF = *MBB.getParent();
592 auto &MRI = MF.getRegInfo();
593
594 if (!isPreISelGenericOpcode(I.getOpcode())) {
595 if (I.isCopy())
596 return selectCopy(I, TII, MRI, TRI, RBI);
597
598 return true;
599 }
600
Diana Picus8abcbbb2017-05-02 09:40:49 +0000601 if (selectImpl(I))
602 return true;
603
Diana Picus519807f2016-12-19 11:26:31 +0000604 MachineInstrBuilder MIB{MF, I};
Diana Picusd83df5d2017-01-25 08:47:40 +0000605 bool isSExt = false;
Diana Picus519807f2016-12-19 11:26:31 +0000606
607 using namespace TargetOpcode;
608 switch (I.getOpcode()) {
Diana Picus8b6c6be2017-01-25 08:10:40 +0000609 case G_SEXT:
Diana Picusd83df5d2017-01-25 08:47:40 +0000610 isSExt = true;
611 LLVM_FALLTHROUGH;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000612 case G_ZEXT: {
613 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
614 // FIXME: Smaller destination sizes coming soon!
615 if (DstTy.getSizeInBits() != 32) {
616 DEBUG(dbgs() << "Unsupported destination size for extension");
617 return false;
618 }
619
620 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
621 unsigned SrcSize = SrcTy.getSizeInBits();
622 switch (SrcSize) {
Diana Picusd83df5d2017-01-25 08:47:40 +0000623 case 1: {
624 // ZExt boils down to & 0x1; for SExt we also subtract that from 0
625 I.setDesc(TII.get(ARM::ANDri));
626 MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
627
628 if (isSExt) {
629 unsigned SExtResult = I.getOperand(0).getReg();
630
631 // Use a new virtual register for the result of the AND
632 unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
633 I.getOperand(0).setReg(AndResult);
634
635 auto InsertBefore = std::next(I.getIterator());
Martin Bohme8396e142017-01-25 14:28:19 +0000636 auto SubI =
Diana Picusd83df5d2017-01-25 08:47:40 +0000637 BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
638 .addDef(SExtResult)
639 .addUse(AndResult)
640 .addImm(0)
641 .add(predOps(ARMCC::AL))
642 .add(condCodeOp());
643 if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
644 return false;
645 }
646 break;
647 }
Diana Picus8b6c6be2017-01-25 08:10:40 +0000648 case 8:
649 case 16: {
650 unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
Diana Picuse8368782017-02-17 13:44:19 +0000651 if (NewOpc == I.getOpcode())
652 return false;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000653 I.setDesc(TII.get(NewOpc));
654 MIB.addImm(0).add(predOps(ARMCC::AL));
655 break;
656 }
657 default:
658 DEBUG(dbgs() << "Unsupported source size for extension");
659 return false;
660 }
661 break;
662 }
Diana Picus657bfd32017-05-11 08:28:31 +0000663 case G_ANYEXT:
Diana Picus64a33432017-04-21 13:16:50 +0000664 case G_TRUNC: {
665 // The high bits are undefined, so there's nothing special to do, just
666 // treat it as a copy.
667 auto SrcReg = I.getOperand(1).getReg();
668 auto DstReg = I.getOperand(0).getReg();
669
670 const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
671 const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
672
673 if (SrcRegBank.getID() != DstRegBank.getID()) {
Diana Picus657bfd32017-05-11 08:28:31 +0000674 DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
Diana Picus64a33432017-04-21 13:16:50 +0000675 return false;
676 }
677
678 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
Diana Picus657bfd32017-05-11 08:28:31 +0000679 DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
Diana Picus64a33432017-04-21 13:16:50 +0000680 return false;
681 }
682
683 I.setDesc(TII.get(COPY));
684 return selectCopy(I, TII, MRI, TRI, RBI);
685 }
Diana Picus7145d222017-06-27 09:19:51 +0000686 case G_SELECT:
687 return selectSelect(MIB, TII, MRI, TRI, RBI);
Diana Picus5b916532017-07-07 08:39:04 +0000688 case G_ICMP:
689 return selectCmp<int>(MIB, TII, MRI, TRI, RBI);
Diana Picus21014df2017-07-12 09:01:54 +0000690 case G_FCMP: {
Diana Picus5b916532017-07-07 08:39:04 +0000691 assert(TII.getSubtarget().hasVFP2() && "Can't select fcmp without VFP");
Diana Picus21014df2017-07-12 09:01:54 +0000692
693 unsigned OpReg = I.getOperand(2).getReg();
694 unsigned Size = MRI.getType(OpReg).getSizeInBits();
695 if (Size == 32)
696 return selectCmp<float>(MIB, TII, MRI, TRI, RBI);
697 if (Size == 64) {
698 if (TII.getSubtarget().isFPOnlySP()) {
699 DEBUG(dbgs() << "Subtarget only supports single precision");
700 return false;
701 }
702 return selectCmp<double>(MIB, TII, MRI, TRI, RBI);
703 }
704
705 DEBUG(dbgs() << "Unsupported size for G_FCMP operand");
706 return false;
707 }
Diana Picus9d070942017-02-28 10:14:38 +0000708 case G_GEP:
Diana Picus812caee2016-12-16 12:54:46 +0000709 I.setDesc(TII.get(ARM::ADDrr));
Diana Picus8a73f552017-01-13 10:18:01 +0000710 MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus519807f2016-12-19 11:26:31 +0000711 break;
712 case G_FRAME_INDEX:
713 // Add 0 to the given frame index and hope it will eventually be folded into
714 // the user(s).
715 I.setDesc(TII.get(ARM::ADDri));
Diana Picus8a73f552017-01-13 10:18:01 +0000716 MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus519807f2016-12-19 11:26:31 +0000717 break;
Diana Picus5a7203a2017-02-28 13:05:42 +0000718 case G_CONSTANT: {
719 unsigned Reg = I.getOperand(0).getReg();
720 if (MRI.getType(Reg).getSizeInBits() != 32)
721 return false;
722
723 assert(RBI.getRegBank(Reg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
724 "Expected constant to live in a GPR");
725 I.setDesc(TII.get(ARM::MOVi));
726 MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus95a8aa92017-04-24 06:30:56 +0000727
728 auto &Val = I.getOperand(1);
729 if (Val.isCImm()) {
730 if (Val.getCImm()->getBitWidth() > 32)
731 return false;
732 Val.ChangeToImmediate(Val.getCImm()->getZExtValue());
733 }
734
735 if (!Val.isImm()) {
736 return false;
737 }
738
Diana Picus5a7203a2017-02-28 13:05:42 +0000739 break;
740 }
Diana Picus3b99c642017-02-24 14:01:27 +0000741 case G_STORE:
Diana Picus278c7222017-01-26 09:20:47 +0000742 case G_LOAD: {
Diana Picus1c33c9f2017-02-20 14:45:58 +0000743 const auto &MemOp = **I.memoperands_begin();
744 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
745 DEBUG(dbgs() << "Atomic load/store not supported yet\n");
746 return false;
747 }
748
Diana Picus1540b062017-02-16 14:10:50 +0000749 unsigned Reg = I.getOperand(0).getReg();
750 unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
751
752 LLT ValTy = MRI.getType(Reg);
Diana Picus278c7222017-01-26 09:20:47 +0000753 const auto ValSize = ValTy.getSizeInBits();
754
Diana Picus1540b062017-02-16 14:10:50 +0000755 assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) &&
Diana Picus3b99c642017-02-24 14:01:27 +0000756 "Don't know how to load/store 64-bit value without VFP");
Diana Picus1540b062017-02-16 14:10:50 +0000757
Diana Picus3b99c642017-02-24 14:01:27 +0000758 const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
759 if (NewOpc == G_LOAD || NewOpc == G_STORE)
Diana Picuse8368782017-02-17 13:44:19 +0000760 return false;
761
Diana Picus278c7222017-01-26 09:20:47 +0000762 I.setDesc(TII.get(NewOpc));
763
Diana Picus3b99c642017-02-24 14:01:27 +0000764 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
Diana Picus278c7222017-01-26 09:20:47 +0000765 // LDRH has a funny addressing mode (there's already a FIXME for it).
766 MIB.addReg(0);
Diana Picus4f8c3e12017-01-13 09:37:56 +0000767 MIB.addImm(0).add(predOps(ARMCC::AL));
Diana Picus519807f2016-12-19 11:26:31 +0000768 break;
Diana Picus278c7222017-01-26 09:20:47 +0000769 }
Diana Picus0b4190a2017-06-07 12:35:05 +0000770 case G_MERGE_VALUES: {
771 if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
Diana Picusb1701e02017-02-16 12:19:57 +0000772 return false;
773 break;
774 }
Diana Picus0b4190a2017-06-07 12:35:05 +0000775 case G_UNMERGE_VALUES: {
776 if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
Diana Picusb1701e02017-02-16 12:19:57 +0000777 return false;
778 break;
779 }
Diana Picus519807f2016-12-19 11:26:31 +0000780 default:
781 return false;
Diana Picus812caee2016-12-16 12:54:46 +0000782 }
783
Diana Picus519807f2016-12-19 11:26:31 +0000784 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Diana Picus22274932016-11-11 08:27:37 +0000785}