blob: 0a98e7d13e3491a188cb27a9d82093925ad56c5e [file] [log] [blame]
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001//===- AArch64InstructionSelector.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
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for
10/// AArch64.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000014#include "AArch64InstrInfo.h"
Tim Northovere9600d82017-02-08 17:57:27 +000015#include "AArch64MachineFunctionInfo.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000016#include "AArch64RegisterBankInfo.h"
17#include "AArch64RegisterInfo.h"
18#include "AArch64Subtarget.h"
Tim Northoverbdf16242016-10-10 21:50:00 +000019#include "AArch64TargetMachine.h"
Tim Northover9ac0eba2016-11-08 00:45:29 +000020#include "MCTargetDesc/AArch64AddressingModes.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000021#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
David Blaikie62651302017-10-26 23:39:54 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Amara Emerson1e8c1642018-07-31 00:09:02 +000023#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Aditya Nandakumar75ad9cc2017-04-19 20:48:50 +000024#include "llvm/CodeGen/GlobalISel/Utils.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000025#include "llvm/CodeGen/MachineBasicBlock.h"
26#include "llvm/CodeGen/MachineFunction.h"
27#include "llvm/CodeGen/MachineInstr.h"
28#include "llvm/CodeGen/MachineInstrBuilder.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000029#include "llvm/CodeGen/MachineOperand.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000030#include "llvm/CodeGen/MachineRegisterInfo.h"
31#include "llvm/IR/Type.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/Support/raw_ostream.h"
34
35#define DEBUG_TYPE "aarch64-isel"
36
37using namespace llvm;
38
Daniel Sanders0b5293f2017-04-06 09:49:34 +000039namespace {
40
Daniel Sanderse7b0d662017-04-21 15:59:56 +000041#define GET_GLOBALISEL_PREDICATE_BITSET
42#include "AArch64GenGlobalISel.inc"
43#undef GET_GLOBALISEL_PREDICATE_BITSET
44
Daniel Sanders0b5293f2017-04-06 09:49:34 +000045class AArch64InstructionSelector : public InstructionSelector {
46public:
47 AArch64InstructionSelector(const AArch64TargetMachine &TM,
48 const AArch64Subtarget &STI,
49 const AArch64RegisterBankInfo &RBI);
50
Daniel Sandersf76f3152017-11-16 00:46:35 +000051 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000052 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000053
54private:
55 /// tblgen-erated 'select' implementation, used as the initial selector for
56 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000057 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000058
59 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF,
60 MachineRegisterInfo &MRI) const;
61 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
62 MachineRegisterInfo &MRI) const;
63
64 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
65 MachineRegisterInfo &MRI) const;
66
Amara Emerson5ec14602018-12-10 18:44:58 +000067 // Helper to generate an equivalent of scalar_to_vector into a new register,
68 // returned via 'Dst'.
69 bool emitScalarToVector(unsigned &Dst, const LLT DstTy,
70 const TargetRegisterClass *DstRC, unsigned Scalar,
71 MachineBasicBlock &MBB,
72 MachineBasicBlock::iterator MBBI,
73 MachineRegisterInfo &MRI) const;
74 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson8cb186c2018-12-20 01:11:04 +000075 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette245047d2019-01-24 22:00:41 +000076 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000077
Daniel Sanders1e4569f2017-10-20 20:55:29 +000078 ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000079
Daniel Sanders1e4569f2017-10-20 20:55:29 +000080 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root,
81 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +000082
Daniel Sanders1e4569f2017-10-20 20:55:29 +000083 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000084 return selectAddrModeUnscaled(Root, 1);
85 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000086 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000087 return selectAddrModeUnscaled(Root, 2);
88 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000089 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000090 return selectAddrModeUnscaled(Root, 4);
91 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000092 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000093 return selectAddrModeUnscaled(Root, 8);
94 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000095 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000096 return selectAddrModeUnscaled(Root, 16);
97 }
98
Daniel Sanders1e4569f2017-10-20 20:55:29 +000099 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root,
100 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000101 template <int Width>
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000102 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000103 return selectAddrModeIndexed(Root, Width / 8);
104 }
105
Volkan Kelesf7f25682018-01-16 18:44:05 +0000106 void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const;
107
Amara Emerson1e8c1642018-07-31 00:09:02 +0000108 // Materialize a GlobalValue or BlockAddress using a movz+movk sequence.
109 void materializeLargeCMVal(MachineInstr &I, const Value *V,
110 unsigned char OpFlags) const;
111
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000112 const AArch64TargetMachine &TM;
113 const AArch64Subtarget &STI;
114 const AArch64InstrInfo &TII;
115 const AArch64RegisterInfo &TRI;
116 const AArch64RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000117
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000118#define GET_GLOBALISEL_PREDICATES_DECL
119#include "AArch64GenGlobalISel.inc"
120#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000121
122// We declare the temporaries used by selectImpl() in the class to minimize the
123// cost of constructing placeholder values.
124#define GET_GLOBALISEL_TEMPORARIES_DECL
125#include "AArch64GenGlobalISel.inc"
126#undef GET_GLOBALISEL_TEMPORARIES_DECL
127};
128
129} // end anonymous namespace
130
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000131#define GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000132#include "AArch64GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000133#undef GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000134
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000135AArch64InstructionSelector::AArch64InstructionSelector(
Tim Northoverbdf16242016-10-10 21:50:00 +0000136 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
137 const AArch64RegisterBankInfo &RBI)
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000138 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000139 TRI(*STI.getRegisterInfo()), RBI(RBI),
140#define GET_GLOBALISEL_PREDICATES_INIT
141#include "AArch64GenGlobalISel.inc"
142#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000143#define GET_GLOBALISEL_TEMPORARIES_INIT
144#include "AArch64GenGlobalISel.inc"
145#undef GET_GLOBALISEL_TEMPORARIES_INIT
146{
147}
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000148
Tim Northoverfb8d9892016-10-12 22:49:15 +0000149// FIXME: This should be target-independent, inferred from the types declared
150// for each class in the bank.
151static const TargetRegisterClass *
152getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
Amara Emerson3838ed02018-02-02 18:03:30 +0000153 const RegisterBankInfo &RBI,
154 bool GetAllRegSet = false) {
Tim Northoverfb8d9892016-10-12 22:49:15 +0000155 if (RB.getID() == AArch64::GPRRegBankID) {
156 if (Ty.getSizeInBits() <= 32)
Amara Emerson3838ed02018-02-02 18:03:30 +0000157 return GetAllRegSet ? &AArch64::GPR32allRegClass
158 : &AArch64::GPR32RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000159 if (Ty.getSizeInBits() == 64)
Amara Emerson3838ed02018-02-02 18:03:30 +0000160 return GetAllRegSet ? &AArch64::GPR64allRegClass
161 : &AArch64::GPR64RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000162 return nullptr;
163 }
164
165 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson3838ed02018-02-02 18:03:30 +0000166 if (Ty.getSizeInBits() <= 16)
167 return &AArch64::FPR16RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000168 if (Ty.getSizeInBits() == 32)
169 return &AArch64::FPR32RegClass;
170 if (Ty.getSizeInBits() == 64)
171 return &AArch64::FPR64RegClass;
172 if (Ty.getSizeInBits() == 128)
173 return &AArch64::FPR128RegClass;
174 return nullptr;
175 }
176
177 return nullptr;
178}
179
Jessica Paquette245047d2019-01-24 22:00:41 +0000180/// Given a register bank, and size in bits, return the smallest register class
181/// that can represent that combination.
182const TargetRegisterClass *getMinClassForRegBank(const RegisterBank &RB,
183 unsigned SizeInBits,
184 bool GetAllRegSet = false) {
185 unsigned RegBankID = RB.getID();
186
187 if (RegBankID == AArch64::GPRRegBankID) {
188 if (SizeInBits <= 32)
189 return GetAllRegSet ? &AArch64::GPR32allRegClass
190 : &AArch64::GPR32RegClass;
191 if (SizeInBits == 64)
192 return GetAllRegSet ? &AArch64::GPR64allRegClass
193 : &AArch64::GPR64RegClass;
194 }
195
196 if (RegBankID == AArch64::FPRRegBankID) {
197 switch (SizeInBits) {
198 default:
199 return nullptr;
200 case 8:
201 return &AArch64::FPR8RegClass;
202 case 16:
203 return &AArch64::FPR16RegClass;
204 case 32:
205 return &AArch64::FPR32RegClass;
206 case 64:
207 return &AArch64::FPR64RegClass;
208 case 128:
209 return &AArch64::FPR128RegClass;
210 }
211 }
212
213 return nullptr;
214}
215
216/// Returns the correct subregister to use for a given register class.
217static bool getSubRegForClass(const TargetRegisterClass *RC,
218 const TargetRegisterInfo &TRI, unsigned &SubReg) {
219 switch (TRI.getRegSizeInBits(*RC)) {
220 case 8:
221 SubReg = AArch64::bsub;
222 break;
223 case 16:
224 SubReg = AArch64::hsub;
225 break;
226 case 32:
227 if (RC == &AArch64::GPR32RegClass)
228 SubReg = AArch64::sub_32;
229 else
230 SubReg = AArch64::ssub;
231 break;
232 case 64:
233 SubReg = AArch64::dsub;
234 break;
235 default:
236 LLVM_DEBUG(
237 dbgs() << "Couldn't find appropriate subregister for register class.");
238 return false;
239 }
240
241 return true;
242}
243
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000244/// Check whether \p I is a currently unsupported binary operation:
245/// - it has an unsized type
246/// - an operand is not a vreg
247/// - all operands are not in the same bank
248/// These are checks that should someday live in the verifier, but right now,
249/// these are mostly limitations of the aarch64 selector.
250static bool unsupportedBinOp(const MachineInstr &I,
251 const AArch64RegisterBankInfo &RBI,
252 const MachineRegisterInfo &MRI,
253 const AArch64RegisterInfo &TRI) {
Tim Northover0f140c72016-09-09 11:46:34 +0000254 LLT Ty = MRI.getType(I.getOperand(0).getReg());
Tim Northover32a078a2016-09-15 10:09:59 +0000255 if (!Ty.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000256 LLVM_DEBUG(dbgs() << "Generic binop register should be typed\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000257 return true;
258 }
259
260 const RegisterBank *PrevOpBank = nullptr;
261 for (auto &MO : I.operands()) {
262 // FIXME: Support non-register operands.
263 if (!MO.isReg()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000264 LLVM_DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000265 return true;
266 }
267
268 // FIXME: Can generic operations have physical registers operands? If
269 // so, this will need to be taught about that, and we'll need to get the
270 // bank out of the minimal class for the register.
271 // Either way, this needs to be documented (and possibly verified).
272 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000273 LLVM_DEBUG(dbgs() << "Generic inst has physical register operand\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000274 return true;
275 }
276
277 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI);
278 if (!OpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000279 LLVM_DEBUG(dbgs() << "Generic register has no bank or class\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000280 return true;
281 }
282
283 if (PrevOpBank && OpBank != PrevOpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000284 LLVM_DEBUG(dbgs() << "Generic inst operands have different banks\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000285 return true;
286 }
287 PrevOpBank = OpBank;
288 }
289 return false;
290}
291
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000292/// Select the AArch64 opcode for the basic binary operation \p GenericOpc
Ahmed Bougachacfb384d2017-01-23 21:10:05 +0000293/// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000294/// and of size \p OpSize.
295/// \returns \p GenericOpc if the combination is unsupported.
296static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
297 unsigned OpSize) {
298 switch (RegBankID) {
299 case AArch64::GPRRegBankID:
Ahmed Bougacha05a5f7d2017-01-25 02:41:38 +0000300 if (OpSize == 32) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000301 switch (GenericOpc) {
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000302 case TargetOpcode::G_SHL:
303 return AArch64::LSLVWr;
304 case TargetOpcode::G_LSHR:
305 return AArch64::LSRVWr;
306 case TargetOpcode::G_ASHR:
307 return AArch64::ASRVWr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000308 default:
309 return GenericOpc;
310 }
Tim Northover55782222016-10-18 20:03:48 +0000311 } else if (OpSize == 64) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000312 switch (GenericOpc) {
Tim Northover2fda4b02016-10-10 21:49:49 +0000313 case TargetOpcode::G_GEP:
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000314 return AArch64::ADDXrr;
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000315 case TargetOpcode::G_SHL:
316 return AArch64::LSLVXr;
317 case TargetOpcode::G_LSHR:
318 return AArch64::LSRVXr;
319 case TargetOpcode::G_ASHR:
320 return AArch64::ASRVXr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000321 default:
322 return GenericOpc;
323 }
324 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000325 break;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000326 case AArch64::FPRRegBankID:
327 switch (OpSize) {
328 case 32:
329 switch (GenericOpc) {
330 case TargetOpcode::G_FADD:
331 return AArch64::FADDSrr;
332 case TargetOpcode::G_FSUB:
333 return AArch64::FSUBSrr;
334 case TargetOpcode::G_FMUL:
335 return AArch64::FMULSrr;
336 case TargetOpcode::G_FDIV:
337 return AArch64::FDIVSrr;
338 default:
339 return GenericOpc;
340 }
341 case 64:
342 switch (GenericOpc) {
343 case TargetOpcode::G_FADD:
344 return AArch64::FADDDrr;
345 case TargetOpcode::G_FSUB:
346 return AArch64::FSUBDrr;
347 case TargetOpcode::G_FMUL:
348 return AArch64::FMULDrr;
349 case TargetOpcode::G_FDIV:
350 return AArch64::FDIVDrr;
Quentin Colombet0e531272016-10-11 00:21:11 +0000351 case TargetOpcode::G_OR:
352 return AArch64::ORRv8i8;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000353 default:
354 return GenericOpc;
355 }
356 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000357 break;
358 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000359 return GenericOpc;
360}
361
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000362/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
363/// appropriate for the (value) register bank \p RegBankID and of memory access
364/// size \p OpSize. This returns the variant with the base+unsigned-immediate
365/// addressing mode (e.g., LDRXui).
366/// \returns \p GenericOpc if the combination is unsupported.
367static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
368 unsigned OpSize) {
369 const bool isStore = GenericOpc == TargetOpcode::G_STORE;
370 switch (RegBankID) {
371 case AArch64::GPRRegBankID:
372 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000373 case 8:
374 return isStore ? AArch64::STRBBui : AArch64::LDRBBui;
375 case 16:
376 return isStore ? AArch64::STRHHui : AArch64::LDRHHui;
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000377 case 32:
378 return isStore ? AArch64::STRWui : AArch64::LDRWui;
379 case 64:
380 return isStore ? AArch64::STRXui : AArch64::LDRXui;
381 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000382 break;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000383 case AArch64::FPRRegBankID:
384 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000385 case 8:
386 return isStore ? AArch64::STRBui : AArch64::LDRBui;
387 case 16:
388 return isStore ? AArch64::STRHui : AArch64::LDRHui;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000389 case 32:
390 return isStore ? AArch64::STRSui : AArch64::LDRSui;
391 case 64:
392 return isStore ? AArch64::STRDui : AArch64::LDRDui;
393 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000394 break;
395 }
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000396 return GenericOpc;
397}
398
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000399#ifndef NDEBUG
Jessica Paquette245047d2019-01-24 22:00:41 +0000400/// Helper function that verifies that we have a valid copy at the end of
401/// selectCopy. Verifies that the source and dest have the expected sizes and
402/// then returns true.
403static bool isValidCopy(const MachineInstr &I, const RegisterBank &DstBank,
404 const MachineRegisterInfo &MRI,
405 const TargetRegisterInfo &TRI,
406 const RegisterBankInfo &RBI) {
407 const unsigned DstReg = I.getOperand(0).getReg();
408 const unsigned SrcReg = I.getOperand(1).getReg();
409 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
410 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Amara Emersondb211892018-02-20 05:11:57 +0000411
Jessica Paquette245047d2019-01-24 22:00:41 +0000412 // Make sure the size of the source and dest line up.
413 assert(
414 (DstSize == SrcSize ||
415 // Copies are a mean to setup initial types, the number of
416 // bits may not exactly match.
417 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && DstSize <= SrcSize) ||
418 // Copies are a mean to copy bits around, as long as we are
419 // on the same register class, that's fine. Otherwise, that
420 // means we need some SUBREG_TO_REG or AND & co.
421 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) &&
422 "Copy with different width?!");
423
424 // Check the size of the destination.
425 assert((DstSize <= 64 || DstBank.getID() == AArch64::FPRRegBankID) &&
426 "GPRs cannot get more than 64-bit width values");
427
428 return true;
429}
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000430#endif
Jessica Paquette245047d2019-01-24 22:00:41 +0000431
432/// Helper function for selectCopy. Inserts a subregister copy from
433/// \p *From to \p *To, linking it up to \p I.
434///
435/// e.g, given I = "Dst = COPY SrcReg", we'll transform that into
436///
437/// CopyReg (From class) = COPY SrcReg
438/// SubRegCopy (To class) = COPY CopyReg:SubReg
439/// Dst = COPY SubRegCopy
440static bool selectSubregisterCopy(MachineInstr &I, const TargetInstrInfo &TII,
441 MachineRegisterInfo &MRI,
442 const RegisterBankInfo &RBI, unsigned SrcReg,
443 const TargetRegisterClass *From,
444 const TargetRegisterClass *To,
445 unsigned SubReg) {
446 unsigned CopyReg = MRI.createVirtualRegister(From);
447 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::COPY), CopyReg)
448 .addUse(SrcReg);
449 unsigned SubRegCopy = MRI.createVirtualRegister(To);
450 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
451 SubRegCopy)
452 .addUse(CopyReg, 0, SubReg);
Amara Emersondb211892018-02-20 05:11:57 +0000453 MachineOperand &RegOp = I.getOperand(1);
454 RegOp.setReg(SubRegCopy);
Jessica Paquette245047d2019-01-24 22:00:41 +0000455
456 // It's possible that the destination register won't be constrained. Make
457 // sure that happens.
458 if (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()))
459 RBI.constrainGenericRegister(I.getOperand(0).getReg(), *To, MRI);
460
Amara Emersondb211892018-02-20 05:11:57 +0000461 return true;
462}
463
Quentin Colombetcb629a82016-10-12 03:57:49 +0000464static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
465 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
466 const RegisterBankInfo &RBI) {
467
468 unsigned DstReg = I.getOperand(0).getReg();
Amara Emersondb211892018-02-20 05:11:57 +0000469 unsigned SrcReg = I.getOperand(1).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +0000470 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
471 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
472 const TargetRegisterClass *DstRC = getMinClassForRegBank(
473 DstRegBank, RBI.getSizeInBits(DstReg, MRI, TRI), true);
474 if (!DstRC) {
475 LLVM_DEBUG(dbgs() << "Unexpected dest size "
476 << RBI.getSizeInBits(DstReg, MRI, TRI) << '\n');
Amara Emerson3838ed02018-02-02 18:03:30 +0000477 return false;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000478 }
479
Jessica Paquette245047d2019-01-24 22:00:41 +0000480 // A couple helpers below, for making sure that the copy we produce is valid.
481
482 // Set to true if we insert a SUBREG_TO_REG. If we do this, then we don't want
483 // to verify that the src and dst are the same size, since that's handled by
484 // the SUBREG_TO_REG.
485 bool KnownValid = false;
486
487 // Returns true, or asserts if something we don't expect happens. Instead of
488 // returning true, we return isValidCopy() to ensure that we verify the
489 // result.
Jessica Paquette76c40f82019-01-24 22:51:31 +0000490 auto CheckCopy = [&]() {
Jessica Paquette245047d2019-01-24 22:00:41 +0000491 // If we have a bitcast or something, we can't have physical registers.
492 assert(
493 I.isCopy() ||
494 (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()) &&
495 !TargetRegisterInfo::isPhysicalRegister(I.getOperand(1).getReg())) &&
496 "No phys reg on generic operator!");
497 assert(KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI));
498 return true;
499 };
500
501 // Is this a copy? If so, then we may need to insert a subregister copy, or
502 // a SUBREG_TO_REG.
503 if (I.isCopy()) {
504 // Yes. Check if there's anything to fix up.
505 const TargetRegisterClass *SrcRC = getMinClassForRegBank(
506 SrcRegBank, RBI.getSizeInBits(SrcReg, MRI, TRI), true);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000507 if (!SrcRC) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000508 LLVM_DEBUG(dbgs() << "Couldn't determine source register class\n");
509 return false;
Amara Emerson7e9f3482018-02-18 17:10:49 +0000510 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000511
512 // Is this a cross-bank copy?
513 if (DstRegBank.getID() != SrcRegBank.getID()) {
514 // If we're doing a cross-bank copy on different-sized registers, we need
515 // to do a bit more work.
516 unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
517 unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
518
519 if (SrcSize > DstSize) {
520 // We're doing a cross-bank copy into a smaller register. We need a
521 // subregister copy. First, get a register class that's on the same bank
522 // as the destination, but the same size as the source.
523 const TargetRegisterClass *SubregRC =
524 getMinClassForRegBank(DstRegBank, SrcSize, true);
525 assert(SubregRC && "Didn't get a register class for subreg?");
526
527 // Get the appropriate subregister for the destination.
528 unsigned SubReg = 0;
529 if (!getSubRegForClass(DstRC, TRI, SubReg)) {
530 LLVM_DEBUG(dbgs() << "Couldn't determine subregister for copy.\n");
531 return false;
532 }
533
534 // Now, insert a subregister copy using the new register class.
535 selectSubregisterCopy(I, TII, MRI, RBI, SrcReg, SubregRC, DstRC,
536 SubReg);
537 return CheckCopy();
538 }
539
540 else if (DstRegBank.getID() == AArch64::GPRRegBankID && DstSize == 32 &&
541 SrcSize == 16) {
542 // Special case for FPR16 to GPR32.
543 // FIXME: This can probably be generalized like the above case.
544 unsigned PromoteReg =
545 MRI.createVirtualRegister(&AArch64::FPR32RegClass);
546 BuildMI(*I.getParent(), I, I.getDebugLoc(),
547 TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
548 .addImm(0)
549 .addUse(SrcReg)
550 .addImm(AArch64::hsub);
551 MachineOperand &RegOp = I.getOperand(1);
552 RegOp.setReg(PromoteReg);
553
554 // Promise that the copy is implicitly validated by the SUBREG_TO_REG.
555 KnownValid = true;
556 }
Amara Emerson7e9f3482018-02-18 17:10:49 +0000557 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000558
559 // If the destination is a physical register, then there's nothing to
560 // change, so we're done.
561 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
562 return CheckCopy();
Amara Emerson7e9f3482018-02-18 17:10:49 +0000563 }
564
Jessica Paquette245047d2019-01-24 22:00:41 +0000565 // No need to constrain SrcReg. It will get constrained when we hit another
566 // of its use or its defs. Copies do not have constraints.
567 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000568 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
569 << " operand\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000570 return false;
571 }
572 I.setDesc(TII.get(AArch64::COPY));
Jessica Paquette245047d2019-01-24 22:00:41 +0000573 return CheckCopy();
Quentin Colombetcb629a82016-10-12 03:57:49 +0000574}
575
Tim Northover69271c62016-10-12 22:49:11 +0000576static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
577 if (!DstTy.isScalar() || !SrcTy.isScalar())
578 return GenericOpc;
579
580 const unsigned DstSize = DstTy.getSizeInBits();
581 const unsigned SrcSize = SrcTy.getSizeInBits();
582
583 switch (DstSize) {
584 case 32:
585 switch (SrcSize) {
586 case 32:
587 switch (GenericOpc) {
588 case TargetOpcode::G_SITOFP:
589 return AArch64::SCVTFUWSri;
590 case TargetOpcode::G_UITOFP:
591 return AArch64::UCVTFUWSri;
592 case TargetOpcode::G_FPTOSI:
593 return AArch64::FCVTZSUWSr;
594 case TargetOpcode::G_FPTOUI:
595 return AArch64::FCVTZUUWSr;
596 default:
597 return GenericOpc;
598 }
599 case 64:
600 switch (GenericOpc) {
601 case TargetOpcode::G_SITOFP:
602 return AArch64::SCVTFUXSri;
603 case TargetOpcode::G_UITOFP:
604 return AArch64::UCVTFUXSri;
605 case TargetOpcode::G_FPTOSI:
606 return AArch64::FCVTZSUWDr;
607 case TargetOpcode::G_FPTOUI:
608 return AArch64::FCVTZUUWDr;
609 default:
610 return GenericOpc;
611 }
612 default:
613 return GenericOpc;
614 }
615 case 64:
616 switch (SrcSize) {
617 case 32:
618 switch (GenericOpc) {
619 case TargetOpcode::G_SITOFP:
620 return AArch64::SCVTFUWDri;
621 case TargetOpcode::G_UITOFP:
622 return AArch64::UCVTFUWDri;
623 case TargetOpcode::G_FPTOSI:
624 return AArch64::FCVTZSUXSr;
625 case TargetOpcode::G_FPTOUI:
626 return AArch64::FCVTZUUXSr;
627 default:
628 return GenericOpc;
629 }
630 case 64:
631 switch (GenericOpc) {
632 case TargetOpcode::G_SITOFP:
633 return AArch64::SCVTFUXDri;
634 case TargetOpcode::G_UITOFP:
635 return AArch64::UCVTFUXDri;
636 case TargetOpcode::G_FPTOSI:
637 return AArch64::FCVTZSUXDr;
638 case TargetOpcode::G_FPTOUI:
639 return AArch64::FCVTZUUXDr;
640 default:
641 return GenericOpc;
642 }
643 default:
644 return GenericOpc;
645 }
646 default:
647 return GenericOpc;
648 };
649 return GenericOpc;
650}
651
Tim Northover6c02ad52016-10-12 22:49:04 +0000652static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
653 switch (P) {
654 default:
655 llvm_unreachable("Unknown condition code!");
656 case CmpInst::ICMP_NE:
657 return AArch64CC::NE;
658 case CmpInst::ICMP_EQ:
659 return AArch64CC::EQ;
660 case CmpInst::ICMP_SGT:
661 return AArch64CC::GT;
662 case CmpInst::ICMP_SGE:
663 return AArch64CC::GE;
664 case CmpInst::ICMP_SLT:
665 return AArch64CC::LT;
666 case CmpInst::ICMP_SLE:
667 return AArch64CC::LE;
668 case CmpInst::ICMP_UGT:
669 return AArch64CC::HI;
670 case CmpInst::ICMP_UGE:
671 return AArch64CC::HS;
672 case CmpInst::ICMP_ULT:
673 return AArch64CC::LO;
674 case CmpInst::ICMP_ULE:
675 return AArch64CC::LS;
676 }
677}
678
Tim Northover7dd378d2016-10-12 22:49:07 +0000679static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
680 AArch64CC::CondCode &CondCode,
681 AArch64CC::CondCode &CondCode2) {
682 CondCode2 = AArch64CC::AL;
683 switch (P) {
684 default:
685 llvm_unreachable("Unknown FP condition!");
686 case CmpInst::FCMP_OEQ:
687 CondCode = AArch64CC::EQ;
688 break;
689 case CmpInst::FCMP_OGT:
690 CondCode = AArch64CC::GT;
691 break;
692 case CmpInst::FCMP_OGE:
693 CondCode = AArch64CC::GE;
694 break;
695 case CmpInst::FCMP_OLT:
696 CondCode = AArch64CC::MI;
697 break;
698 case CmpInst::FCMP_OLE:
699 CondCode = AArch64CC::LS;
700 break;
701 case CmpInst::FCMP_ONE:
702 CondCode = AArch64CC::MI;
703 CondCode2 = AArch64CC::GT;
704 break;
705 case CmpInst::FCMP_ORD:
706 CondCode = AArch64CC::VC;
707 break;
708 case CmpInst::FCMP_UNO:
709 CondCode = AArch64CC::VS;
710 break;
711 case CmpInst::FCMP_UEQ:
712 CondCode = AArch64CC::EQ;
713 CondCode2 = AArch64CC::VS;
714 break;
715 case CmpInst::FCMP_UGT:
716 CondCode = AArch64CC::HI;
717 break;
718 case CmpInst::FCMP_UGE:
719 CondCode = AArch64CC::PL;
720 break;
721 case CmpInst::FCMP_ULT:
722 CondCode = AArch64CC::LT;
723 break;
724 case CmpInst::FCMP_ULE:
725 CondCode = AArch64CC::LE;
726 break;
727 case CmpInst::FCMP_UNE:
728 CondCode = AArch64CC::NE;
729 break;
730 }
731}
732
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000733bool AArch64InstructionSelector::selectCompareBranch(
734 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
735
736 const unsigned CondReg = I.getOperand(0).getReg();
737 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
738 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
Aditya Nandakumar02c602e2017-07-31 17:00:16 +0000739 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC)
740 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg());
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000741 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
742 return false;
743
744 unsigned LHS = CCMI->getOperand(2).getReg();
745 unsigned RHS = CCMI->getOperand(3).getReg();
746 if (!getConstantVRegVal(RHS, MRI))
747 std::swap(RHS, LHS);
748
749 const auto RHSImm = getConstantVRegVal(RHS, MRI);
750 if (!RHSImm || *RHSImm != 0)
751 return false;
752
753 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
754 if (RB.getID() != AArch64::GPRRegBankID)
755 return false;
756
757 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
758 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
759 return false;
760
761 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
762 unsigned CBOpc = 0;
763 if (CmpWidth <= 32)
764 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
765 else if (CmpWidth == 64)
766 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
767 else
768 return false;
769
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +0000770 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
771 .addUse(LHS)
772 .addMBB(DestMBB)
773 .constrainAllUses(TII, TRI, RBI);
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000774
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000775 I.eraseFromParent();
776 return true;
777}
778
Tim Northovere9600d82017-02-08 17:57:27 +0000779bool AArch64InstructionSelector::selectVaStartAAPCS(
780 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
781 return false;
782}
783
784bool AArch64InstructionSelector::selectVaStartDarwin(
785 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
786 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
787 unsigned ListReg = I.getOperand(0).getReg();
788
789 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
790
791 auto MIB =
792 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri))
793 .addDef(ArgsAddrReg)
794 .addFrameIndex(FuncInfo->getVarArgsStackIndex())
795 .addImm(0)
796 .addImm(0);
797
798 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
799
800 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui))
801 .addUse(ArgsAddrReg)
802 .addUse(ListReg)
803 .addImm(0)
804 .addMemOperand(*I.memoperands_begin());
805
806 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
807 I.eraseFromParent();
808 return true;
809}
810
Amara Emerson1e8c1642018-07-31 00:09:02 +0000811void AArch64InstructionSelector::materializeLargeCMVal(
812 MachineInstr &I, const Value *V, unsigned char OpFlags) const {
813 MachineBasicBlock &MBB = *I.getParent();
814 MachineFunction &MF = *MBB.getParent();
815 MachineRegisterInfo &MRI = MF.getRegInfo();
816 MachineIRBuilder MIB(I);
817
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000818 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, {&AArch64::GPR64RegClass}, {});
Amara Emerson1e8c1642018-07-31 00:09:02 +0000819 MovZ->addOperand(MF, I.getOperand(1));
820 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 |
821 AArch64II::MO_NC);
822 MovZ->addOperand(MF, MachineOperand::CreateImm(0));
823 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI);
824
825 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, unsigned Offset,
826 unsigned ForceDstReg) {
827 unsigned DstReg = ForceDstReg
828 ? ForceDstReg
829 : MRI.createVirtualRegister(&AArch64::GPR64RegClass);
830 auto MovI = MIB.buildInstr(AArch64::MOVKXi).addDef(DstReg).addUse(SrcReg);
831 if (auto *GV = dyn_cast<GlobalValue>(V)) {
832 MovI->addOperand(MF, MachineOperand::CreateGA(
833 GV, MovZ->getOperand(1).getOffset(), Flags));
834 } else {
835 MovI->addOperand(
836 MF, MachineOperand::CreateBA(cast<BlockAddress>(V),
837 MovZ->getOperand(1).getOffset(), Flags));
838 }
839 MovI->addOperand(MF, MachineOperand::CreateImm(Offset));
840 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI);
841 return DstReg;
842 };
843 unsigned DstReg = BuildMovK(MovZ->getOperand(0).getReg(),
844 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0);
845 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0);
846 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg());
847 return;
848}
849
Daniel Sandersf76f3152017-11-16 00:46:35 +0000850bool AArch64InstructionSelector::select(MachineInstr &I,
851 CodeGenCoverage &CoverageInfo) const {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000852 assert(I.getParent() && "Instruction should be in a basic block!");
853 assert(I.getParent()->getParent() && "Instruction should be in a function!");
854
855 MachineBasicBlock &MBB = *I.getParent();
856 MachineFunction &MF = *MBB.getParent();
857 MachineRegisterInfo &MRI = MF.getRegInfo();
858
Tim Northovercdf23f12016-10-31 18:30:59 +0000859 unsigned Opcode = I.getOpcode();
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000860 // G_PHI requires same handling as PHI
861 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
Tim Northovercdf23f12016-10-31 18:30:59 +0000862 // Certain non-generic instructions also need some special handling.
863
864 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
865 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000866
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000867 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
Tim Northover7d88da62016-11-08 00:34:06 +0000868 const unsigned DefReg = I.getOperand(0).getReg();
869 const LLT DefTy = MRI.getType(DefReg);
870
871 const TargetRegisterClass *DefRC = nullptr;
872 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
873 DefRC = TRI.getRegClass(DefReg);
874 } else {
875 const RegClassOrRegBank &RegClassOrBank =
876 MRI.getRegClassOrRegBank(DefReg);
877
878 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
879 if (!DefRC) {
880 if (!DefTy.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000881 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000882 return false;
883 }
884 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
885 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
886 if (!DefRC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000887 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000888 return false;
889 }
890 }
891 }
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000892 I.setDesc(TII.get(TargetOpcode::PHI));
Tim Northover7d88da62016-11-08 00:34:06 +0000893
894 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
895 }
896
897 if (I.isCopy())
Tim Northovercdf23f12016-10-31 18:30:59 +0000898 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000899
900 return true;
Tim Northovercdf23f12016-10-31 18:30:59 +0000901 }
902
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000903
904 if (I.getNumOperands() != I.getNumExplicitOperands()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000905 LLVM_DEBUG(
906 dbgs() << "Generic instruction has unexpected implicit operands\n");
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000907 return false;
908 }
909
Daniel Sandersf76f3152017-11-16 00:46:35 +0000910 if (selectImpl(I, CoverageInfo))
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000911 return true;
912
Tim Northover32a078a2016-09-15 10:09:59 +0000913 LLT Ty =
914 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000915
Tim Northover69271c62016-10-12 22:49:11 +0000916 switch (Opcode) {
Tim Northover5e3dbf32016-10-12 22:49:01 +0000917 case TargetOpcode::G_BRCOND: {
918 if (Ty.getSizeInBits() > 32) {
919 // We shouldn't need this on AArch64, but it would be implemented as an
920 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
921 // bit being tested is < 32.
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000922 LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
923 << ", expected at most 32-bits");
Tim Northover5e3dbf32016-10-12 22:49:01 +0000924 return false;
925 }
926
927 const unsigned CondReg = I.getOperand(0).getReg();
928 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
929
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000930 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
931 // instructions will not be produced, as they are conditional branch
932 // instructions that do not set flags.
933 bool ProduceNonFlagSettingCondBr =
934 !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening);
935 if (ProduceNonFlagSettingCondBr && selectCompareBranch(I, MF, MRI))
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000936 return true;
937
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000938 if (ProduceNonFlagSettingCondBr) {
939 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
940 .addUse(CondReg)
941 .addImm(/*bit offset=*/0)
942 .addMBB(DestMBB);
Tim Northover5e3dbf32016-10-12 22:49:01 +0000943
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000944 I.eraseFromParent();
945 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
946 } else {
947 auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
948 .addDef(AArch64::WZR)
949 .addUse(CondReg)
950 .addImm(1);
951 constrainSelectedInstRegOperands(*CMP.getInstr(), TII, TRI, RBI);
952 auto Bcc =
953 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::Bcc))
954 .addImm(AArch64CC::EQ)
955 .addMBB(DestMBB);
956
957 I.eraseFromParent();
958 return constrainSelectedInstRegOperands(*Bcc.getInstr(), TII, TRI, RBI);
959 }
Tim Northover5e3dbf32016-10-12 22:49:01 +0000960 }
961
Kristof Beyls65a12c02017-01-30 09:13:18 +0000962 case TargetOpcode::G_BRINDIRECT: {
963 I.setDesc(TII.get(AArch64::BR));
964 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
965 }
966
Tim Northover4494d692016-10-18 19:47:57 +0000967 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +0000968 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +0000969 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
970
971 const LLT s32 = LLT::scalar(32);
972 const LLT s64 = LLT::scalar(64);
973 const LLT p0 = LLT::pointer(0, 64);
974
975 const unsigned DefReg = I.getOperand(0).getReg();
976 const LLT DefTy = MRI.getType(DefReg);
977 const unsigned DefSize = DefTy.getSizeInBits();
978 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
979
980 // FIXME: Redundant check, but even less readable when factored out.
981 if (isFP) {
982 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000983 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
984 << " constant, expected: " << s32 << " or " << s64
985 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +0000986 return false;
987 }
988
989 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000990 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
991 << " constant on bank: " << RB
992 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +0000993 return false;
994 }
Daniel Sanders11300ce2017-10-13 21:28:03 +0000995
996 // The case when we have 0.0 is covered by tablegen. Reject it here so we
997 // can be sure tablegen works correctly and isn't rescued by this code.
998 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
999 return false;
Tim Northover4494d692016-10-18 19:47:57 +00001000 } else {
Daniel Sanders05540042017-08-08 10:44:31 +00001001 // s32 and s64 are covered by tablegen.
1002 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001003 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1004 << " constant, expected: " << s32 << ", " << s64
1005 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001006 return false;
1007 }
1008
1009 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001010 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1011 << " constant on bank: " << RB
1012 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001013 return false;
1014 }
1015 }
1016
1017 const unsigned MovOpc =
1018 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
1019
1020 I.setDesc(TII.get(MovOpc));
1021
1022 if (isFP) {
1023 const TargetRegisterClass &GPRRC =
1024 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
1025 const TargetRegisterClass &FPRRC =
1026 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
1027
1028 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
1029 MachineOperand &RegOp = I.getOperand(0);
1030 RegOp.setReg(DefGPRReg);
1031
1032 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1033 TII.get(AArch64::COPY))
1034 .addDef(DefReg)
1035 .addUse(DefGPRReg);
1036
1037 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001038 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +00001039 return false;
1040 }
1041
1042 MachineOperand &ImmOp = I.getOperand(1);
1043 // FIXME: Is going through int64_t always correct?
1044 ImmOp.ChangeToImmediate(
1045 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001046 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +00001047 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
1048 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001049 } else if (I.getOperand(1).isImm()) {
1050 uint64_t Val = I.getOperand(1).getImm();
1051 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +00001052 }
1053
1054 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1055 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +00001056 }
Tim Northover7b6d66c2017-07-20 22:58:38 +00001057 case TargetOpcode::G_EXTRACT: {
1058 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001059 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +00001060 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +00001061 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001062 // Larger extracts are vectors, same-size extracts should be something else
1063 // by now (either split up or simplified to a COPY).
1064 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
1065 return false;
1066
Amara Emersonbc03bae2018-02-18 17:03:02 +00001067 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001068 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
1069 Ty.getSizeInBits() - 1);
1070
Amara Emersonbc03bae2018-02-18 17:03:02 +00001071 if (SrcSize < 64) {
1072 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
1073 "unexpected G_EXTRACT types");
1074 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1075 }
1076
Tim Northover7b6d66c2017-07-20 22:58:38 +00001077 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1078 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1079 TII.get(AArch64::COPY))
1080 .addDef(I.getOperand(0).getReg())
1081 .addUse(DstReg, 0, AArch64::sub_32);
1082 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
1083 AArch64::GPR32RegClass, MRI);
1084 I.getOperand(0).setReg(DstReg);
1085
1086 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1087 }
1088
1089 case TargetOpcode::G_INSERT: {
1090 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001091 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1092 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001093 // Larger inserts are vectors, same-size ones should be something else by
1094 // now (split up or turned into COPYs).
1095 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
1096 return false;
1097
Amara Emersonbc03bae2018-02-18 17:03:02 +00001098 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001099 unsigned LSB = I.getOperand(3).getImm();
1100 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +00001101 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +00001102 MachineInstrBuilder(MF, I).addImm(Width - 1);
1103
Amara Emersonbc03bae2018-02-18 17:03:02 +00001104 if (DstSize < 64) {
1105 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
1106 "unexpected G_INSERT types");
1107 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1108 }
1109
Tim Northover7b6d66c2017-07-20 22:58:38 +00001110 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1111 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
1112 TII.get(AArch64::SUBREG_TO_REG))
1113 .addDef(SrcReg)
1114 .addImm(0)
1115 .addUse(I.getOperand(2).getReg())
1116 .addImm(AArch64::sub_32);
1117 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
1118 AArch64::GPR32RegClass, MRI);
1119 I.getOperand(2).setReg(SrcReg);
1120
1121 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1122 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001123 case TargetOpcode::G_FRAME_INDEX: {
1124 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +00001125 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001126 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
1127 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001128 return false;
1129 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001130 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001131
1132 // MOs for a #0 shifted immediate.
1133 I.addOperand(MachineOperand::CreateImm(0));
1134 I.addOperand(MachineOperand::CreateImm(0));
1135
1136 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1137 }
Tim Northoverbdf16242016-10-10 21:50:00 +00001138
1139 case TargetOpcode::G_GLOBAL_VALUE: {
1140 auto GV = I.getOperand(1).getGlobal();
1141 if (GV->isThreadLocal()) {
1142 // FIXME: we don't support TLS yet.
1143 return false;
1144 }
1145 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001146 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +00001147 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001148 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001149 } else if (TM.getCodeModel() == CodeModel::Large) {
1150 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +00001151 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001152 I.eraseFromParent();
1153 return true;
David Green9dd1d452018-08-22 11:31:39 +00001154 } else if (TM.getCodeModel() == CodeModel::Tiny) {
1155 I.setDesc(TII.get(AArch64::ADR));
1156 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001157 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +00001158 I.setDesc(TII.get(AArch64::MOVaddr));
1159 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1160 MachineInstrBuilder MIB(MF, I);
1161 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1162 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1163 }
1164 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1165 }
1166
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001167 case TargetOpcode::G_LOAD:
1168 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001169 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001170
Tim Northover5ae83502016-09-15 09:20:34 +00001171 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001172 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1173 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001174 return false;
1175 }
1176
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001177 auto &MemOp = **I.memoperands_begin();
1178 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001179 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001180 return false;
1181 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001182 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001183
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001184 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001185#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001186 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001187 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001188 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1189 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001190 assert(MRI.getType(PtrReg).isPointer() &&
1191 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001192#endif
1193
1194 const unsigned ValReg = I.getOperand(0).getReg();
1195 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1196
1197 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001198 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001199 if (NewOpc == I.getOpcode())
1200 return false;
1201
1202 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001203
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001204 uint64_t Offset = 0;
1205 auto *PtrMI = MRI.getVRegDef(PtrReg);
1206
1207 // Try to fold a GEP into our unsigned immediate addressing mode.
1208 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1209 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1210 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001211 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001212 const unsigned Scale = Log2_32(Size);
1213 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1214 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1215 I.getOperand(1).setReg(Ptr2Reg);
1216 PtrMI = MRI.getVRegDef(Ptr2Reg);
1217 Offset = Imm / Size;
1218 }
1219 }
1220 }
1221
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001222 // If we haven't folded anything into our addressing mode yet, try to fold
1223 // a frame index into the base+offset.
1224 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1225 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1226
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001227 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001228
1229 // If we're storing a 0, use WZR/XZR.
1230 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1231 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1232 if (I.getOpcode() == AArch64::STRWui)
1233 I.getOperand(0).setReg(AArch64::WZR);
1234 else if (I.getOpcode() == AArch64::STRXui)
1235 I.getOperand(0).setReg(AArch64::XZR);
1236 }
1237 }
1238
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001239 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1240 }
1241
Tim Northover9dd78f82017-02-08 21:22:25 +00001242 case TargetOpcode::G_SMULH:
1243 case TargetOpcode::G_UMULH: {
1244 // Reject the various things we don't support yet.
1245 if (unsupportedBinOp(I, RBI, MRI, TRI))
1246 return false;
1247
1248 const unsigned DefReg = I.getOperand(0).getReg();
1249 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1250
1251 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001252 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001253 return false;
1254 }
1255
1256 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001257 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1258 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001259 return false;
1260 }
1261
1262 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1263 : AArch64::UMULHrr;
1264 I.setDesc(TII.get(NewOpc));
1265
1266 // Now that we selected an opcode, we need to constrain the register
1267 // operands to use appropriate classes.
1268 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1269 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001270 case TargetOpcode::G_FADD:
1271 case TargetOpcode::G_FSUB:
1272 case TargetOpcode::G_FMUL:
1273 case TargetOpcode::G_FDIV:
1274
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001275 case TargetOpcode::G_OR:
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001276 case TargetOpcode::G_SHL:
1277 case TargetOpcode::G_LSHR:
1278 case TargetOpcode::G_ASHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001279 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001280 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001281 if (unsupportedBinOp(I, RBI, MRI, TRI))
1282 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001283
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001284 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001285
1286 const unsigned DefReg = I.getOperand(0).getReg();
1287 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1288
1289 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1290 if (NewOpc == I.getOpcode())
1291 return false;
1292
1293 I.setDesc(TII.get(NewOpc));
1294 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001295
1296 // Now that we selected an opcode, we need to constrain the register
1297 // operands to use appropriate classes.
1298 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1299 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001300
Tim Northover398c5f52017-02-14 20:56:29 +00001301 case TargetOpcode::G_PTR_MASK: {
1302 uint64_t Align = I.getOperand(2).getImm();
1303 if (Align >= 64 || Align == 0)
1304 return false;
1305
1306 uint64_t Mask = ~((1ULL << Align) - 1);
1307 I.setDesc(TII.get(AArch64::ANDXri));
1308 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1309
1310 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1311 }
Tim Northover037af52c2016-10-31 18:31:09 +00001312 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001313 case TargetOpcode::G_TRUNC: {
1314 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1315 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1316
1317 const unsigned DstReg = I.getOperand(0).getReg();
1318 const unsigned SrcReg = I.getOperand(1).getReg();
1319
1320 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1321 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1322
1323 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001324 LLVM_DEBUG(
1325 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001326 return false;
1327 }
1328
1329 if (DstRB.getID() == AArch64::GPRRegBankID) {
1330 const TargetRegisterClass *DstRC =
1331 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1332 if (!DstRC)
1333 return false;
1334
1335 const TargetRegisterClass *SrcRC =
1336 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1337 if (!SrcRC)
1338 return false;
1339
1340 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1341 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001342 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001343 return false;
1344 }
1345
1346 if (DstRC == SrcRC) {
1347 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001348 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1349 SrcTy == LLT::scalar(64)) {
1350 llvm_unreachable("TableGen can import this case");
1351 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001352 } else if (DstRC == &AArch64::GPR32RegClass &&
1353 SrcRC == &AArch64::GPR64RegClass) {
1354 I.getOperand(1).setSubReg(AArch64::sub_32);
1355 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001356 LLVM_DEBUG(
1357 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001358 return false;
1359 }
1360
1361 I.setDesc(TII.get(TargetOpcode::COPY));
1362 return true;
1363 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1364 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1365 I.setDesc(TII.get(AArch64::XTNv4i16));
1366 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1367 return true;
1368 }
1369 }
1370
1371 return false;
1372 }
1373
Tim Northover3d38b3a2016-10-11 20:50:21 +00001374 case TargetOpcode::G_ANYEXT: {
1375 const unsigned DstReg = I.getOperand(0).getReg();
1376 const unsigned SrcReg = I.getOperand(1).getReg();
1377
Quentin Colombetcb629a82016-10-12 03:57:49 +00001378 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1379 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001380 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1381 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001382 return false;
1383 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001384
Quentin Colombetcb629a82016-10-12 03:57:49 +00001385 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1386 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001387 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1388 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001389 return false;
1390 }
1391
1392 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1393
1394 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001395 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001396 return false;
1397 }
1398
Quentin Colombetcb629a82016-10-12 03:57:49 +00001399 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001400 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1401 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001402 return false;
1403 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001404 // At this point G_ANYEXT is just like a plain COPY, but we need
1405 // to explicitly form the 64-bit value if any.
1406 if (DstSize > 32) {
1407 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1408 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1409 .addDef(ExtSrc)
1410 .addImm(0)
1411 .addUse(SrcReg)
1412 .addImm(AArch64::sub_32);
1413 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001414 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001415 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001416 }
1417
1418 case TargetOpcode::G_ZEXT:
1419 case TargetOpcode::G_SEXT: {
1420 unsigned Opcode = I.getOpcode();
1421 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1422 SrcTy = MRI.getType(I.getOperand(1).getReg());
1423 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1424 const unsigned DefReg = I.getOperand(0).getReg();
1425 const unsigned SrcReg = I.getOperand(1).getReg();
1426 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1427
1428 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001429 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1430 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001431 return false;
1432 }
1433
1434 MachineInstr *ExtI;
1435 if (DstTy == LLT::scalar(64)) {
1436 // FIXME: Can we avoid manually doing this?
1437 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001438 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1439 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001440 return false;
1441 }
1442
1443 const unsigned SrcXReg =
1444 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1445 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1446 .addDef(SrcXReg)
1447 .addImm(0)
1448 .addUse(SrcReg)
1449 .addImm(AArch64::sub_32);
1450
1451 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1452 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1453 .addDef(DefReg)
1454 .addUse(SrcXReg)
1455 .addImm(0)
1456 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001457 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001458 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1459 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1460 .addDef(DefReg)
1461 .addUse(SrcReg)
1462 .addImm(0)
1463 .addImm(SrcTy.getSizeInBits() - 1);
1464 } else {
1465 return false;
1466 }
1467
1468 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1469
1470 I.eraseFromParent();
1471 return true;
1472 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001473
Tim Northover69271c62016-10-12 22:49:11 +00001474 case TargetOpcode::G_SITOFP:
1475 case TargetOpcode::G_UITOFP:
1476 case TargetOpcode::G_FPTOSI:
1477 case TargetOpcode::G_FPTOUI: {
1478 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1479 SrcTy = MRI.getType(I.getOperand(1).getReg());
1480 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1481 if (NewOpc == Opcode)
1482 return false;
1483
1484 I.setDesc(TII.get(NewOpc));
1485 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1486
1487 return true;
1488 }
1489
1490
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001491 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001492 // The importer is currently unable to import pointer types since they
1493 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001494 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001495
Daniel Sandersedd07842017-08-17 09:26:14 +00001496 case TargetOpcode::G_BITCAST:
1497 // Imported SelectionDAG rules can handle every bitcast except those that
1498 // bitcast from a type to the same type. Ideally, these shouldn't occur
1499 // but we might not run an optimizer that deletes them.
1500 if (MRI.getType(I.getOperand(0).getReg()) ==
1501 MRI.getType(I.getOperand(1).getReg()))
1502 return selectCopy(I, TII, MRI, TRI, RBI);
1503 return false;
1504
Tim Northover9ac0eba2016-11-08 00:45:29 +00001505 case TargetOpcode::G_SELECT: {
1506 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001507 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1508 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001509 return false;
1510 }
1511
1512 const unsigned CondReg = I.getOperand(1).getReg();
1513 const unsigned TReg = I.getOperand(2).getReg();
1514 const unsigned FReg = I.getOperand(3).getReg();
1515
1516 unsigned CSelOpc = 0;
1517
1518 if (Ty == LLT::scalar(32)) {
1519 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001520 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001521 CSelOpc = AArch64::CSELXr;
1522 } else {
1523 return false;
1524 }
1525
1526 MachineInstr &TstMI =
1527 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1528 .addDef(AArch64::WZR)
1529 .addUse(CondReg)
1530 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1531
1532 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1533 .addDef(I.getOperand(0).getReg())
1534 .addUse(TReg)
1535 .addUse(FReg)
1536 .addImm(AArch64CC::NE);
1537
1538 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1539 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1540
1541 I.eraseFromParent();
1542 return true;
1543 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001544 case TargetOpcode::G_ICMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001545 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001546 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1547 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001548 return false;
1549 }
1550
1551 unsigned CmpOpc = 0;
1552 unsigned ZReg = 0;
1553
1554 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1555 if (CmpTy == LLT::scalar(32)) {
1556 CmpOpc = AArch64::SUBSWrr;
1557 ZReg = AArch64::WZR;
1558 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1559 CmpOpc = AArch64::SUBSXrr;
1560 ZReg = AArch64::XZR;
1561 } else {
1562 return false;
1563 }
1564
Kristof Beyls22524402017-01-05 10:16:08 +00001565 // CSINC increments the result by one when the condition code is false.
1566 // Therefore, we have to invert the predicate to get an increment by 1 when
1567 // the predicate is true.
1568 const AArch64CC::CondCode invCC =
1569 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1570 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001571
1572 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1573 .addDef(ZReg)
1574 .addUse(I.getOperand(2).getReg())
1575 .addUse(I.getOperand(3).getReg());
1576
1577 MachineInstr &CSetMI =
1578 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1579 .addDef(I.getOperand(0).getReg())
1580 .addUse(AArch64::WZR)
1581 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001582 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001583
1584 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1585 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1586
1587 I.eraseFromParent();
1588 return true;
1589 }
1590
Tim Northover7dd378d2016-10-12 22:49:07 +00001591 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001592 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001593 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1594 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001595 return false;
1596 }
1597
1598 unsigned CmpOpc = 0;
1599 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1600 if (CmpTy == LLT::scalar(32)) {
1601 CmpOpc = AArch64::FCMPSrr;
1602 } else if (CmpTy == LLT::scalar(64)) {
1603 CmpOpc = AArch64::FCMPDrr;
1604 } else {
1605 return false;
1606 }
1607
1608 // FIXME: regbank
1609
1610 AArch64CC::CondCode CC1, CC2;
1611 changeFCMPPredToAArch64CC(
1612 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1613
1614 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1615 .addUse(I.getOperand(2).getReg())
1616 .addUse(I.getOperand(3).getReg());
1617
1618 const unsigned DefReg = I.getOperand(0).getReg();
1619 unsigned Def1Reg = DefReg;
1620 if (CC2 != AArch64CC::AL)
1621 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1622
1623 MachineInstr &CSetMI =
1624 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1625 .addDef(Def1Reg)
1626 .addUse(AArch64::WZR)
1627 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001628 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001629
1630 if (CC2 != AArch64CC::AL) {
1631 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1632 MachineInstr &CSet2MI =
1633 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1634 .addDef(Def2Reg)
1635 .addUse(AArch64::WZR)
1636 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001637 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001638 MachineInstr &OrMI =
1639 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1640 .addDef(DefReg)
1641 .addUse(Def1Reg)
1642 .addUse(Def2Reg);
1643 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1644 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1645 }
1646
1647 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1648 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1649
1650 I.eraseFromParent();
1651 return true;
1652 }
Tim Northovere9600d82017-02-08 17:57:27 +00001653 case TargetOpcode::G_VASTART:
1654 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1655 : selectVaStartAAPCS(I, MF, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001656 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1657 if (!I.getOperand(0).isIntrinsicID())
1658 return false;
1659 if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1660 return false;
1661 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::BRK))
1662 .addImm(1);
1663 I.eraseFromParent();
1664 return true;
Amara Emerson1e8c1642018-07-31 00:09:02 +00001665 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001666 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001667 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1668 const unsigned DstReg = I.getOperand(0).getReg();
1669 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1670 const TargetRegisterClass *DstRC =
1671 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1672 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001673 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001674 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001675 case TargetOpcode::G_BLOCK_ADDR: {
1676 if (TM.getCodeModel() == CodeModel::Large) {
1677 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1678 I.eraseFromParent();
1679 return true;
1680 } else {
1681 I.setDesc(TII.get(AArch64::MOVaddrBA));
1682 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1683 I.getOperand(0).getReg())
1684 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1685 /* Offset */ 0, AArch64II::MO_PAGE)
1686 .addBlockAddress(
1687 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1688 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1689 I.eraseFromParent();
1690 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1691 }
1692 }
Amara Emerson5ec14602018-12-10 18:44:58 +00001693 case TargetOpcode::G_BUILD_VECTOR:
1694 return selectBuildVector(I, MRI);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001695 case TargetOpcode::G_MERGE_VALUES:
1696 return selectMergeValues(I, MRI);
Jessica Paquette245047d2019-01-24 22:00:41 +00001697 case TargetOpcode::G_UNMERGE_VALUES:
1698 return selectUnmergeValues(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001699 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001700
1701 return false;
1702}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001703
Amara Emerson5ec14602018-12-10 18:44:58 +00001704bool AArch64InstructionSelector::emitScalarToVector(
1705 unsigned &Dst, const LLT DstTy, const TargetRegisterClass *DstRC,
1706 unsigned Scalar, MachineBasicBlock &MBB,
1707 MachineBasicBlock::iterator MBBI, MachineRegisterInfo &MRI) const {
1708 Dst = MRI.createVirtualRegister(DstRC);
1709
1710 unsigned UndefVec = MRI.createVirtualRegister(DstRC);
1711 MachineInstr &UndefMI = *BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1712 TII.get(TargetOpcode::IMPLICIT_DEF))
1713 .addDef(UndefVec);
1714
1715 auto BuildFn = [&](unsigned SubregIndex) {
1716 MachineInstr &InsMI = *BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1717 TII.get(TargetOpcode::INSERT_SUBREG))
1718 .addDef(Dst)
1719 .addUse(UndefVec)
1720 .addUse(Scalar)
1721 .addImm(SubregIndex);
1722 constrainSelectedInstRegOperands(UndefMI, TII, TRI, RBI);
1723 return constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1724 };
1725
1726 switch (DstTy.getElementType().getSizeInBits()) {
Jessica Paquette245047d2019-01-24 22:00:41 +00001727 case 16:
1728 return BuildFn(AArch64::hsub);
Amara Emerson5ec14602018-12-10 18:44:58 +00001729 case 32:
1730 return BuildFn(AArch64::ssub);
1731 case 64:
1732 return BuildFn(AArch64::dsub);
1733 default:
1734 return false;
1735 }
1736}
1737
Amara Emerson8cb186c2018-12-20 01:11:04 +00001738bool AArch64InstructionSelector::selectMergeValues(
1739 MachineInstr &I, MachineRegisterInfo &MRI) const {
1740 assert(I.getOpcode() == TargetOpcode::G_MERGE_VALUES && "unexpected opcode");
1741 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1742 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1743 assert(!DstTy.isVector() && !SrcTy.isVector() && "invalid merge operation");
1744
1745 // At the moment we only support merging two s32s into an s64.
1746 if (I.getNumOperands() != 3)
1747 return false;
1748 if (DstTy.getSizeInBits() != 64 || SrcTy.getSizeInBits() != 32)
1749 return false;
1750 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1751 if (RB.getID() != AArch64::GPRRegBankID)
1752 return false;
1753
1754 auto *DstRC = &AArch64::GPR64RegClass;
1755 unsigned SubToRegDef = MRI.createVirtualRegister(DstRC);
1756 MachineInstr &SubRegMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1757 TII.get(TargetOpcode::SUBREG_TO_REG))
1758 .addDef(SubToRegDef)
1759 .addImm(0)
1760 .addUse(I.getOperand(1).getReg())
1761 .addImm(AArch64::sub_32);
1762 unsigned SubToRegDef2 = MRI.createVirtualRegister(DstRC);
1763 // Need to anyext the second scalar before we can use bfm
1764 MachineInstr &SubRegMI2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1765 TII.get(TargetOpcode::SUBREG_TO_REG))
1766 .addDef(SubToRegDef2)
1767 .addImm(0)
1768 .addUse(I.getOperand(2).getReg())
1769 .addImm(AArch64::sub_32);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001770 MachineInstr &BFM =
1771 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::BFMXri))
Amara Emerson321bfb22018-12-20 03:27:42 +00001772 .addDef(I.getOperand(0).getReg())
Amara Emerson8cb186c2018-12-20 01:11:04 +00001773 .addUse(SubToRegDef)
1774 .addUse(SubToRegDef2)
1775 .addImm(32)
1776 .addImm(31);
1777 constrainSelectedInstRegOperands(SubRegMI, TII, TRI, RBI);
1778 constrainSelectedInstRegOperands(SubRegMI2, TII, TRI, RBI);
1779 constrainSelectedInstRegOperands(BFM, TII, TRI, RBI);
1780 I.eraseFromParent();
1781 return true;
1782}
1783
Jessica Paquette245047d2019-01-24 22:00:41 +00001784bool AArch64InstructionSelector::selectUnmergeValues(
1785 MachineInstr &I, MachineRegisterInfo &MRI) const {
1786 assert(I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
1787 "unexpected opcode");
1788
1789 // TODO: Handle unmerging into GPRs and from scalars to scalars.
1790 if (RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI)->getID() !=
1791 AArch64::FPRRegBankID ||
1792 RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI)->getID() !=
1793 AArch64::FPRRegBankID) {
1794 LLVM_DEBUG(dbgs() << "Unmerging vector-to-gpr and scalar-to-scalar "
1795 "currently unsupported.\n");
1796 return false;
1797 }
1798
1799 // The last operand is the vector source register, and every other operand is
1800 // a register to unpack into.
1801 unsigned NumElts = I.getNumOperands() - 1;
1802 unsigned SrcReg = I.getOperand(NumElts).getReg();
1803 const LLT NarrowTy = MRI.getType(I.getOperand(0).getReg());
1804 const LLT WideTy = MRI.getType(SrcReg);
1805 assert(WideTy.isVector() && "can only unmerge from vector types!");
1806 assert(WideTy.getSizeInBits() > NarrowTy.getSizeInBits() &&
1807 "source register size too small!");
1808
1809 // TODO: Handle unmerging into scalars.
1810 if (!NarrowTy.isScalar()) {
1811 LLVM_DEBUG(dbgs() << "Vector-to-vector unmerges not supported yet.\n");
1812 return false;
1813 }
1814
1815 // Choose a lane copy opcode and subregister based off of the size of the
1816 // vector's elements.
1817 unsigned CopyOpc = 0;
1818 unsigned ExtractSubReg = 0;
1819 switch (NarrowTy.getSizeInBits()) {
1820 case 16:
1821 CopyOpc = AArch64::CPYi16;
1822 ExtractSubReg = AArch64::hsub;
1823 break;
1824 case 32:
1825 CopyOpc = AArch64::CPYi32;
1826 ExtractSubReg = AArch64::ssub;
1827 break;
1828 case 64:
1829 CopyOpc = AArch64::CPYi64;
1830 ExtractSubReg = AArch64::dsub;
1831 break;
1832 default:
1833 // Unknown size, bail out.
1834 LLVM_DEBUG(dbgs() << "NarrowTy had unsupported size.\n");
1835 return false;
1836 }
1837
1838 // Set up for the lane copies.
1839 MachineBasicBlock &MBB = *I.getParent();
1840
1841 // Stores the registers we'll be copying from.
1842 SmallVector<unsigned, 4> InsertRegs;
1843
1844 // We'll use the first register twice, so we only need NumElts-1 registers.
1845 unsigned NumInsertRegs = NumElts - 1;
1846
1847 // If our elements fit into exactly 128 bits, then we can copy from the source
1848 // directly. Otherwise, we need to do a bit of setup with some subregister
1849 // inserts.
1850 if (NarrowTy.getSizeInBits() * NumElts == 128) {
1851 InsertRegs = SmallVector<unsigned, 4>(NumInsertRegs, SrcReg);
1852 } else {
1853 // No. We have to perform subregister inserts. For each insert, create an
1854 // implicit def and a subregister insert, and save the register we create.
1855 for (unsigned Idx = 0; Idx < NumInsertRegs; ++Idx) {
1856 unsigned ImpDefReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
1857 MachineInstr &ImpDefMI =
1858 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
1859 ImpDefReg);
1860
1861 // Now, create the subregister insert from SrcReg.
1862 unsigned InsertReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
1863 MachineInstr &InsMI =
1864 *BuildMI(MBB, I, I.getDebugLoc(),
1865 TII.get(TargetOpcode::INSERT_SUBREG), InsertReg)
1866 .addUse(ImpDefReg)
1867 .addUse(SrcReg)
1868 .addImm(AArch64::dsub);
1869
1870 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
1871 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1872
1873 // Save the register so that we can copy from it after.
1874 InsertRegs.push_back(InsertReg);
1875 }
1876 }
1877
1878 // Now that we've created any necessary subregister inserts, we can
1879 // create the copies.
1880 //
1881 // Perform the first copy separately as a subregister copy.
1882 unsigned CopyTo = I.getOperand(0).getReg();
1883 MachineInstr &FirstCopy =
1884 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), CopyTo)
1885 .addUse(InsertRegs[0], 0, ExtractSubReg);
1886 constrainSelectedInstRegOperands(FirstCopy, TII, TRI, RBI);
1887
1888 // Now, perform the remaining copies as vector lane copies.
1889 unsigned LaneIdx = 1;
1890 for (unsigned InsReg : InsertRegs) {
1891 unsigned CopyTo = I.getOperand(LaneIdx).getReg();
1892 MachineInstr &CopyInst =
1893 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CopyOpc), CopyTo)
1894 .addUse(InsReg)
1895 .addImm(LaneIdx);
1896 constrainSelectedInstRegOperands(CopyInst, TII, TRI, RBI);
1897 ++LaneIdx;
1898 }
1899
1900 // Separately constrain the first copy's destination. Because of the
1901 // limitation in constrainOperandRegClass, we can't guarantee that this will
1902 // actually be constrained. So, do it ourselves using the second operand.
1903 const TargetRegisterClass *RC =
1904 MRI.getRegClassOrNull(I.getOperand(1).getReg());
1905 if (!RC) {
1906 LLVM_DEBUG(dbgs() << "Couldn't constrain copy destination.\n");
1907 return false;
1908 }
1909
1910 RBI.constrainGenericRegister(CopyTo, *RC, MRI);
1911 I.eraseFromParent();
1912 return true;
1913}
1914
Amara Emerson5ec14602018-12-10 18:44:58 +00001915bool AArch64InstructionSelector::selectBuildVector(
1916 MachineInstr &I, MachineRegisterInfo &MRI) const {
1917 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
1918 // Until we port more of the optimized selections, for now just use a vector
1919 // insert sequence.
1920 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1921 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
1922 unsigned EltSize = EltTy.getSizeInBits();
Jessica Paquette245047d2019-01-24 22:00:41 +00001923 if (EltSize < 16 || EltSize > 64)
Amara Emerson5ec14602018-12-10 18:44:58 +00001924 return false; // Don't support all element types yet.
1925 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1926 unsigned Opc;
1927 unsigned SubregIdx;
1928 if (RB.getID() == AArch64::GPRRegBankID) {
1929 if (EltSize == 32) {
1930 Opc = AArch64::INSvi32gpr;
1931 SubregIdx = AArch64::ssub;
1932 } else {
1933 Opc = AArch64::INSvi64gpr;
1934 SubregIdx = AArch64::dsub;
1935 }
1936 } else {
Jessica Paquette245047d2019-01-24 22:00:41 +00001937 if (EltSize == 16) {
1938 Opc = AArch64::INSvi16lane;
1939 SubregIdx = AArch64::hsub;
1940 } else if (EltSize == 32) {
Amara Emerson5ec14602018-12-10 18:44:58 +00001941 Opc = AArch64::INSvi32lane;
1942 SubregIdx = AArch64::ssub;
1943 } else {
1944 Opc = AArch64::INSvi64lane;
1945 SubregIdx = AArch64::dsub;
1946 }
1947 }
1948
Amara Emerson5ec14602018-12-10 18:44:58 +00001949 unsigned DstVec = 0;
Jessica Paquette245047d2019-01-24 22:00:41 +00001950
1951 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
1952 if (!emitScalarToVector(DstVec, DstTy, DstRC, I.getOperand(1).getReg(),
1953 *I.getParent(), I.getIterator(), MRI))
1954 return false;
1955
1956 unsigned DstSize = DstTy.getSizeInBits();
1957
1958 // Keep track of the last MI we inserted. Later on, we might be able to save
1959 // a copy using it.
1960 MachineInstr *PrevMI = nullptr;
1961 for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
Amara Emerson5ec14602018-12-10 18:44:58 +00001962 unsigned InsDef;
Jessica Paquette245047d2019-01-24 22:00:41 +00001963
1964 // Note that if we don't do a subregister copy, we end up making one more
1965 // of these than we need.
1966 InsDef = MRI.createVirtualRegister(DstRC);
Amara Emerson5ec14602018-12-10 18:44:58 +00001967 unsigned LaneIdx = i - 1;
1968 if (RB.getID() == AArch64::FPRRegBankID) {
1969 unsigned ImpDef = MRI.createVirtualRegister(DstRC);
1970 MachineInstr &ImpDefMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1971 TII.get(TargetOpcode::IMPLICIT_DEF))
1972 .addDef(ImpDef);
1973 unsigned InsSubDef = MRI.createVirtualRegister(DstRC);
1974 MachineInstr &InsSubMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1975 TII.get(TargetOpcode::INSERT_SUBREG))
1976 .addDef(InsSubDef)
1977 .addUse(ImpDef)
1978 .addUse(I.getOperand(i).getReg())
1979 .addImm(SubregIdx);
1980 MachineInstr &InsEltMI =
1981 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
1982 .addDef(InsDef)
1983 .addUse(DstVec)
1984 .addImm(LaneIdx)
1985 .addUse(InsSubDef)
1986 .addImm(0);
1987 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
1988 constrainSelectedInstRegOperands(InsSubMI, TII, TRI, RBI);
1989 constrainSelectedInstRegOperands(InsEltMI, TII, TRI, RBI);
1990 DstVec = InsDef;
Jessica Paquette245047d2019-01-24 22:00:41 +00001991 PrevMI = &InsEltMI;
Amara Emerson5ec14602018-12-10 18:44:58 +00001992 } else {
1993 MachineInstr &InsMI =
1994 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
1995 .addDef(InsDef)
1996 .addUse(DstVec)
1997 .addImm(LaneIdx)
1998 .addUse(I.getOperand(i).getReg());
1999 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
2000 DstVec = InsDef;
Jessica Paquette245047d2019-01-24 22:00:41 +00002001 PrevMI = &InsMI;
Amara Emerson5ec14602018-12-10 18:44:58 +00002002 }
2003 }
Jessica Paquette245047d2019-01-24 22:00:41 +00002004
2005 // If DstTy's size in bits is less than 128, then emit a subregister copy
2006 // from DstVec to the last register we've defined.
2007 if (DstSize < 128) {
2008 unsigned SubReg = 0;
2009
2010 // Helper lambda to decide on a register class and subregister for the
2011 // subregister copy.
2012 auto GetRegInfoForCopy = [&SubReg,
2013 &DstSize]() -> const TargetRegisterClass * {
2014 switch (DstSize) {
2015 default:
2016 LLVM_DEBUG(dbgs() << "Unknown destination size (" << DstSize << ")\n");
2017 return nullptr;
2018 case 32:
2019 SubReg = AArch64::ssub;
2020 return &AArch64::FPR32RegClass;
2021 case 64:
2022 SubReg = AArch64::dsub;
2023 return &AArch64::FPR64RegClass;
2024 }
2025 };
2026
2027 const TargetRegisterClass *RC = GetRegInfoForCopy();
2028 if (!RC)
2029 return false;
2030
2031 unsigned Reg = MRI.createVirtualRegister(RC);
2032 unsigned DstReg = I.getOperand(0).getReg();
2033
2034 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
2035 DstReg)
2036 .addUse(DstVec, 0, SubReg);
2037 MachineOperand &RegOp = I.getOperand(1);
2038 RegOp.setReg(Reg);
2039 RBI.constrainGenericRegister(DstReg, *RC, MRI);
2040 } else {
2041 // We don't need a subregister copy. Save a copy by re-using the
2042 // destination register on the final insert.
2043 assert(PrevMI && "PrevMI was null?");
2044 PrevMI->getOperand(0).setReg(I.getOperand(0).getReg());
2045 constrainSelectedInstRegOperands(*PrevMI, TII, TRI, RBI);
2046 }
2047
Amara Emerson5ec14602018-12-10 18:44:58 +00002048 I.eraseFromParent();
2049 return true;
2050}
2051
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002052/// SelectArithImmed - Select an immediate value that can be represented as
2053/// a 12-bit value shifted left by either 0 or 12. If so, return true with
2054/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002055InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00002056AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002057 MachineInstr &MI = *Root.getParent();
2058 MachineBasicBlock &MBB = *MI.getParent();
2059 MachineFunction &MF = *MBB.getParent();
2060 MachineRegisterInfo &MRI = MF.getRegInfo();
2061
2062 // This function is called from the addsub_shifted_imm ComplexPattern,
2063 // which lists [imm] as the list of opcode it's interested in, however
2064 // we still need to check whether the operand is actually an immediate
2065 // here because the ComplexPattern opcode list is only used in
2066 // root-level opcode matching.
2067 uint64_t Immed;
2068 if (Root.isImm())
2069 Immed = Root.getImm();
2070 else if (Root.isCImm())
2071 Immed = Root.getCImm()->getZExtValue();
2072 else if (Root.isReg()) {
2073 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
2074 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002075 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002076 MachineOperand &Op1 = Def->getOperand(1);
2077 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002078 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002079 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002080 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002081 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002082
2083 unsigned ShiftAmt;
2084
2085 if (Immed >> 12 == 0) {
2086 ShiftAmt = 0;
2087 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
2088 ShiftAmt = 12;
2089 Immed = Immed >> 12;
2090 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002091 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002092
2093 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002094 return {{
2095 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
2096 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
2097 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002098}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002099
Daniel Sandersea8711b2017-10-16 03:36:29 +00002100/// Select a "register plus unscaled signed 9-bit immediate" address. This
2101/// should only match when there is an offset that is not valid for a scaled
2102/// immediate addressing mode. The "Size" argument is the size in bytes of the
2103/// memory reference, which is needed here to know what is valid for a scaled
2104/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002105InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002106AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
2107 unsigned Size) const {
2108 MachineRegisterInfo &MRI =
2109 Root.getParent()->getParent()->getParent()->getRegInfo();
2110
2111 if (!Root.isReg())
2112 return None;
2113
2114 if (!isBaseWithConstantOffset(Root, MRI))
2115 return None;
2116
2117 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2118 if (!RootDef)
2119 return None;
2120
2121 MachineOperand &OffImm = RootDef->getOperand(2);
2122 if (!OffImm.isReg())
2123 return None;
2124 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
2125 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
2126 return None;
2127 int64_t RHSC;
2128 MachineOperand &RHSOp1 = RHS->getOperand(1);
2129 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
2130 return None;
2131 RHSC = RHSOp1.getCImm()->getSExtValue();
2132
2133 // If the offset is valid as a scaled immediate, don't match here.
2134 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
2135 return None;
2136 if (RHSC >= -256 && RHSC < 256) {
2137 MachineOperand &Base = RootDef->getOperand(1);
2138 return {{
2139 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
2140 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
2141 }};
2142 }
2143 return None;
2144}
2145
2146/// Select a "register plus scaled unsigned 12-bit immediate" address. The
2147/// "Size" argument is the size in bytes of the memory reference, which
2148/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002149InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002150AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
2151 unsigned Size) const {
2152 MachineRegisterInfo &MRI =
2153 Root.getParent()->getParent()->getParent()->getRegInfo();
2154
2155 if (!Root.isReg())
2156 return None;
2157
2158 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2159 if (!RootDef)
2160 return None;
2161
2162 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
2163 return {{
2164 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
2165 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2166 }};
2167 }
2168
2169 if (isBaseWithConstantOffset(Root, MRI)) {
2170 MachineOperand &LHS = RootDef->getOperand(1);
2171 MachineOperand &RHS = RootDef->getOperand(2);
2172 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
2173 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
2174 if (LHSDef && RHSDef) {
2175 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
2176 unsigned Scale = Log2_32(Size);
2177 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
2178 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00002179 return {{
2180 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
2181 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2182 }};
2183
Daniel Sandersea8711b2017-10-16 03:36:29 +00002184 return {{
2185 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
2186 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2187 }};
2188 }
2189 }
2190 }
2191
2192 // Before falling back to our general case, check if the unscaled
2193 // instructions can handle this. If so, that's preferable.
2194 if (selectAddrModeUnscaled(Root, Size).hasValue())
2195 return None;
2196
2197 return {{
2198 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
2199 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2200 }};
2201}
2202
Volkan Kelesf7f25682018-01-16 18:44:05 +00002203void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
2204 const MachineInstr &MI) const {
2205 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2206 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
2207 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
2208 assert(CstVal && "Expected constant value");
2209 MIB.addImm(CstVal.getValue());
2210}
2211
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002212namespace llvm {
2213InstructionSelector *
2214createAArch64InstructionSelector(const AArch64TargetMachine &TM,
2215 AArch64Subtarget &Subtarget,
2216 AArch64RegisterBankInfo &RBI) {
2217 return new AArch64InstructionSelector(TM, Subtarget, RBI);
2218}
2219}