blob: 0c95c21054dda4ca07bd60e1a729f1163505b23c [file] [log] [blame]
Diana Picus22274932016-11-11 08:27:37 +00001//===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Diana Picus22274932016-11-11 08:27:37 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for ARM.
10/// \todo This should be generated by TableGen.
11//===----------------------------------------------------------------------===//
12
Diana Picus22274932016-11-11 08:27:37 +000013#include "ARMRegisterBankInfo.h"
14#include "ARMSubtarget.h"
15#include "ARMTargetMachine.h"
Diana Picus674888d2017-04-28 09:10:38 +000016#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
David Blaikie62651302017-10-26 23:39:54 +000017#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Diana Picus930e6ec2017-08-03 09:14:59 +000018#include "llvm/CodeGen/MachineConstantPool.h"
Diana Picus812caee2016-12-16 12:54:46 +000019#include "llvm/CodeGen/MachineRegisterInfo.h"
Diana Picus22274932016-11-11 08:27:37 +000020#include "llvm/Support/Debug.h"
21
22#define DEBUG_TYPE "arm-isel"
23
24using namespace llvm;
25
Diana Picus674888d2017-04-28 09:10:38 +000026namespace {
Diana Picus8abcbbb2017-05-02 09:40:49 +000027
28#define GET_GLOBALISEL_PREDICATE_BITSET
29#include "ARMGenGlobalISel.inc"
30#undef GET_GLOBALISEL_PREDICATE_BITSET
31
Diana Picus674888d2017-04-28 09:10:38 +000032class ARMInstructionSelector : public InstructionSelector {
33public:
Diana Picus8abcbbb2017-05-02 09:40:49 +000034 ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
Diana Picus674888d2017-04-28 09:10:38 +000035 const ARMRegisterBankInfo &RBI);
36
Daniel Sandersf76f3152017-11-16 00:46:35 +000037 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000038 static const char *getName() { return DEBUG_TYPE; }
Diana Picus674888d2017-04-28 09:10:38 +000039
40private:
Daniel Sandersf76f3152017-11-16 00:46:35 +000041 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Diana Picus8abcbbb2017-05-02 09:40:49 +000042
Diana Picus995746d2017-07-12 10:31:16 +000043 struct CmpConstants;
44 struct InsertInfo;
Diana Picus5b916532017-07-07 08:39:04 +000045
Diana Picus995746d2017-07-12 10:31:16 +000046 bool selectCmp(CmpConstants Helper, MachineInstrBuilder &MIB,
47 MachineRegisterInfo &MRI) const;
Diana Picus621894a2017-06-19 09:40:51 +000048
Diana Picus995746d2017-07-12 10:31:16 +000049 // Helper for inserting a comparison sequence that sets \p ResReg to either 1
50 // if \p LHSReg and \p RHSReg are in the relationship defined by \p Cond, or
51 // \p PrevRes otherwise. In essence, it computes PrevRes OR (LHS Cond RHS).
52 bool insertComparison(CmpConstants Helper, InsertInfo I, unsigned ResReg,
53 ARMCC::CondCodes Cond, unsigned LHSReg, unsigned RHSReg,
54 unsigned PrevRes) const;
55
56 // Set \p DestReg to \p Constant.
57 void putConstant(InsertInfo I, unsigned DestReg, unsigned Constant) const;
58
Diana Picus930e6ec2017-08-03 09:14:59 +000059 bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
Diana Picus995746d2017-07-12 10:31:16 +000060 bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
Diana Picuse393bc72017-10-06 15:39:16 +000061 bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const;
Diana Picus995746d2017-07-12 10:31:16 +000062
63 // Check if the types match and both operands have the expected size and
64 // register bank.
65 bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
66 unsigned ExpectedSize, unsigned ExpectedRegBankID) const;
67
68 // Check if the register has the expected size and register bank.
69 bool validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize,
70 unsigned ExpectedRegBankID) const;
Diana Picus7145d222017-06-27 09:19:51 +000071
Diana Picus674888d2017-04-28 09:10:38 +000072 const ARMBaseInstrInfo &TII;
73 const ARMBaseRegisterInfo &TRI;
Diana Picus8abcbbb2017-05-02 09:40:49 +000074 const ARMBaseTargetMachine &TM;
Diana Picus674888d2017-04-28 09:10:38 +000075 const ARMRegisterBankInfo &RBI;
Diana Picus8abcbbb2017-05-02 09:40:49 +000076 const ARMSubtarget &STI;
77
Diana Picus813af0d2018-12-14 12:37:24 +000078 // Store the opcodes that we might need, so we don't have to check what kind
79 // of subtarget (ARM vs Thumb) we have all the time.
80 struct OpcodeCache {
81 unsigned ZEXT16;
82 unsigned SEXT16;
83
84 unsigned ZEXT8;
85 unsigned SEXT8;
86
87 // Used for implementing ZEXT/SEXT from i1
88 unsigned AND;
89 unsigned RSB;
90
91 unsigned STORE32;
92 unsigned LOAD32;
93
94 unsigned STORE16;
95 unsigned LOAD16;
96
97 unsigned STORE8;
98 unsigned LOAD8;
99
Diana Picusc0f964eb2019-02-15 10:50:02 +0000100 unsigned ADDrr;
101
Diana Picusaa4118a2019-02-13 11:25:32 +0000102 // Used for G_ICMP
Diana Picus75a04e22019-02-07 11:05:33 +0000103 unsigned CMPrr;
104 unsigned MOVi;
105 unsigned MOVCCi;
106
Diana Picusaa4118a2019-02-13 11:25:32 +0000107 // Used for G_SELECT
108 unsigned CMPri;
109 unsigned MOVCCr;
110
Diana Picusa00425f2019-02-15 10:24:03 +0000111 unsigned TSTri;
112 unsigned Bcc;
113
Diana Picus813af0d2018-12-14 12:37:24 +0000114 OpcodeCache(const ARMSubtarget &STI);
115 } const Opcodes;
116
117 // Select the opcode for simple extensions (that translate to a single SXT/UXT
118 // instruction). Extension operations more complicated than that should not
119 // invoke this. Returns the original opcode if it doesn't know how to select a
120 // better one.
121 unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) const;
122
123 // Select the opcode for simple loads and stores. Returns the original opcode
124 // if it doesn't know how to select a better one.
125 unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
126 unsigned Size) const;
127
Diana Picus8abcbbb2017-05-02 09:40:49 +0000128#define GET_GLOBALISEL_PREDICATES_DECL
129#include "ARMGenGlobalISel.inc"
130#undef GET_GLOBALISEL_PREDICATES_DECL
131
132// We declare the temporaries used by selectImpl() in the class to minimize the
133// cost of constructing placeholder values.
134#define GET_GLOBALISEL_TEMPORARIES_DECL
135#include "ARMGenGlobalISel.inc"
136#undef GET_GLOBALISEL_TEMPORARIES_DECL
Diana Picus674888d2017-04-28 09:10:38 +0000137};
138} // end anonymous namespace
139
140namespace llvm {
141InstructionSelector *
Diana Picus8abcbbb2017-05-02 09:40:49 +0000142createARMInstructionSelector(const ARMBaseTargetMachine &TM,
143 const ARMSubtarget &STI,
Diana Picus674888d2017-04-28 09:10:38 +0000144 const ARMRegisterBankInfo &RBI) {
Diana Picus8abcbbb2017-05-02 09:40:49 +0000145 return new ARMInstructionSelector(TM, STI, RBI);
Diana Picus674888d2017-04-28 09:10:38 +0000146}
147}
148
Daniel Sanders8e82af22017-07-27 11:03:45 +0000149const unsigned zero_reg = 0;
Diana Picus8abcbbb2017-05-02 09:40:49 +0000150
151#define GET_GLOBALISEL_IMPL
152#include "ARMGenGlobalISel.inc"
153#undef GET_GLOBALISEL_IMPL
154
155ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
156 const ARMSubtarget &STI,
Diana Picus22274932016-11-11 08:27:37 +0000157 const ARMRegisterBankInfo &RBI)
Diana Picus895c6aa2016-11-15 16:42:10 +0000158 : InstructionSelector(), TII(*STI.getInstrInfo()),
Diana Picus813af0d2018-12-14 12:37:24 +0000159 TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI), Opcodes(STI),
Diana Picus8abcbbb2017-05-02 09:40:49 +0000160#define GET_GLOBALISEL_PREDICATES_INIT
161#include "ARMGenGlobalISel.inc"
162#undef GET_GLOBALISEL_PREDICATES_INIT
163#define GET_GLOBALISEL_TEMPORARIES_INIT
164#include "ARMGenGlobalISel.inc"
165#undef GET_GLOBALISEL_TEMPORARIES_INIT
166{
167}
Diana Picus22274932016-11-11 08:27:37 +0000168
Diana Picus865f7fe2018-01-04 13:09:25 +0000169static const TargetRegisterClass *guessRegClass(unsigned Reg,
170 MachineRegisterInfo &MRI,
171 const TargetRegisterInfo &TRI,
172 const RegisterBankInfo &RBI) {
173 const RegisterBank *RegBank = RBI.getRegBank(Reg, MRI, TRI);
174 assert(RegBank && "Can't get reg bank for virtual register");
175
176 const unsigned Size = MRI.getType(Reg).getSizeInBits();
177 assert((RegBank->getID() == ARM::GPRRegBankID ||
178 RegBank->getID() == ARM::FPRRegBankID) &&
179 "Unsupported reg bank");
180
181 if (RegBank->getID() == ARM::FPRRegBankID) {
182 if (Size == 32)
183 return &ARM::SPRRegClass;
184 else if (Size == 64)
185 return &ARM::DPRRegClass;
Roman Tereshine79d6562018-05-23 02:59:31 +0000186 else if (Size == 128)
187 return &ARM::QPRRegClass;
Diana Picus865f7fe2018-01-04 13:09:25 +0000188 else
189 llvm_unreachable("Unsupported destination size");
190 }
191
192 return &ARM::GPRRegClass;
193}
194
Diana Picus812caee2016-12-16 12:54:46 +0000195static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
196 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
197 const RegisterBankInfo &RBI) {
198 unsigned DstReg = I.getOperand(0).getReg();
199 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
200 return true;
201
Diana Picus865f7fe2018-01-04 13:09:25 +0000202 const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
Diana Picus4fa83c02017-02-08 13:23:04 +0000203
Diana Picus812caee2016-12-16 12:54:46 +0000204 // No need to constrain SrcReg. It will get constrained when
205 // we hit another of its uses or its defs.
206 // Copies do not have constraints.
207 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000208 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
209 << " operand\n");
Diana Picus812caee2016-12-16 12:54:46 +0000210 return false;
211 }
212 return true;
213}
214
Diana Picus0b4190a2017-06-07 12:35:05 +0000215static bool selectMergeValues(MachineInstrBuilder &MIB,
216 const ARMBaseInstrInfo &TII,
217 MachineRegisterInfo &MRI,
218 const TargetRegisterInfo &TRI,
219 const RegisterBankInfo &RBI) {
220 assert(TII.getSubtarget().hasVFP2() && "Can't select merge without VFP");
Diana Picusb1701e02017-02-16 12:19:57 +0000221
Diana Picus0b4190a2017-06-07 12:35:05 +0000222 // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
Diana Picusb1701e02017-02-16 12:19:57 +0000223 // into one DPR.
224 unsigned VReg0 = MIB->getOperand(0).getReg();
225 (void)VReg0;
226 assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
227 RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000228 "Unsupported operand for G_MERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000229 unsigned VReg1 = MIB->getOperand(1).getReg();
230 (void)VReg1;
231 assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
232 RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000233 "Unsupported operand for G_MERGE_VALUES");
234 unsigned VReg2 = MIB->getOperand(2).getReg();
Diana Picusb1701e02017-02-16 12:19:57 +0000235 (void)VReg2;
236 assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
237 RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000238 "Unsupported operand for G_MERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000239
240 MIB->setDesc(TII.get(ARM::VMOVDRR));
241 MIB.add(predOps(ARMCC::AL));
242
243 return true;
244}
245
Diana Picus0b4190a2017-06-07 12:35:05 +0000246static bool selectUnmergeValues(MachineInstrBuilder &MIB,
247 const ARMBaseInstrInfo &TII,
248 MachineRegisterInfo &MRI,
249 const TargetRegisterInfo &TRI,
250 const RegisterBankInfo &RBI) {
251 assert(TII.getSubtarget().hasVFP2() && "Can't select unmerge without VFP");
Diana Picusb1701e02017-02-16 12:19:57 +0000252
Diana Picus0b4190a2017-06-07 12:35:05 +0000253 // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
254 // GPRs.
Diana Picusb1701e02017-02-16 12:19:57 +0000255 unsigned VReg0 = MIB->getOperand(0).getReg();
256 (void)VReg0;
257 assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
258 RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
Diana Picus0b4190a2017-06-07 12:35:05 +0000259 "Unsupported operand for G_UNMERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000260 unsigned VReg1 = MIB->getOperand(1).getReg();
261 (void)VReg1;
Diana Picus0b4190a2017-06-07 12:35:05 +0000262 assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
263 RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
264 "Unsupported operand for G_UNMERGE_VALUES");
265 unsigned VReg2 = MIB->getOperand(2).getReg();
266 (void)VReg2;
267 assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
268 RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
269 "Unsupported operand for G_UNMERGE_VALUES");
Diana Picusb1701e02017-02-16 12:19:57 +0000270
Diana Picus0b4190a2017-06-07 12:35:05 +0000271 MIB->setDesc(TII.get(ARM::VMOVRRD));
Diana Picusb1701e02017-02-16 12:19:57 +0000272 MIB.add(predOps(ARMCC::AL));
273
274 return true;
275}
276
Diana Picus813af0d2018-12-14 12:37:24 +0000277ARMInstructionSelector::OpcodeCache::OpcodeCache(const ARMSubtarget &STI) {
278 bool isThumb = STI.isThumb();
279
280 using namespace TargetOpcode;
281
282#define STORE_OPCODE(VAR, OPC) VAR = isThumb ? ARM::t2##OPC : ARM::OPC
283 STORE_OPCODE(SEXT16, SXTH);
284 STORE_OPCODE(ZEXT16, UXTH);
285
286 STORE_OPCODE(SEXT8, SXTB);
287 STORE_OPCODE(ZEXT8, UXTB);
288
289 STORE_OPCODE(AND, ANDri);
290 STORE_OPCODE(RSB, RSBri);
291
292 STORE_OPCODE(STORE32, STRi12);
293 STORE_OPCODE(LOAD32, LDRi12);
294
295 // LDRH/STRH are special...
296 STORE16 = isThumb ? ARM::t2STRHi12 : ARM::STRH;
297 LOAD16 = isThumb ? ARM::t2LDRHi12 : ARM::LDRH;
298
299 STORE_OPCODE(STORE8, STRBi12);
300 STORE_OPCODE(LOAD8, LDRBi12);
Diana Picus75a04e22019-02-07 11:05:33 +0000301
Diana Picusc0f964eb2019-02-15 10:50:02 +0000302 STORE_OPCODE(ADDrr, ADDrr);
303
Diana Picus75a04e22019-02-07 11:05:33 +0000304 STORE_OPCODE(CMPrr, CMPrr);
305 STORE_OPCODE(MOVi, MOVi);
306 STORE_OPCODE(MOVCCi, MOVCCi);
Diana Picusaa4118a2019-02-13 11:25:32 +0000307
308 STORE_OPCODE(CMPri, CMPri);
309 STORE_OPCODE(MOVCCr, MOVCCr);
Diana Picusa00425f2019-02-15 10:24:03 +0000310
311 STORE_OPCODE(TSTri, TSTri);
312 STORE_OPCODE(Bcc, Bcc);
Diana Picus813af0d2018-12-14 12:37:24 +0000313#undef MAP_OPCODE
314}
315
316unsigned ARMInstructionSelector::selectSimpleExtOpc(unsigned Opc,
317 unsigned Size) const {
Diana Picus8b6c6be2017-01-25 08:10:40 +0000318 using namespace TargetOpcode;
319
Diana Picuse8368782017-02-17 13:44:19 +0000320 if (Size != 8 && Size != 16)
321 return Opc;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000322
323 if (Opc == G_SEXT)
Diana Picus813af0d2018-12-14 12:37:24 +0000324 return Size == 8 ? Opcodes.SEXT8 : Opcodes.SEXT16;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000325
326 if (Opc == G_ZEXT)
Diana Picus813af0d2018-12-14 12:37:24 +0000327 return Size == 8 ? Opcodes.ZEXT8 : Opcodes.ZEXT16;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000328
Diana Picuse8368782017-02-17 13:44:19 +0000329 return Opc;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000330}
331
Diana Picus813af0d2018-12-14 12:37:24 +0000332unsigned ARMInstructionSelector::selectLoadStoreOpCode(unsigned Opc,
333 unsigned RegBank,
334 unsigned Size) const {
Diana Picus3b99c642017-02-24 14:01:27 +0000335 bool isStore = Opc == TargetOpcode::G_STORE;
336
Diana Picus1540b062017-02-16 14:10:50 +0000337 if (RegBank == ARM::GPRRegBankID) {
338 switch (Size) {
339 case 1:
340 case 8:
Diana Picus813af0d2018-12-14 12:37:24 +0000341 return isStore ? Opcodes.STORE8 : Opcodes.LOAD8;
Diana Picus1540b062017-02-16 14:10:50 +0000342 case 16:
Diana Picus813af0d2018-12-14 12:37:24 +0000343 return isStore ? Opcodes.STORE16 : Opcodes.LOAD16;
Diana Picus1540b062017-02-16 14:10:50 +0000344 case 32:
Diana Picus813af0d2018-12-14 12:37:24 +0000345 return isStore ? Opcodes.STORE32 : Opcodes.LOAD32;
Diana Picuse8368782017-02-17 13:44:19 +0000346 default:
Diana Picus3b99c642017-02-24 14:01:27 +0000347 return Opc;
Diana Picus1540b062017-02-16 14:10:50 +0000348 }
Diana Picus1540b062017-02-16 14:10:50 +0000349 }
350
Diana Picuse8368782017-02-17 13:44:19 +0000351 if (RegBank == ARM::FPRRegBankID) {
352 switch (Size) {
353 case 32:
Diana Picus3b99c642017-02-24 14:01:27 +0000354 return isStore ? ARM::VSTRS : ARM::VLDRS;
Diana Picuse8368782017-02-17 13:44:19 +0000355 case 64:
Diana Picus3b99c642017-02-24 14:01:27 +0000356 return isStore ? ARM::VSTRD : ARM::VLDRD;
Diana Picuse8368782017-02-17 13:44:19 +0000357 default:
Diana Picus3b99c642017-02-24 14:01:27 +0000358 return Opc;
Diana Picuse8368782017-02-17 13:44:19 +0000359 }
Diana Picus278c7222017-01-26 09:20:47 +0000360 }
361
Diana Picus3b99c642017-02-24 14:01:27 +0000362 return Opc;
Diana Picus278c7222017-01-26 09:20:47 +0000363}
364
Diana Picus5b916532017-07-07 08:39:04 +0000365// When lowering comparisons, we sometimes need to perform two compares instead
366// of just one. Get the condition codes for both comparisons. If only one is
367// needed, the second member of the pair is ARMCC::AL.
368static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
369getComparePreds(CmpInst::Predicate Pred) {
370 std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
Diana Picus621894a2017-06-19 09:40:51 +0000371 switch (Pred) {
Diana Picus621894a2017-06-19 09:40:51 +0000372 case CmpInst::FCMP_ONE:
Diana Picus5b916532017-07-07 08:39:04 +0000373 Preds = {ARMCC::GT, ARMCC::MI};
374 break;
Diana Picus621894a2017-06-19 09:40:51 +0000375 case CmpInst::FCMP_UEQ:
Diana Picus5b916532017-07-07 08:39:04 +0000376 Preds = {ARMCC::EQ, ARMCC::VS};
377 break;
Diana Picus621894a2017-06-19 09:40:51 +0000378 case CmpInst::ICMP_EQ:
379 case CmpInst::FCMP_OEQ:
Diana Picus5b916532017-07-07 08:39:04 +0000380 Preds.first = ARMCC::EQ;
381 break;
Diana Picus621894a2017-06-19 09:40:51 +0000382 case CmpInst::ICMP_SGT:
383 case CmpInst::FCMP_OGT:
Diana Picus5b916532017-07-07 08:39:04 +0000384 Preds.first = ARMCC::GT;
385 break;
Diana Picus621894a2017-06-19 09:40:51 +0000386 case CmpInst::ICMP_SGE:
387 case CmpInst::FCMP_OGE:
Diana Picus5b916532017-07-07 08:39:04 +0000388 Preds.first = ARMCC::GE;
389 break;
Diana Picus621894a2017-06-19 09:40:51 +0000390 case CmpInst::ICMP_UGT:
391 case CmpInst::FCMP_UGT:
Diana Picus5b916532017-07-07 08:39:04 +0000392 Preds.first = ARMCC::HI;
393 break;
Diana Picus621894a2017-06-19 09:40:51 +0000394 case CmpInst::FCMP_OLT:
Diana Picus5b916532017-07-07 08:39:04 +0000395 Preds.first = ARMCC::MI;
396 break;
Diana Picus621894a2017-06-19 09:40:51 +0000397 case CmpInst::ICMP_ULE:
398 case CmpInst::FCMP_OLE:
Diana Picus5b916532017-07-07 08:39:04 +0000399 Preds.first = ARMCC::LS;
400 break;
Diana Picus621894a2017-06-19 09:40:51 +0000401 case CmpInst::FCMP_ORD:
Diana Picus5b916532017-07-07 08:39:04 +0000402 Preds.first = ARMCC::VC;
403 break;
Diana Picus621894a2017-06-19 09:40:51 +0000404 case CmpInst::FCMP_UNO:
Diana Picus5b916532017-07-07 08:39:04 +0000405 Preds.first = ARMCC::VS;
406 break;
Diana Picus621894a2017-06-19 09:40:51 +0000407 case CmpInst::FCMP_UGE:
Diana Picus5b916532017-07-07 08:39:04 +0000408 Preds.first = ARMCC::PL;
409 break;
Diana Picus621894a2017-06-19 09:40:51 +0000410 case CmpInst::ICMP_SLT:
411 case CmpInst::FCMP_ULT:
Diana Picus5b916532017-07-07 08:39:04 +0000412 Preds.first = ARMCC::LT;
413 break;
Diana Picus621894a2017-06-19 09:40:51 +0000414 case CmpInst::ICMP_SLE:
415 case CmpInst::FCMP_ULE:
Diana Picus5b916532017-07-07 08:39:04 +0000416 Preds.first = ARMCC::LE;
417 break;
Diana Picus621894a2017-06-19 09:40:51 +0000418 case CmpInst::FCMP_UNE:
419 case CmpInst::ICMP_NE:
Diana Picus5b916532017-07-07 08:39:04 +0000420 Preds.first = ARMCC::NE;
421 break;
Diana Picus621894a2017-06-19 09:40:51 +0000422 case CmpInst::ICMP_UGE:
Diana Picus5b916532017-07-07 08:39:04 +0000423 Preds.first = ARMCC::HS;
424 break;
Diana Picus621894a2017-06-19 09:40:51 +0000425 case CmpInst::ICMP_ULT:
Diana Picus5b916532017-07-07 08:39:04 +0000426 Preds.first = ARMCC::LO;
427 break;
428 default:
429 break;
Diana Picus621894a2017-06-19 09:40:51 +0000430 }
Diana Picus5b916532017-07-07 08:39:04 +0000431 assert(Preds.first != ARMCC::AL && "No comparisons needed?");
432 return Preds;
Diana Picus621894a2017-06-19 09:40:51 +0000433}
434
Diana Picus995746d2017-07-12 10:31:16 +0000435struct ARMInstructionSelector::CmpConstants {
Diana Picus75a04e22019-02-07 11:05:33 +0000436 CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned SelectOpcode,
437 unsigned OpRegBank, unsigned OpSize)
Diana Picus995746d2017-07-12 10:31:16 +0000438 : ComparisonOpcode(CmpOpcode), ReadFlagsOpcode(FlagsOpcode),
Diana Picus75a04e22019-02-07 11:05:33 +0000439 SelectResultOpcode(SelectOpcode), OperandRegBankID(OpRegBank),
440 OperandSize(OpSize) {}
Diana Picus621894a2017-06-19 09:40:51 +0000441
Diana Picus5b916532017-07-07 08:39:04 +0000442 // The opcode used for performing the comparison.
Diana Picus995746d2017-07-12 10:31:16 +0000443 const unsigned ComparisonOpcode;
Diana Picus621894a2017-06-19 09:40:51 +0000444
Diana Picus5b916532017-07-07 08:39:04 +0000445 // The opcode used for reading the flags set by the comparison. May be
446 // ARM::INSTRUCTION_LIST_END if we don't need to read the flags.
Diana Picus995746d2017-07-12 10:31:16 +0000447 const unsigned ReadFlagsOpcode;
Diana Picus5b916532017-07-07 08:39:04 +0000448
Diana Picus75a04e22019-02-07 11:05:33 +0000449 // The opcode used for materializing the result of the comparison.
450 const unsigned SelectResultOpcode;
451
Diana Picus5b916532017-07-07 08:39:04 +0000452 // The assumed register bank ID for the operands.
Diana Picus995746d2017-07-12 10:31:16 +0000453 const unsigned OperandRegBankID;
Diana Picus5b916532017-07-07 08:39:04 +0000454
Diana Picus21014df2017-07-12 09:01:54 +0000455 // The assumed size in bits for the operands.
Diana Picus995746d2017-07-12 10:31:16 +0000456 const unsigned OperandSize;
Diana Picus5b916532017-07-07 08:39:04 +0000457};
458
Diana Picus995746d2017-07-12 10:31:16 +0000459struct ARMInstructionSelector::InsertInfo {
460 InsertInfo(MachineInstrBuilder &MIB)
461 : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())),
462 DbgLoc(MIB->getDebugLoc()) {}
Diana Picus5b916532017-07-07 08:39:04 +0000463
Diana Picus995746d2017-07-12 10:31:16 +0000464 MachineBasicBlock &MBB;
465 const MachineBasicBlock::instr_iterator InsertBefore;
466 const DebugLoc &DbgLoc;
467};
Diana Picus5b916532017-07-07 08:39:04 +0000468
Diana Picus995746d2017-07-12 10:31:16 +0000469void ARMInstructionSelector::putConstant(InsertInfo I, unsigned DestReg,
470 unsigned Constant) const {
Diana Picus75a04e22019-02-07 11:05:33 +0000471 (void)BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Opcodes.MOVi))
Diana Picus995746d2017-07-12 10:31:16 +0000472 .addDef(DestReg)
473 .addImm(Constant)
474 .add(predOps(ARMCC::AL))
475 .add(condCodeOp());
476}
Diana Picus21014df2017-07-12 09:01:54 +0000477
Diana Picus995746d2017-07-12 10:31:16 +0000478bool ARMInstructionSelector::validOpRegPair(MachineRegisterInfo &MRI,
479 unsigned LHSReg, unsigned RHSReg,
480 unsigned ExpectedSize,
481 unsigned ExpectedRegBankID) const {
482 return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
483 validReg(MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
484 validReg(MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
485}
Diana Picus5b916532017-07-07 08:39:04 +0000486
Diana Picus995746d2017-07-12 10:31:16 +0000487bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg,
488 unsigned ExpectedSize,
489 unsigned ExpectedRegBankID) const {
490 if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000491 LLVM_DEBUG(dbgs() << "Unexpected size for register");
Diana Picus995746d2017-07-12 10:31:16 +0000492 return false;
493 }
494
495 if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000496 LLVM_DEBUG(dbgs() << "Unexpected register bank for register");
Diana Picus995746d2017-07-12 10:31:16 +0000497 return false;
498 }
499
500 return true;
501}
502
503bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
504 MachineInstrBuilder &MIB,
505 MachineRegisterInfo &MRI) const {
506 const InsertInfo I(MIB);
Diana Picus5b916532017-07-07 08:39:04 +0000507
Diana Picus621894a2017-06-19 09:40:51 +0000508 auto ResReg = MIB->getOperand(0).getReg();
Diana Picus995746d2017-07-12 10:31:16 +0000509 if (!validReg(MRI, ResReg, 1, ARM::GPRRegBankID))
Diana Picus5b916532017-07-07 08:39:04 +0000510 return false;
511
Diana Picus621894a2017-06-19 09:40:51 +0000512 auto Cond =
513 static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
Diana Picus5b916532017-07-07 08:39:04 +0000514 if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) {
Diana Picus995746d2017-07-12 10:31:16 +0000515 putConstant(I, ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0);
Diana Picus5b916532017-07-07 08:39:04 +0000516 MIB->eraseFromParent();
517 return true;
518 }
519
520 auto LHSReg = MIB->getOperand(2).getReg();
521 auto RHSReg = MIB->getOperand(3).getReg();
Diana Picus995746d2017-07-12 10:31:16 +0000522 if (!validOpRegPair(MRI, LHSReg, RHSReg, Helper.OperandSize,
523 Helper.OperandRegBankID))
Diana Picus621894a2017-06-19 09:40:51 +0000524 return false;
525
Diana Picus5b916532017-07-07 08:39:04 +0000526 auto ARMConds = getComparePreds(Cond);
Diana Picus995746d2017-07-12 10:31:16 +0000527 auto ZeroReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
528 putConstant(I, ZeroReg, 0);
Diana Picus5b916532017-07-07 08:39:04 +0000529
530 if (ARMConds.second == ARMCC::AL) {
531 // Simple case, we only need one comparison and we're done.
Diana Picus995746d2017-07-12 10:31:16 +0000532 if (!insertComparison(Helper, I, ResReg, ARMConds.first, LHSReg, RHSReg,
533 ZeroReg))
Diana Picus5b916532017-07-07 08:39:04 +0000534 return false;
535 } else {
536 // Not so simple, we need two successive comparisons.
537 auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
Diana Picus995746d2017-07-12 10:31:16 +0000538 if (!insertComparison(Helper, I, IntermediateRes, ARMConds.first, LHSReg,
539 RHSReg, ZeroReg))
Diana Picus5b916532017-07-07 08:39:04 +0000540 return false;
Diana Picus995746d2017-07-12 10:31:16 +0000541 if (!insertComparison(Helper, I, ResReg, ARMConds.second, LHSReg, RHSReg,
542 IntermediateRes))
Diana Picus5b916532017-07-07 08:39:04 +0000543 return false;
544 }
Diana Picus621894a2017-06-19 09:40:51 +0000545
546 MIB->eraseFromParent();
547 return true;
548}
549
Diana Picus995746d2017-07-12 10:31:16 +0000550bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I,
551 unsigned ResReg,
552 ARMCC::CondCodes Cond,
553 unsigned LHSReg, unsigned RHSReg,
554 unsigned PrevRes) const {
555 // Perform the comparison.
556 auto CmpI =
557 BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Helper.ComparisonOpcode))
558 .addUse(LHSReg)
559 .addUse(RHSReg)
560 .add(predOps(ARMCC::AL));
561 if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
562 return false;
563
564 // Read the comparison flags (if necessary).
565 if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
566 auto ReadI = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
567 TII.get(Helper.ReadFlagsOpcode))
568 .add(predOps(ARMCC::AL));
569 if (!constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
570 return false;
571 }
572
573 // Select either 1 or the previous result based on the value of the flags.
Diana Picus75a04e22019-02-07 11:05:33 +0000574 auto Mov1I = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
575 TII.get(Helper.SelectResultOpcode))
Diana Picus995746d2017-07-12 10:31:16 +0000576 .addDef(ResReg)
577 .addUse(PrevRes)
578 .addImm(1)
579 .add(predOps(Cond, ARM::CPSR));
580 if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
581 return false;
582
583 return true;
584}
585
Diana Picus930e6ec2017-08-03 09:14:59 +0000586bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
587 MachineRegisterInfo &MRI) const {
Diana Picusabb08862017-09-05 07:57:41 +0000588 if ((STI.isROPI() || STI.isRWPI()) && !STI.isTargetELF()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000589 LLVM_DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n");
Diana Picus930e6ec2017-08-03 09:14:59 +0000590 return false;
591 }
Diana Picus930e6ec2017-08-03 09:14:59 +0000592
593 auto GV = MIB->getOperand(1).getGlobal();
594 if (GV->isThreadLocal()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000595 LLVM_DEBUG(dbgs() << "TLS variables not supported yet\n");
Diana Picus930e6ec2017-08-03 09:14:59 +0000596 return false;
597 }
598
599 auto &MBB = *MIB->getParent();
600 auto &MF = *MBB.getParent();
601
Sam Parker5b098342019-02-08 07:57:42 +0000602 bool UseMovt = STI.useMovt();
Diana Picus930e6ec2017-08-03 09:14:59 +0000603
Matt Arsenault41e5ac42018-03-14 00:36:23 +0000604 unsigned Size = TM.getPointerSize(0);
Diana Picusc9f29c62017-08-29 09:47:55 +0000605 unsigned Alignment = 4;
Diana Picusabb08862017-09-05 07:57:41 +0000606
607 auto addOpsForConstantPoolLoad = [&MF, Alignment,
608 Size](MachineInstrBuilder &MIB,
609 const GlobalValue *GV, bool IsSBREL) {
610 assert(MIB->getOpcode() == ARM::LDRi12 && "Unsupported instruction");
611 auto ConstPool = MF.getConstantPool();
612 auto CPIndex =
613 // For SB relative entries we need a target-specific constant pool.
614 // Otherwise, just use a regular constant pool entry.
615 IsSBREL
616 ? ConstPool->getConstantPoolIndex(
617 ARMConstantPoolConstant::Create(GV, ARMCP::SBREL), Alignment)
618 : ConstPool->getConstantPoolIndex(GV, Alignment);
619 MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
620 .addMemOperand(
621 MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
622 MachineMemOperand::MOLoad, Size, Alignment))
623 .addImm(0)
624 .add(predOps(ARMCC::AL));
625 };
626
Diana Picusc9f29c62017-08-29 09:47:55 +0000627 if (TM.isPositionIndependent()) {
Diana Picusac154732017-09-05 08:22:47 +0000628 bool Indirect = STI.isGVIndirectSymbol(GV);
Diana Picusc9f29c62017-08-29 09:47:55 +0000629 // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't
630 // support it yet. See PR28229.
631 unsigned Opc =
Diana Picusac154732017-09-05 08:22:47 +0000632 UseMovt && !STI.isTargetELF()
Diana Picusc9f29c62017-08-29 09:47:55 +0000633 ? (Indirect ? ARM::MOV_ga_pcrel_ldr : ARM::MOV_ga_pcrel)
634 : (Indirect ? ARM::LDRLIT_ga_pcrel_ldr : ARM::LDRLIT_ga_pcrel);
635 MIB->setDesc(TII.get(Opc));
636
Evgeniy Stepanov76d5ac42017-11-13 20:45:38 +0000637 int TargetFlags = ARMII::MO_NO_FLAG;
Diana Picusac154732017-09-05 08:22:47 +0000638 if (STI.isTargetDarwin())
Evgeniy Stepanov76d5ac42017-11-13 20:45:38 +0000639 TargetFlags |= ARMII::MO_NONLAZY;
640 if (STI.isGVInGOT(GV))
641 TargetFlags |= ARMII::MO_GOT;
642 MIB->getOperand(1).setTargetFlags(TargetFlags);
Diana Picusc9f29c62017-08-29 09:47:55 +0000643
644 if (Indirect)
645 MIB.addMemOperand(MF.getMachineMemOperand(
646 MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad,
Matt Arsenault41e5ac42018-03-14 00:36:23 +0000647 TM.getProgramPointerSize(), Alignment));
Diana Picusc9f29c62017-08-29 09:47:55 +0000648
Diana Picusac154732017-09-05 08:22:47 +0000649 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
Diana Picusc9f29c62017-08-29 09:47:55 +0000650 }
651
Diana Picusf95979112017-09-01 11:13:39 +0000652 bool isReadOnly = STI.getTargetLowering()->isReadOnly(GV);
653 if (STI.isROPI() && isReadOnly) {
654 unsigned Opc = UseMovt ? ARM::MOV_ga_pcrel : ARM::LDRLIT_ga_pcrel;
655 MIB->setDesc(TII.get(Opc));
656 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
657 }
Diana Picusabb08862017-09-05 07:57:41 +0000658 if (STI.isRWPI() && !isReadOnly) {
659 auto Offset = MRI.createVirtualRegister(&ARM::GPRRegClass);
660 MachineInstrBuilder OffsetMIB;
661 if (UseMovt) {
662 OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
663 TII.get(ARM::MOVi32imm), Offset);
664 OffsetMIB.addGlobalAddress(GV, /*Offset*/ 0, ARMII::MO_SBREL);
665 } else {
666 // Load the offset from the constant pool.
667 OffsetMIB =
668 BuildMI(MBB, *MIB, MIB->getDebugLoc(), TII.get(ARM::LDRi12), Offset);
669 addOpsForConstantPoolLoad(OffsetMIB, GV, /*IsSBREL*/ true);
670 }
671 if (!constrainSelectedInstRegOperands(*OffsetMIB, TII, TRI, RBI))
672 return false;
673
674 // Add the offset to the SB register.
675 MIB->setDesc(TII.get(ARM::ADDrr));
676 MIB->RemoveOperand(1);
677 MIB.addReg(ARM::R9) // FIXME: don't hardcode R9
678 .addReg(Offset)
679 .add(predOps(ARMCC::AL))
680 .add(condCodeOp());
681
682 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
683 }
Diana Picusf95979112017-09-01 11:13:39 +0000684
Diana Picusac154732017-09-05 08:22:47 +0000685 if (STI.isTargetELF()) {
Diana Picus930e6ec2017-08-03 09:14:59 +0000686 if (UseMovt) {
687 MIB->setDesc(TII.get(ARM::MOVi32imm));
688 } else {
689 // Load the global's address from the constant pool.
690 MIB->setDesc(TII.get(ARM::LDRi12));
691 MIB->RemoveOperand(1);
Diana Picusabb08862017-09-05 07:57:41 +0000692 addOpsForConstantPoolLoad(MIB, GV, /*IsSBREL*/ false);
Diana Picus930e6ec2017-08-03 09:14:59 +0000693 }
Diana Picusac154732017-09-05 08:22:47 +0000694 } else if (STI.isTargetMachO()) {
Diana Picus930e6ec2017-08-03 09:14:59 +0000695 if (UseMovt)
696 MIB->setDesc(TII.get(ARM::MOVi32imm));
697 else
698 MIB->setDesc(TII.get(ARM::LDRLIT_ga_abs));
699 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000700 LLVM_DEBUG(dbgs() << "Object format not supported yet\n");
Diana Picus930e6ec2017-08-03 09:14:59 +0000701 return false;
702 }
703
704 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
705}
706
Diana Picus7145d222017-06-27 09:19:51 +0000707bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
Diana Picus995746d2017-07-12 10:31:16 +0000708 MachineRegisterInfo &MRI) const {
Diana Picus7145d222017-06-27 09:19:51 +0000709 auto &MBB = *MIB->getParent();
710 auto InsertBefore = std::next(MIB->getIterator());
Diana Picus77367372017-07-07 08:53:27 +0000711 auto &DbgLoc = MIB->getDebugLoc();
Diana Picus7145d222017-06-27 09:19:51 +0000712
713 // Compare the condition to 0.
714 auto CondReg = MIB->getOperand(1).getReg();
Diana Picus995746d2017-07-12 10:31:16 +0000715 assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) &&
Diana Picus7145d222017-06-27 09:19:51 +0000716 "Unsupported types for select operation");
Diana Picusaa4118a2019-02-13 11:25:32 +0000717 auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.CMPri))
Diana Picus7145d222017-06-27 09:19:51 +0000718 .addUse(CondReg)
719 .addImm(0)
720 .add(predOps(ARMCC::AL));
721 if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
722 return false;
723
724 // Move a value into the result register based on the result of the
725 // comparison.
726 auto ResReg = MIB->getOperand(0).getReg();
727 auto TrueReg = MIB->getOperand(2).getReg();
728 auto FalseReg = MIB->getOperand(3).getReg();
Diana Picus995746d2017-07-12 10:31:16 +0000729 assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
730 validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
Diana Picus7145d222017-06-27 09:19:51 +0000731 "Unsupported types for select operation");
Diana Picusaa4118a2019-02-13 11:25:32 +0000732 auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.MOVCCr))
Diana Picus7145d222017-06-27 09:19:51 +0000733 .addDef(ResReg)
734 .addUse(TrueReg)
735 .addUse(FalseReg)
736 .add(predOps(ARMCC::EQ, ARM::CPSR));
737 if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
738 return false;
739
740 MIB->eraseFromParent();
741 return true;
742}
743
Diana Picuse393bc72017-10-06 15:39:16 +0000744bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
745 MachineInstrBuilder &MIB) const {
746 MIB->setDesc(TII.get(ARM::MOVsr));
747 MIB.addImm(ShiftOpc);
748 MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
749 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
750}
751
Daniel Sandersf76f3152017-11-16 00:46:35 +0000752bool ARMInstructionSelector::select(MachineInstr &I,
753 CodeGenCoverage &CoverageInfo) const {
Diana Picus812caee2016-12-16 12:54:46 +0000754 assert(I.getParent() && "Instruction should be in a basic block!");
755 assert(I.getParent()->getParent() && "Instruction should be in a function!");
756
757 auto &MBB = *I.getParent();
758 auto &MF = *MBB.getParent();
759 auto &MRI = MF.getRegInfo();
760
761 if (!isPreISelGenericOpcode(I.getOpcode())) {
762 if (I.isCopy())
763 return selectCopy(I, TII, MRI, TRI, RBI);
764
765 return true;
766 }
767
Diana Picus68773852017-12-22 11:09:18 +0000768 using namespace TargetOpcode;
Diana Picus68773852017-12-22 11:09:18 +0000769
Daniel Sandersf76f3152017-11-16 00:46:35 +0000770 if (selectImpl(I, CoverageInfo))
Diana Picus8abcbbb2017-05-02 09:40:49 +0000771 return true;
772
Diana Picus519807f2016-12-19 11:26:31 +0000773 MachineInstrBuilder MIB{MF, I};
Diana Picusd83df5d2017-01-25 08:47:40 +0000774 bool isSExt = false;
Diana Picus519807f2016-12-19 11:26:31 +0000775
Diana Picus519807f2016-12-19 11:26:31 +0000776 switch (I.getOpcode()) {
Diana Picus8b6c6be2017-01-25 08:10:40 +0000777 case G_SEXT:
Diana Picusd83df5d2017-01-25 08:47:40 +0000778 isSExt = true;
779 LLVM_FALLTHROUGH;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000780 case G_ZEXT: {
781 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
782 // FIXME: Smaller destination sizes coming soon!
783 if (DstTy.getSizeInBits() != 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000784 LLVM_DEBUG(dbgs() << "Unsupported destination size for extension");
Diana Picus8b6c6be2017-01-25 08:10:40 +0000785 return false;
786 }
787
788 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
789 unsigned SrcSize = SrcTy.getSizeInBits();
790 switch (SrcSize) {
Diana Picusd83df5d2017-01-25 08:47:40 +0000791 case 1: {
792 // ZExt boils down to & 0x1; for SExt we also subtract that from 0
Diana Picus813af0d2018-12-14 12:37:24 +0000793 I.setDesc(TII.get(Opcodes.AND));
Diana Picusd83df5d2017-01-25 08:47:40 +0000794 MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
795
796 if (isSExt) {
797 unsigned SExtResult = I.getOperand(0).getReg();
798
799 // Use a new virtual register for the result of the AND
800 unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
801 I.getOperand(0).setReg(AndResult);
802
803 auto InsertBefore = std::next(I.getIterator());
Diana Picus813af0d2018-12-14 12:37:24 +0000804 auto SubI =
805 BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(Opcodes.RSB))
806 .addDef(SExtResult)
807 .addUse(AndResult)
808 .addImm(0)
809 .add(predOps(ARMCC::AL))
810 .add(condCodeOp());
Diana Picusd83df5d2017-01-25 08:47:40 +0000811 if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
812 return false;
813 }
814 break;
815 }
Diana Picus8b6c6be2017-01-25 08:10:40 +0000816 case 8:
817 case 16: {
Diana Picus813af0d2018-12-14 12:37:24 +0000818 unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
Diana Picuse8368782017-02-17 13:44:19 +0000819 if (NewOpc == I.getOpcode())
820 return false;
Diana Picus8b6c6be2017-01-25 08:10:40 +0000821 I.setDesc(TII.get(NewOpc));
822 MIB.addImm(0).add(predOps(ARMCC::AL));
823 break;
824 }
825 default:
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000826 LLVM_DEBUG(dbgs() << "Unsupported source size for extension");
Diana Picus8b6c6be2017-01-25 08:10:40 +0000827 return false;
828 }
829 break;
830 }
Diana Picus657bfd32017-05-11 08:28:31 +0000831 case G_ANYEXT:
Diana Picus64a33432017-04-21 13:16:50 +0000832 case G_TRUNC: {
833 // The high bits are undefined, so there's nothing special to do, just
834 // treat it as a copy.
835 auto SrcReg = I.getOperand(1).getReg();
836 auto DstReg = I.getOperand(0).getReg();
837
838 const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
839 const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
840
Diana Picus75ce8522017-12-20 11:27:10 +0000841 if (SrcRegBank.getID() == ARM::FPRRegBankID) {
842 // This should only happen in the obscure case where we have put a 64-bit
843 // integer into a D register. Get it out of there and keep only the
844 // interesting part.
845 assert(I.getOpcode() == G_TRUNC && "Unsupported operand for G_ANYEXT");
846 assert(DstRegBank.getID() == ARM::GPRRegBankID &&
847 "Unsupported combination of register banks");
848 assert(MRI.getType(SrcReg).getSizeInBits() == 64 && "Unsupported size");
849 assert(MRI.getType(DstReg).getSizeInBits() <= 32 && "Unsupported size");
850
851 unsigned IgnoredBits = MRI.createVirtualRegister(&ARM::GPRRegClass);
852 auto InsertBefore = std::next(I.getIterator());
853 auto MovI =
854 BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::VMOVRRD))
855 .addDef(DstReg)
856 .addDef(IgnoredBits)
857 .addUse(SrcReg)
858 .add(predOps(ARMCC::AL));
859 if (!constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI))
860 return false;
861
862 MIB->eraseFromParent();
863 return true;
864 }
865
Diana Picus64a33432017-04-21 13:16:50 +0000866 if (SrcRegBank.getID() != DstRegBank.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000867 LLVM_DEBUG(
868 dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
Diana Picus64a33432017-04-21 13:16:50 +0000869 return false;
870 }
871
872 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000873 LLVM_DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
Diana Picus64a33432017-04-21 13:16:50 +0000874 return false;
875 }
876
877 I.setDesc(TII.get(COPY));
878 return selectCopy(I, TII, MRI, TRI, RBI);
879 }
Diana Picus37ae9f62018-01-04 10:54:57 +0000880 case G_CONSTANT: {
881 if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) {
882 // Non-pointer constants should be handled by TableGen.
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000883 LLVM_DEBUG(dbgs() << "Unsupported constant type\n");
Diana Picus37ae9f62018-01-04 10:54:57 +0000884 return false;
885 }
886
887 auto &Val = I.getOperand(1);
888 if (Val.isCImm()) {
889 if (!Val.getCImm()->isZero()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000890 LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
Diana Picus37ae9f62018-01-04 10:54:57 +0000891 return false;
892 }
893 Val.ChangeToImmediate(0);
894 } else {
895 assert(Val.isImm() && "Unexpected operand for G_CONSTANT");
896 if (Val.getImm() != 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000897 LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
Diana Picus37ae9f62018-01-04 10:54:57 +0000898 return false;
899 }
900 }
901
902 I.setDesc(TII.get(ARM::MOVi));
903 MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
904 break;
905 }
Diana Picus28a6d0e2017-12-22 13:05:51 +0000906 case G_INTTOPTR:
907 case G_PTRTOINT: {
908 auto SrcReg = I.getOperand(1).getReg();
909 auto DstReg = I.getOperand(0).getReg();
910
911 const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
912 const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
913
914 if (SrcRegBank.getID() != DstRegBank.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000915 LLVM_DEBUG(
916 dbgs()
917 << "G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
Diana Picus28a6d0e2017-12-22 13:05:51 +0000918 return false;
919 }
920
921 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000922 LLVM_DEBUG(
923 dbgs() << "G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
Diana Picus28a6d0e2017-12-22 13:05:51 +0000924 return false;
925 }
926
927 I.setDesc(TII.get(COPY));
928 return selectCopy(I, TII, MRI, TRI, RBI);
929 }
Diana Picus7145d222017-06-27 09:19:51 +0000930 case G_SELECT:
Diana Picus995746d2017-07-12 10:31:16 +0000931 return selectSelect(MIB, MRI);
932 case G_ICMP: {
Diana Picus75a04e22019-02-07 11:05:33 +0000933 CmpConstants Helper(Opcodes.CMPrr, ARM::INSTRUCTION_LIST_END,
934 Opcodes.MOVCCi, ARM::GPRRegBankID, 32);
Diana Picus995746d2017-07-12 10:31:16 +0000935 return selectCmp(Helper, MIB, MRI);
936 }
Diana Picus21014df2017-07-12 09:01:54 +0000937 case G_FCMP: {
Diana Picusac154732017-09-05 08:22:47 +0000938 assert(STI.hasVFP2() && "Can't select fcmp without VFP");
Diana Picus21014df2017-07-12 09:01:54 +0000939
940 unsigned OpReg = I.getOperand(2).getReg();
941 unsigned Size = MRI.getType(OpReg).getSizeInBits();
Diana Picus995746d2017-07-12 10:31:16 +0000942
Diana Picusac154732017-09-05 08:22:47 +0000943 if (Size == 64 && STI.isFPOnlySP()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000944 LLVM_DEBUG(dbgs() << "Subtarget only supports single precision");
Diana Picus995746d2017-07-12 10:31:16 +0000945 return false;
946 }
947 if (Size != 32 && Size != 64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000948 LLVM_DEBUG(dbgs() << "Unsupported size for G_FCMP operand");
Diana Picus995746d2017-07-12 10:31:16 +0000949 return false;
Diana Picus21014df2017-07-12 09:01:54 +0000950 }
951
Diana Picus995746d2017-07-12 10:31:16 +0000952 CmpConstants Helper(Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
Diana Picus75a04e22019-02-07 11:05:33 +0000953 Opcodes.MOVCCi, ARM::FPRRegBankID, Size);
Diana Picus995746d2017-07-12 10:31:16 +0000954 return selectCmp(Helper, MIB, MRI);
Diana Picus21014df2017-07-12 09:01:54 +0000955 }
Diana Picuse393bc72017-10-06 15:39:16 +0000956 case G_LSHR:
957 return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
958 case G_ASHR:
959 return selectShift(ARM_AM::ShiftOpc::asr, MIB);
960 case G_SHL: {
961 return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
962 }
Diana Picus9d070942017-02-28 10:14:38 +0000963 case G_GEP:
Diana Picusc0f964eb2019-02-15 10:50:02 +0000964 I.setDesc(TII.get(Opcodes.ADDrr));
Diana Picus8a73f552017-01-13 10:18:01 +0000965 MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus519807f2016-12-19 11:26:31 +0000966 break;
967 case G_FRAME_INDEX:
968 // Add 0 to the given frame index and hope it will eventually be folded into
969 // the user(s).
970 I.setDesc(TII.get(ARM::ADDri));
Diana Picus8a73f552017-01-13 10:18:01 +0000971 MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
Diana Picus519807f2016-12-19 11:26:31 +0000972 break;
Diana Picus930e6ec2017-08-03 09:14:59 +0000973 case G_GLOBAL_VALUE:
974 return selectGlobal(MIB, MRI);
Diana Picus3b99c642017-02-24 14:01:27 +0000975 case G_STORE:
Diana Picus278c7222017-01-26 09:20:47 +0000976 case G_LOAD: {
Daniel Sanders3c1c4c02017-12-05 05:52:07 +0000977 const auto &MemOp = **I.memoperands_begin();
978 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000979 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +0000980 return false;
981 }
982
Diana Picus1540b062017-02-16 14:10:50 +0000983 unsigned Reg = I.getOperand(0).getReg();
984 unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
985
986 LLT ValTy = MRI.getType(Reg);
Diana Picus278c7222017-01-26 09:20:47 +0000987 const auto ValSize = ValTy.getSizeInBits();
988
Diana Picusac154732017-09-05 08:22:47 +0000989 assert((ValSize != 64 || STI.hasVFP2()) &&
Diana Picus3b99c642017-02-24 14:01:27 +0000990 "Don't know how to load/store 64-bit value without VFP");
Diana Picus1540b062017-02-16 14:10:50 +0000991
Diana Picus813af0d2018-12-14 12:37:24 +0000992 const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
Diana Picus3b99c642017-02-24 14:01:27 +0000993 if (NewOpc == G_LOAD || NewOpc == G_STORE)
Diana Picuse8368782017-02-17 13:44:19 +0000994 return false;
995
Diana Picus278c7222017-01-26 09:20:47 +0000996 I.setDesc(TII.get(NewOpc));
997
Diana Picus3b99c642017-02-24 14:01:27 +0000998 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
Diana Picus278c7222017-01-26 09:20:47 +0000999 // LDRH has a funny addressing mode (there's already a FIXME for it).
1000 MIB.addReg(0);
Diana Picus4f8c3e12017-01-13 09:37:56 +00001001 MIB.addImm(0).add(predOps(ARMCC::AL));
Diana Picus519807f2016-12-19 11:26:31 +00001002 break;
Diana Picus278c7222017-01-26 09:20:47 +00001003 }
Diana Picus0b4190a2017-06-07 12:35:05 +00001004 case G_MERGE_VALUES: {
1005 if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
Diana Picusb1701e02017-02-16 12:19:57 +00001006 return false;
1007 break;
1008 }
Diana Picus0b4190a2017-06-07 12:35:05 +00001009 case G_UNMERGE_VALUES: {
1010 if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
Diana Picusb1701e02017-02-16 12:19:57 +00001011 return false;
1012 break;
1013 }
Diana Picus87a70672017-07-14 09:46:06 +00001014 case G_BRCOND: {
1015 if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001016 LLVM_DEBUG(dbgs() << "Unsupported condition register for G_BRCOND");
Diana Picus87a70672017-07-14 09:46:06 +00001017 return false;
1018 }
1019
1020 // Set the flags.
Diana Picusa00425f2019-02-15 10:24:03 +00001021 auto Test =
1022 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcodes.TSTri))
1023 .addReg(I.getOperand(0).getReg())
1024 .addImm(1)
1025 .add(predOps(ARMCC::AL));
Diana Picus87a70672017-07-14 09:46:06 +00001026 if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI))
1027 return false;
1028
1029 // Branch conditionally.
Diana Picusa00425f2019-02-15 10:24:03 +00001030 auto Branch =
1031 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcodes.Bcc))
1032 .add(I.getOperand(1))
1033 .add(predOps(ARMCC::NE, ARM::CPSR));
Diana Picus87a70672017-07-14 09:46:06 +00001034 if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
1035 return false;
1036 I.eraseFromParent();
1037 return true;
1038 }
Diana Picus865f7fe2018-01-04 13:09:25 +00001039 case G_PHI: {
1040 I.setDesc(TII.get(PHI));
1041
1042 unsigned DstReg = I.getOperand(0).getReg();
1043 const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
1044 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1045 break;
1046 }
1047
1048 return true;
1049 }
Diana Picus519807f2016-12-19 11:26:31 +00001050 default:
1051 return false;
Diana Picus812caee2016-12-16 12:54:46 +00001052 }
1053
Diana Picus519807f2016-12-19 11:26:31 +00001054 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Diana Picus22274932016-11-11 08:27:37 +00001055}