blob: ec2ce9355e64c5a45580c6c7915889b88142ef1b [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"
Amara Emerson1abe05c2019-02-21 20:20:16 +000026#include "llvm/CodeGen/MachineConstantPool.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000027#include "llvm/CodeGen/MachineFunction.h"
28#include "llvm/CodeGen/MachineInstr.h"
29#include "llvm/CodeGen/MachineInstrBuilder.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000030#include "llvm/CodeGen/MachineOperand.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000031#include "llvm/CodeGen/MachineRegisterInfo.h"
32#include "llvm/IR/Type.h"
33#include "llvm/Support/Debug.h"
34#include "llvm/Support/raw_ostream.h"
35
36#define DEBUG_TYPE "aarch64-isel"
37
38using namespace llvm;
39
Daniel Sanders0b5293f2017-04-06 09:49:34 +000040namespace {
41
Daniel Sanderse7b0d662017-04-21 15:59:56 +000042#define GET_GLOBALISEL_PREDICATE_BITSET
43#include "AArch64GenGlobalISel.inc"
44#undef GET_GLOBALISEL_PREDICATE_BITSET
45
Daniel Sanders0b5293f2017-04-06 09:49:34 +000046class AArch64InstructionSelector : public InstructionSelector {
47public:
48 AArch64InstructionSelector(const AArch64TargetMachine &TM,
49 const AArch64Subtarget &STI,
50 const AArch64RegisterBankInfo &RBI);
51
Daniel Sandersf76f3152017-11-16 00:46:35 +000052 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000053 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000054
55private:
56 /// tblgen-erated 'select' implementation, used as the initial selector for
57 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000058 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000059
60 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF,
61 MachineRegisterInfo &MRI) const;
62 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
63 MachineRegisterInfo &MRI) const;
64
65 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
66 MachineRegisterInfo &MRI) const;
67
Amara Emerson5ec14602018-12-10 18:44:58 +000068 // Helper to generate an equivalent of scalar_to_vector into a new register,
69 // returned via 'Dst'.
Amara Emerson8acb0d92019-03-04 19:16:00 +000070 MachineInstr *emitScalarToVector(unsigned EltSize,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +000071 const TargetRegisterClass *DstRC,
72 unsigned Scalar,
73 MachineIRBuilder &MIRBuilder) const;
Jessica Paquette16d67a32019-03-13 23:22:23 +000074
75 /// Emit a lane insert into \p DstReg, or a new vector register if None is
76 /// provided.
77 ///
78 /// The lane inserted into is defined by \p LaneIdx. The vector source
79 /// register is given by \p SrcReg. The register containing the element is
80 /// given by \p EltReg.
81 MachineInstr *emitLaneInsert(Optional<unsigned> DstReg, unsigned SrcReg,
82 unsigned EltReg, unsigned LaneIdx,
83 const RegisterBank &RB,
84 MachineIRBuilder &MIRBuilder) const;
Jessica Paquette5aff1f42019-03-14 18:01:30 +000085 bool selectInsertElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000086 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson8cb186c2018-12-20 01:11:04 +000087 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette245047d2019-01-24 22:00:41 +000088 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000089
Amara Emerson1abe05c2019-02-21 20:20:16 +000090 void collectShuffleMaskIndices(MachineInstr &I, MachineRegisterInfo &MRI,
91 SmallVectorImpl<int> &Idxs) const;
92 bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette607774c2019-03-11 22:18:01 +000093 bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +000094
95 unsigned emitConstantPoolEntry(Constant *CPVal, MachineFunction &MF) const;
96 MachineInstr *emitLoadFromConstantPool(Constant *CPVal,
97 MachineIRBuilder &MIRBuilder) const;
Amara Emerson8acb0d92019-03-04 19:16:00 +000098 MachineInstr *emitVectorConcat(unsigned Op1, unsigned Op2,
99 MachineIRBuilder &MIRBuilder) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +0000100
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000101 ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000102
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000103 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root,
104 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000105
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000106 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000107 return selectAddrModeUnscaled(Root, 1);
108 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000109 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000110 return selectAddrModeUnscaled(Root, 2);
111 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000112 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000113 return selectAddrModeUnscaled(Root, 4);
114 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000115 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000116 return selectAddrModeUnscaled(Root, 8);
117 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000118 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000119 return selectAddrModeUnscaled(Root, 16);
120 }
121
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000122 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root,
123 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000124 template <int Width>
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000125 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000126 return selectAddrModeIndexed(Root, Width / 8);
127 }
128
Volkan Kelesf7f25682018-01-16 18:44:05 +0000129 void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const;
130
Amara Emerson1e8c1642018-07-31 00:09:02 +0000131 // Materialize a GlobalValue or BlockAddress using a movz+movk sequence.
132 void materializeLargeCMVal(MachineInstr &I, const Value *V,
133 unsigned char OpFlags) const;
134
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000135 const AArch64TargetMachine &TM;
136 const AArch64Subtarget &STI;
137 const AArch64InstrInfo &TII;
138 const AArch64RegisterInfo &TRI;
139 const AArch64RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000140
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000141#define GET_GLOBALISEL_PREDICATES_DECL
142#include "AArch64GenGlobalISel.inc"
143#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000144
145// We declare the temporaries used by selectImpl() in the class to minimize the
146// cost of constructing placeholder values.
147#define GET_GLOBALISEL_TEMPORARIES_DECL
148#include "AArch64GenGlobalISel.inc"
149#undef GET_GLOBALISEL_TEMPORARIES_DECL
150};
151
152} // end anonymous namespace
153
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000154#define GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000155#include "AArch64GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000156#undef GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000157
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000158AArch64InstructionSelector::AArch64InstructionSelector(
Tim Northoverbdf16242016-10-10 21:50:00 +0000159 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
160 const AArch64RegisterBankInfo &RBI)
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000161 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000162 TRI(*STI.getRegisterInfo()), RBI(RBI),
163#define GET_GLOBALISEL_PREDICATES_INIT
164#include "AArch64GenGlobalISel.inc"
165#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000166#define GET_GLOBALISEL_TEMPORARIES_INIT
167#include "AArch64GenGlobalISel.inc"
168#undef GET_GLOBALISEL_TEMPORARIES_INIT
169{
170}
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000171
Tim Northoverfb8d9892016-10-12 22:49:15 +0000172// FIXME: This should be target-independent, inferred from the types declared
173// for each class in the bank.
174static const TargetRegisterClass *
175getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
Amara Emerson3838ed02018-02-02 18:03:30 +0000176 const RegisterBankInfo &RBI,
177 bool GetAllRegSet = false) {
Tim Northoverfb8d9892016-10-12 22:49:15 +0000178 if (RB.getID() == AArch64::GPRRegBankID) {
179 if (Ty.getSizeInBits() <= 32)
Amara Emerson3838ed02018-02-02 18:03:30 +0000180 return GetAllRegSet ? &AArch64::GPR32allRegClass
181 : &AArch64::GPR32RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000182 if (Ty.getSizeInBits() == 64)
Amara Emerson3838ed02018-02-02 18:03:30 +0000183 return GetAllRegSet ? &AArch64::GPR64allRegClass
184 : &AArch64::GPR64RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000185 return nullptr;
186 }
187
188 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson3838ed02018-02-02 18:03:30 +0000189 if (Ty.getSizeInBits() <= 16)
190 return &AArch64::FPR16RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000191 if (Ty.getSizeInBits() == 32)
192 return &AArch64::FPR32RegClass;
193 if (Ty.getSizeInBits() == 64)
194 return &AArch64::FPR64RegClass;
195 if (Ty.getSizeInBits() == 128)
196 return &AArch64::FPR128RegClass;
197 return nullptr;
198 }
199
200 return nullptr;
201}
202
Jessica Paquette245047d2019-01-24 22:00:41 +0000203/// Given a register bank, and size in bits, return the smallest register class
204/// that can represent that combination.
Benjamin Kramer711950c2019-02-11 15:16:21 +0000205static const TargetRegisterClass *
206getMinClassForRegBank(const RegisterBank &RB, unsigned SizeInBits,
207 bool GetAllRegSet = false) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000208 unsigned RegBankID = RB.getID();
209
210 if (RegBankID == AArch64::GPRRegBankID) {
211 if (SizeInBits <= 32)
212 return GetAllRegSet ? &AArch64::GPR32allRegClass
213 : &AArch64::GPR32RegClass;
214 if (SizeInBits == 64)
215 return GetAllRegSet ? &AArch64::GPR64allRegClass
216 : &AArch64::GPR64RegClass;
217 }
218
219 if (RegBankID == AArch64::FPRRegBankID) {
220 switch (SizeInBits) {
221 default:
222 return nullptr;
223 case 8:
224 return &AArch64::FPR8RegClass;
225 case 16:
226 return &AArch64::FPR16RegClass;
227 case 32:
228 return &AArch64::FPR32RegClass;
229 case 64:
230 return &AArch64::FPR64RegClass;
231 case 128:
232 return &AArch64::FPR128RegClass;
233 }
234 }
235
236 return nullptr;
237}
238
239/// Returns the correct subregister to use for a given register class.
240static bool getSubRegForClass(const TargetRegisterClass *RC,
241 const TargetRegisterInfo &TRI, unsigned &SubReg) {
242 switch (TRI.getRegSizeInBits(*RC)) {
243 case 8:
244 SubReg = AArch64::bsub;
245 break;
246 case 16:
247 SubReg = AArch64::hsub;
248 break;
249 case 32:
250 if (RC == &AArch64::GPR32RegClass)
251 SubReg = AArch64::sub_32;
252 else
253 SubReg = AArch64::ssub;
254 break;
255 case 64:
256 SubReg = AArch64::dsub;
257 break;
258 default:
259 LLVM_DEBUG(
260 dbgs() << "Couldn't find appropriate subregister for register class.");
261 return false;
262 }
263
264 return true;
265}
266
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000267/// Check whether \p I is a currently unsupported binary operation:
268/// - it has an unsized type
269/// - an operand is not a vreg
270/// - all operands are not in the same bank
271/// These are checks that should someday live in the verifier, but right now,
272/// these are mostly limitations of the aarch64 selector.
273static bool unsupportedBinOp(const MachineInstr &I,
274 const AArch64RegisterBankInfo &RBI,
275 const MachineRegisterInfo &MRI,
276 const AArch64RegisterInfo &TRI) {
Tim Northover0f140c72016-09-09 11:46:34 +0000277 LLT Ty = MRI.getType(I.getOperand(0).getReg());
Tim Northover32a078a2016-09-15 10:09:59 +0000278 if (!Ty.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000279 LLVM_DEBUG(dbgs() << "Generic binop register should be typed\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000280 return true;
281 }
282
283 const RegisterBank *PrevOpBank = nullptr;
284 for (auto &MO : I.operands()) {
285 // FIXME: Support non-register operands.
286 if (!MO.isReg()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000287 LLVM_DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000288 return true;
289 }
290
291 // FIXME: Can generic operations have physical registers operands? If
292 // so, this will need to be taught about that, and we'll need to get the
293 // bank out of the minimal class for the register.
294 // Either way, this needs to be documented (and possibly verified).
295 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000296 LLVM_DEBUG(dbgs() << "Generic inst has physical register operand\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000297 return true;
298 }
299
300 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI);
301 if (!OpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000302 LLVM_DEBUG(dbgs() << "Generic register has no bank or class\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000303 return true;
304 }
305
306 if (PrevOpBank && OpBank != PrevOpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000307 LLVM_DEBUG(dbgs() << "Generic inst operands have different banks\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000308 return true;
309 }
310 PrevOpBank = OpBank;
311 }
312 return false;
313}
314
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000315/// Select the AArch64 opcode for the basic binary operation \p GenericOpc
Ahmed Bougachacfb384d2017-01-23 21:10:05 +0000316/// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000317/// and of size \p OpSize.
318/// \returns \p GenericOpc if the combination is unsupported.
319static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
320 unsigned OpSize) {
321 switch (RegBankID) {
322 case AArch64::GPRRegBankID:
Ahmed Bougacha05a5f7d2017-01-25 02:41:38 +0000323 if (OpSize == 32) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000324 switch (GenericOpc) {
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000325 case TargetOpcode::G_SHL:
326 return AArch64::LSLVWr;
327 case TargetOpcode::G_LSHR:
328 return AArch64::LSRVWr;
329 case TargetOpcode::G_ASHR:
330 return AArch64::ASRVWr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000331 default:
332 return GenericOpc;
333 }
Tim Northover55782222016-10-18 20:03:48 +0000334 } else if (OpSize == 64) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000335 switch (GenericOpc) {
Tim Northover2fda4b02016-10-10 21:49:49 +0000336 case TargetOpcode::G_GEP:
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000337 return AArch64::ADDXrr;
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000338 case TargetOpcode::G_SHL:
339 return AArch64::LSLVXr;
340 case TargetOpcode::G_LSHR:
341 return AArch64::LSRVXr;
342 case TargetOpcode::G_ASHR:
343 return AArch64::ASRVXr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000344 default:
345 return GenericOpc;
346 }
347 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000348 break;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000349 case AArch64::FPRRegBankID:
350 switch (OpSize) {
351 case 32:
352 switch (GenericOpc) {
353 case TargetOpcode::G_FADD:
354 return AArch64::FADDSrr;
355 case TargetOpcode::G_FSUB:
356 return AArch64::FSUBSrr;
357 case TargetOpcode::G_FMUL:
358 return AArch64::FMULSrr;
359 case TargetOpcode::G_FDIV:
360 return AArch64::FDIVSrr;
361 default:
362 return GenericOpc;
363 }
364 case 64:
365 switch (GenericOpc) {
366 case TargetOpcode::G_FADD:
367 return AArch64::FADDDrr;
368 case TargetOpcode::G_FSUB:
369 return AArch64::FSUBDrr;
370 case TargetOpcode::G_FMUL:
371 return AArch64::FMULDrr;
372 case TargetOpcode::G_FDIV:
373 return AArch64::FDIVDrr;
Quentin Colombet0e531272016-10-11 00:21:11 +0000374 case TargetOpcode::G_OR:
375 return AArch64::ORRv8i8;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000376 default:
377 return GenericOpc;
378 }
379 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000380 break;
381 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000382 return GenericOpc;
383}
384
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000385/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
386/// appropriate for the (value) register bank \p RegBankID and of memory access
387/// size \p OpSize. This returns the variant with the base+unsigned-immediate
388/// addressing mode (e.g., LDRXui).
389/// \returns \p GenericOpc if the combination is unsupported.
390static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
391 unsigned OpSize) {
392 const bool isStore = GenericOpc == TargetOpcode::G_STORE;
393 switch (RegBankID) {
394 case AArch64::GPRRegBankID:
395 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000396 case 8:
397 return isStore ? AArch64::STRBBui : AArch64::LDRBBui;
398 case 16:
399 return isStore ? AArch64::STRHHui : AArch64::LDRHHui;
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000400 case 32:
401 return isStore ? AArch64::STRWui : AArch64::LDRWui;
402 case 64:
403 return isStore ? AArch64::STRXui : AArch64::LDRXui;
404 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000405 break;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000406 case AArch64::FPRRegBankID:
407 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000408 case 8:
409 return isStore ? AArch64::STRBui : AArch64::LDRBui;
410 case 16:
411 return isStore ? AArch64::STRHui : AArch64::LDRHui;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000412 case 32:
413 return isStore ? AArch64::STRSui : AArch64::LDRSui;
414 case 64:
415 return isStore ? AArch64::STRDui : AArch64::LDRDui;
416 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000417 break;
418 }
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000419 return GenericOpc;
420}
421
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000422#ifndef NDEBUG
Jessica Paquette245047d2019-01-24 22:00:41 +0000423/// Helper function that verifies that we have a valid copy at the end of
424/// selectCopy. Verifies that the source and dest have the expected sizes and
425/// then returns true.
426static bool isValidCopy(const MachineInstr &I, const RegisterBank &DstBank,
427 const MachineRegisterInfo &MRI,
428 const TargetRegisterInfo &TRI,
429 const RegisterBankInfo &RBI) {
430 const unsigned DstReg = I.getOperand(0).getReg();
431 const unsigned SrcReg = I.getOperand(1).getReg();
432 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
433 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Amara Emersondb211892018-02-20 05:11:57 +0000434
Jessica Paquette245047d2019-01-24 22:00:41 +0000435 // Make sure the size of the source and dest line up.
436 assert(
437 (DstSize == SrcSize ||
438 // Copies are a mean to setup initial types, the number of
439 // bits may not exactly match.
440 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && DstSize <= SrcSize) ||
441 // Copies are a mean to copy bits around, as long as we are
442 // on the same register class, that's fine. Otherwise, that
443 // means we need some SUBREG_TO_REG or AND & co.
444 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) &&
445 "Copy with different width?!");
446
447 // Check the size of the destination.
448 assert((DstSize <= 64 || DstBank.getID() == AArch64::FPRRegBankID) &&
449 "GPRs cannot get more than 64-bit width values");
450
451 return true;
452}
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000453#endif
Jessica Paquette245047d2019-01-24 22:00:41 +0000454
455/// Helper function for selectCopy. Inserts a subregister copy from
456/// \p *From to \p *To, linking it up to \p I.
457///
458/// e.g, given I = "Dst = COPY SrcReg", we'll transform that into
459///
460/// CopyReg (From class) = COPY SrcReg
461/// SubRegCopy (To class) = COPY CopyReg:SubReg
462/// Dst = COPY SubRegCopy
463static bool selectSubregisterCopy(MachineInstr &I, const TargetInstrInfo &TII,
464 MachineRegisterInfo &MRI,
465 const RegisterBankInfo &RBI, unsigned SrcReg,
466 const TargetRegisterClass *From,
467 const TargetRegisterClass *To,
468 unsigned SubReg) {
469 unsigned CopyReg = MRI.createVirtualRegister(From);
470 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::COPY), CopyReg)
471 .addUse(SrcReg);
472 unsigned SubRegCopy = MRI.createVirtualRegister(To);
473 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
474 SubRegCopy)
475 .addUse(CopyReg, 0, SubReg);
Amara Emersondb211892018-02-20 05:11:57 +0000476 MachineOperand &RegOp = I.getOperand(1);
477 RegOp.setReg(SubRegCopy);
Jessica Paquette245047d2019-01-24 22:00:41 +0000478
479 // It's possible that the destination register won't be constrained. Make
480 // sure that happens.
481 if (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()))
482 RBI.constrainGenericRegister(I.getOperand(0).getReg(), *To, MRI);
483
Amara Emersondb211892018-02-20 05:11:57 +0000484 return true;
485}
486
Quentin Colombetcb629a82016-10-12 03:57:49 +0000487static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
488 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
489 const RegisterBankInfo &RBI) {
490
491 unsigned DstReg = I.getOperand(0).getReg();
Amara Emersondb211892018-02-20 05:11:57 +0000492 unsigned SrcReg = I.getOperand(1).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +0000493 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
494 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
495 const TargetRegisterClass *DstRC = getMinClassForRegBank(
496 DstRegBank, RBI.getSizeInBits(DstReg, MRI, TRI), true);
497 if (!DstRC) {
498 LLVM_DEBUG(dbgs() << "Unexpected dest size "
499 << RBI.getSizeInBits(DstReg, MRI, TRI) << '\n');
Amara Emerson3838ed02018-02-02 18:03:30 +0000500 return false;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000501 }
502
Jessica Paquette245047d2019-01-24 22:00:41 +0000503 // A couple helpers below, for making sure that the copy we produce is valid.
504
505 // Set to true if we insert a SUBREG_TO_REG. If we do this, then we don't want
506 // to verify that the src and dst are the same size, since that's handled by
507 // the SUBREG_TO_REG.
508 bool KnownValid = false;
509
510 // Returns true, or asserts if something we don't expect happens. Instead of
511 // returning true, we return isValidCopy() to ensure that we verify the
512 // result.
Jessica Paquette76c40f82019-01-24 22:51:31 +0000513 auto CheckCopy = [&]() {
Jessica Paquette245047d2019-01-24 22:00:41 +0000514 // If we have a bitcast or something, we can't have physical registers.
515 assert(
Simon Pilgrimdea61742019-01-25 11:38:40 +0000516 (I.isCopy() ||
517 (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()) &&
518 !TargetRegisterInfo::isPhysicalRegister(I.getOperand(1).getReg()))) &&
519 "No phys reg on generic operator!");
Jessica Paquette245047d2019-01-24 22:00:41 +0000520 assert(KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI));
Jonas Hahnfeld65a401f2019-03-04 08:51:32 +0000521 (void)KnownValid;
Jessica Paquette245047d2019-01-24 22:00:41 +0000522 return true;
523 };
524
525 // Is this a copy? If so, then we may need to insert a subregister copy, or
526 // a SUBREG_TO_REG.
527 if (I.isCopy()) {
528 // Yes. Check if there's anything to fix up.
529 const TargetRegisterClass *SrcRC = getMinClassForRegBank(
530 SrcRegBank, RBI.getSizeInBits(SrcReg, MRI, TRI), true);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000531 if (!SrcRC) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000532 LLVM_DEBUG(dbgs() << "Couldn't determine source register class\n");
533 return false;
Amara Emerson7e9f3482018-02-18 17:10:49 +0000534 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000535
536 // Is this a cross-bank copy?
537 if (DstRegBank.getID() != SrcRegBank.getID()) {
538 // If we're doing a cross-bank copy on different-sized registers, we need
539 // to do a bit more work.
540 unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
541 unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
542
543 if (SrcSize > DstSize) {
544 // We're doing a cross-bank copy into a smaller register. We need a
545 // subregister copy. First, get a register class that's on the same bank
546 // as the destination, but the same size as the source.
547 const TargetRegisterClass *SubregRC =
548 getMinClassForRegBank(DstRegBank, SrcSize, true);
549 assert(SubregRC && "Didn't get a register class for subreg?");
550
551 // Get the appropriate subregister for the destination.
552 unsigned SubReg = 0;
553 if (!getSubRegForClass(DstRC, TRI, SubReg)) {
554 LLVM_DEBUG(dbgs() << "Couldn't determine subregister for copy.\n");
555 return false;
556 }
557
558 // Now, insert a subregister copy using the new register class.
559 selectSubregisterCopy(I, TII, MRI, RBI, SrcReg, SubregRC, DstRC,
560 SubReg);
561 return CheckCopy();
562 }
563
564 else if (DstRegBank.getID() == AArch64::GPRRegBankID && DstSize == 32 &&
565 SrcSize == 16) {
566 // Special case for FPR16 to GPR32.
567 // FIXME: This can probably be generalized like the above case.
568 unsigned PromoteReg =
569 MRI.createVirtualRegister(&AArch64::FPR32RegClass);
570 BuildMI(*I.getParent(), I, I.getDebugLoc(),
571 TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
572 .addImm(0)
573 .addUse(SrcReg)
574 .addImm(AArch64::hsub);
575 MachineOperand &RegOp = I.getOperand(1);
576 RegOp.setReg(PromoteReg);
577
578 // Promise that the copy is implicitly validated by the SUBREG_TO_REG.
579 KnownValid = true;
580 }
Amara Emerson7e9f3482018-02-18 17:10:49 +0000581 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000582
583 // If the destination is a physical register, then there's nothing to
584 // change, so we're done.
585 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
586 return CheckCopy();
Amara Emerson7e9f3482018-02-18 17:10:49 +0000587 }
588
Jessica Paquette245047d2019-01-24 22:00:41 +0000589 // No need to constrain SrcReg. It will get constrained when we hit another
590 // of its use or its defs. Copies do not have constraints.
591 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000592 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
593 << " operand\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000594 return false;
595 }
596 I.setDesc(TII.get(AArch64::COPY));
Jessica Paquette245047d2019-01-24 22:00:41 +0000597 return CheckCopy();
Quentin Colombetcb629a82016-10-12 03:57:49 +0000598}
599
Tim Northover69271c62016-10-12 22:49:11 +0000600static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
601 if (!DstTy.isScalar() || !SrcTy.isScalar())
602 return GenericOpc;
603
604 const unsigned DstSize = DstTy.getSizeInBits();
605 const unsigned SrcSize = SrcTy.getSizeInBits();
606
607 switch (DstSize) {
608 case 32:
609 switch (SrcSize) {
610 case 32:
611 switch (GenericOpc) {
612 case TargetOpcode::G_SITOFP:
613 return AArch64::SCVTFUWSri;
614 case TargetOpcode::G_UITOFP:
615 return AArch64::UCVTFUWSri;
616 case TargetOpcode::G_FPTOSI:
617 return AArch64::FCVTZSUWSr;
618 case TargetOpcode::G_FPTOUI:
619 return AArch64::FCVTZUUWSr;
620 default:
621 return GenericOpc;
622 }
623 case 64:
624 switch (GenericOpc) {
625 case TargetOpcode::G_SITOFP:
626 return AArch64::SCVTFUXSri;
627 case TargetOpcode::G_UITOFP:
628 return AArch64::UCVTFUXSri;
629 case TargetOpcode::G_FPTOSI:
630 return AArch64::FCVTZSUWDr;
631 case TargetOpcode::G_FPTOUI:
632 return AArch64::FCVTZUUWDr;
633 default:
634 return GenericOpc;
635 }
636 default:
637 return GenericOpc;
638 }
639 case 64:
640 switch (SrcSize) {
641 case 32:
642 switch (GenericOpc) {
643 case TargetOpcode::G_SITOFP:
644 return AArch64::SCVTFUWDri;
645 case TargetOpcode::G_UITOFP:
646 return AArch64::UCVTFUWDri;
647 case TargetOpcode::G_FPTOSI:
648 return AArch64::FCVTZSUXSr;
649 case TargetOpcode::G_FPTOUI:
650 return AArch64::FCVTZUUXSr;
651 default:
652 return GenericOpc;
653 }
654 case 64:
655 switch (GenericOpc) {
656 case TargetOpcode::G_SITOFP:
657 return AArch64::SCVTFUXDri;
658 case TargetOpcode::G_UITOFP:
659 return AArch64::UCVTFUXDri;
660 case TargetOpcode::G_FPTOSI:
661 return AArch64::FCVTZSUXDr;
662 case TargetOpcode::G_FPTOUI:
663 return AArch64::FCVTZUUXDr;
664 default:
665 return GenericOpc;
666 }
667 default:
668 return GenericOpc;
669 }
670 default:
671 return GenericOpc;
672 };
673 return GenericOpc;
674}
675
Tim Northover6c02ad52016-10-12 22:49:04 +0000676static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
677 switch (P) {
678 default:
679 llvm_unreachable("Unknown condition code!");
680 case CmpInst::ICMP_NE:
681 return AArch64CC::NE;
682 case CmpInst::ICMP_EQ:
683 return AArch64CC::EQ;
684 case CmpInst::ICMP_SGT:
685 return AArch64CC::GT;
686 case CmpInst::ICMP_SGE:
687 return AArch64CC::GE;
688 case CmpInst::ICMP_SLT:
689 return AArch64CC::LT;
690 case CmpInst::ICMP_SLE:
691 return AArch64CC::LE;
692 case CmpInst::ICMP_UGT:
693 return AArch64CC::HI;
694 case CmpInst::ICMP_UGE:
695 return AArch64CC::HS;
696 case CmpInst::ICMP_ULT:
697 return AArch64CC::LO;
698 case CmpInst::ICMP_ULE:
699 return AArch64CC::LS;
700 }
701}
702
Tim Northover7dd378d2016-10-12 22:49:07 +0000703static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
704 AArch64CC::CondCode &CondCode,
705 AArch64CC::CondCode &CondCode2) {
706 CondCode2 = AArch64CC::AL;
707 switch (P) {
708 default:
709 llvm_unreachable("Unknown FP condition!");
710 case CmpInst::FCMP_OEQ:
711 CondCode = AArch64CC::EQ;
712 break;
713 case CmpInst::FCMP_OGT:
714 CondCode = AArch64CC::GT;
715 break;
716 case CmpInst::FCMP_OGE:
717 CondCode = AArch64CC::GE;
718 break;
719 case CmpInst::FCMP_OLT:
720 CondCode = AArch64CC::MI;
721 break;
722 case CmpInst::FCMP_OLE:
723 CondCode = AArch64CC::LS;
724 break;
725 case CmpInst::FCMP_ONE:
726 CondCode = AArch64CC::MI;
727 CondCode2 = AArch64CC::GT;
728 break;
729 case CmpInst::FCMP_ORD:
730 CondCode = AArch64CC::VC;
731 break;
732 case CmpInst::FCMP_UNO:
733 CondCode = AArch64CC::VS;
734 break;
735 case CmpInst::FCMP_UEQ:
736 CondCode = AArch64CC::EQ;
737 CondCode2 = AArch64CC::VS;
738 break;
739 case CmpInst::FCMP_UGT:
740 CondCode = AArch64CC::HI;
741 break;
742 case CmpInst::FCMP_UGE:
743 CondCode = AArch64CC::PL;
744 break;
745 case CmpInst::FCMP_ULT:
746 CondCode = AArch64CC::LT;
747 break;
748 case CmpInst::FCMP_ULE:
749 CondCode = AArch64CC::LE;
750 break;
751 case CmpInst::FCMP_UNE:
752 CondCode = AArch64CC::NE;
753 break;
754 }
755}
756
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000757bool AArch64InstructionSelector::selectCompareBranch(
758 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
759
760 const unsigned CondReg = I.getOperand(0).getReg();
761 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
762 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
Aditya Nandakumar02c602e2017-07-31 17:00:16 +0000763 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC)
764 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg());
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000765 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
766 return false;
767
768 unsigned LHS = CCMI->getOperand(2).getReg();
769 unsigned RHS = CCMI->getOperand(3).getReg();
770 if (!getConstantVRegVal(RHS, MRI))
771 std::swap(RHS, LHS);
772
773 const auto RHSImm = getConstantVRegVal(RHS, MRI);
774 if (!RHSImm || *RHSImm != 0)
775 return false;
776
777 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
778 if (RB.getID() != AArch64::GPRRegBankID)
779 return false;
780
781 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
782 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
783 return false;
784
785 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
786 unsigned CBOpc = 0;
787 if (CmpWidth <= 32)
788 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
789 else if (CmpWidth == 64)
790 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
791 else
792 return false;
793
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +0000794 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
795 .addUse(LHS)
796 .addMBB(DestMBB)
797 .constrainAllUses(TII, TRI, RBI);
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000798
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000799 I.eraseFromParent();
800 return true;
801}
802
Tim Northovere9600d82017-02-08 17:57:27 +0000803bool AArch64InstructionSelector::selectVaStartAAPCS(
804 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
805 return false;
806}
807
808bool AArch64InstructionSelector::selectVaStartDarwin(
809 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
810 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
811 unsigned ListReg = I.getOperand(0).getReg();
812
813 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
814
815 auto MIB =
816 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri))
817 .addDef(ArgsAddrReg)
818 .addFrameIndex(FuncInfo->getVarArgsStackIndex())
819 .addImm(0)
820 .addImm(0);
821
822 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
823
824 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui))
825 .addUse(ArgsAddrReg)
826 .addUse(ListReg)
827 .addImm(0)
828 .addMemOperand(*I.memoperands_begin());
829
830 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
831 I.eraseFromParent();
832 return true;
833}
834
Amara Emerson1e8c1642018-07-31 00:09:02 +0000835void AArch64InstructionSelector::materializeLargeCMVal(
836 MachineInstr &I, const Value *V, unsigned char OpFlags) const {
837 MachineBasicBlock &MBB = *I.getParent();
838 MachineFunction &MF = *MBB.getParent();
839 MachineRegisterInfo &MRI = MF.getRegInfo();
840 MachineIRBuilder MIB(I);
841
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000842 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, {&AArch64::GPR64RegClass}, {});
Amara Emerson1e8c1642018-07-31 00:09:02 +0000843 MovZ->addOperand(MF, I.getOperand(1));
844 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 |
845 AArch64II::MO_NC);
846 MovZ->addOperand(MF, MachineOperand::CreateImm(0));
847 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI);
848
849 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, unsigned Offset,
850 unsigned ForceDstReg) {
851 unsigned DstReg = ForceDstReg
852 ? ForceDstReg
853 : MRI.createVirtualRegister(&AArch64::GPR64RegClass);
854 auto MovI = MIB.buildInstr(AArch64::MOVKXi).addDef(DstReg).addUse(SrcReg);
855 if (auto *GV = dyn_cast<GlobalValue>(V)) {
856 MovI->addOperand(MF, MachineOperand::CreateGA(
857 GV, MovZ->getOperand(1).getOffset(), Flags));
858 } else {
859 MovI->addOperand(
860 MF, MachineOperand::CreateBA(cast<BlockAddress>(V),
861 MovZ->getOperand(1).getOffset(), Flags));
862 }
863 MovI->addOperand(MF, MachineOperand::CreateImm(Offset));
864 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI);
865 return DstReg;
866 };
Aditya Nandakumarfef76192019-02-05 22:14:40 +0000867 unsigned DstReg = BuildMovK(MovZ.getReg(0),
Amara Emerson1e8c1642018-07-31 00:09:02 +0000868 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0);
869 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0);
870 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg());
871 return;
872}
873
Daniel Sandersf76f3152017-11-16 00:46:35 +0000874bool AArch64InstructionSelector::select(MachineInstr &I,
875 CodeGenCoverage &CoverageInfo) const {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000876 assert(I.getParent() && "Instruction should be in a basic block!");
877 assert(I.getParent()->getParent() && "Instruction should be in a function!");
878
879 MachineBasicBlock &MBB = *I.getParent();
880 MachineFunction &MF = *MBB.getParent();
881 MachineRegisterInfo &MRI = MF.getRegInfo();
882
Tim Northovercdf23f12016-10-31 18:30:59 +0000883 unsigned Opcode = I.getOpcode();
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000884 // G_PHI requires same handling as PHI
885 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
Tim Northovercdf23f12016-10-31 18:30:59 +0000886 // Certain non-generic instructions also need some special handling.
887
888 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
889 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000890
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000891 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
Tim Northover7d88da62016-11-08 00:34:06 +0000892 const unsigned DefReg = I.getOperand(0).getReg();
893 const LLT DefTy = MRI.getType(DefReg);
894
895 const TargetRegisterClass *DefRC = nullptr;
896 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
897 DefRC = TRI.getRegClass(DefReg);
898 } else {
899 const RegClassOrRegBank &RegClassOrBank =
900 MRI.getRegClassOrRegBank(DefReg);
901
902 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
903 if (!DefRC) {
904 if (!DefTy.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000905 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000906 return false;
907 }
908 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
909 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
910 if (!DefRC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000911 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000912 return false;
913 }
914 }
915 }
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000916 I.setDesc(TII.get(TargetOpcode::PHI));
Tim Northover7d88da62016-11-08 00:34:06 +0000917
918 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
919 }
920
921 if (I.isCopy())
Tim Northovercdf23f12016-10-31 18:30:59 +0000922 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000923
924 return true;
Tim Northovercdf23f12016-10-31 18:30:59 +0000925 }
926
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000927
928 if (I.getNumOperands() != I.getNumExplicitOperands()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000929 LLVM_DEBUG(
930 dbgs() << "Generic instruction has unexpected implicit operands\n");
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000931 return false;
932 }
933
Daniel Sandersf76f3152017-11-16 00:46:35 +0000934 if (selectImpl(I, CoverageInfo))
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000935 return true;
936
Tim Northover32a078a2016-09-15 10:09:59 +0000937 LLT Ty =
938 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000939
Tim Northover69271c62016-10-12 22:49:11 +0000940 switch (Opcode) {
Tim Northover5e3dbf32016-10-12 22:49:01 +0000941 case TargetOpcode::G_BRCOND: {
942 if (Ty.getSizeInBits() > 32) {
943 // We shouldn't need this on AArch64, but it would be implemented as an
944 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
945 // bit being tested is < 32.
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000946 LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
947 << ", expected at most 32-bits");
Tim Northover5e3dbf32016-10-12 22:49:01 +0000948 return false;
949 }
950
951 const unsigned CondReg = I.getOperand(0).getReg();
952 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
953
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000954 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
955 // instructions will not be produced, as they are conditional branch
956 // instructions that do not set flags.
957 bool ProduceNonFlagSettingCondBr =
958 !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening);
959 if (ProduceNonFlagSettingCondBr && selectCompareBranch(I, MF, MRI))
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000960 return true;
961
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000962 if (ProduceNonFlagSettingCondBr) {
963 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
964 .addUse(CondReg)
965 .addImm(/*bit offset=*/0)
966 .addMBB(DestMBB);
Tim Northover5e3dbf32016-10-12 22:49:01 +0000967
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000968 I.eraseFromParent();
969 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
970 } else {
971 auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
972 .addDef(AArch64::WZR)
973 .addUse(CondReg)
974 .addImm(1);
975 constrainSelectedInstRegOperands(*CMP.getInstr(), TII, TRI, RBI);
976 auto Bcc =
977 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::Bcc))
978 .addImm(AArch64CC::EQ)
979 .addMBB(DestMBB);
980
981 I.eraseFromParent();
982 return constrainSelectedInstRegOperands(*Bcc.getInstr(), TII, TRI, RBI);
983 }
Tim Northover5e3dbf32016-10-12 22:49:01 +0000984 }
985
Kristof Beyls65a12c02017-01-30 09:13:18 +0000986 case TargetOpcode::G_BRINDIRECT: {
987 I.setDesc(TII.get(AArch64::BR));
988 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
989 }
990
Tim Northover4494d692016-10-18 19:47:57 +0000991 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +0000992 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +0000993 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
994
995 const LLT s32 = LLT::scalar(32);
996 const LLT s64 = LLT::scalar(64);
997 const LLT p0 = LLT::pointer(0, 64);
998
999 const unsigned DefReg = I.getOperand(0).getReg();
1000 const LLT DefTy = MRI.getType(DefReg);
1001 const unsigned DefSize = DefTy.getSizeInBits();
1002 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1003
1004 // FIXME: Redundant check, but even less readable when factored out.
1005 if (isFP) {
1006 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001007 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1008 << " constant, expected: " << s32 << " or " << s64
1009 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001010 return false;
1011 }
1012
1013 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001014 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1015 << " constant on bank: " << RB
1016 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001017 return false;
1018 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00001019
1020 // The case when we have 0.0 is covered by tablegen. Reject it here so we
1021 // can be sure tablegen works correctly and isn't rescued by this code.
1022 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
1023 return false;
Tim Northover4494d692016-10-18 19:47:57 +00001024 } else {
Daniel Sanders05540042017-08-08 10:44:31 +00001025 // s32 and s64 are covered by tablegen.
1026 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001027 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1028 << " constant, expected: " << s32 << ", " << s64
1029 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001030 return false;
1031 }
1032
1033 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001034 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1035 << " constant on bank: " << RB
1036 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001037 return false;
1038 }
1039 }
1040
1041 const unsigned MovOpc =
1042 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
1043
1044 I.setDesc(TII.get(MovOpc));
1045
1046 if (isFP) {
1047 const TargetRegisterClass &GPRRC =
1048 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
1049 const TargetRegisterClass &FPRRC =
1050 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
1051
1052 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
1053 MachineOperand &RegOp = I.getOperand(0);
1054 RegOp.setReg(DefGPRReg);
1055
1056 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1057 TII.get(AArch64::COPY))
1058 .addDef(DefReg)
1059 .addUse(DefGPRReg);
1060
1061 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001062 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +00001063 return false;
1064 }
1065
1066 MachineOperand &ImmOp = I.getOperand(1);
1067 // FIXME: Is going through int64_t always correct?
1068 ImmOp.ChangeToImmediate(
1069 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001070 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +00001071 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
1072 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001073 } else if (I.getOperand(1).isImm()) {
1074 uint64_t Val = I.getOperand(1).getImm();
1075 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +00001076 }
1077
1078 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1079 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +00001080 }
Tim Northover7b6d66c2017-07-20 22:58:38 +00001081 case TargetOpcode::G_EXTRACT: {
1082 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001083 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +00001084 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +00001085 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001086 // Larger extracts are vectors, same-size extracts should be something else
1087 // by now (either split up or simplified to a COPY).
1088 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
1089 return false;
1090
Amara Emersonbc03bae2018-02-18 17:03:02 +00001091 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001092 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
1093 Ty.getSizeInBits() - 1);
1094
Amara Emersonbc03bae2018-02-18 17:03:02 +00001095 if (SrcSize < 64) {
1096 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
1097 "unexpected G_EXTRACT types");
1098 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1099 }
1100
Tim Northover7b6d66c2017-07-20 22:58:38 +00001101 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1102 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1103 TII.get(AArch64::COPY))
1104 .addDef(I.getOperand(0).getReg())
1105 .addUse(DstReg, 0, AArch64::sub_32);
1106 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
1107 AArch64::GPR32RegClass, MRI);
1108 I.getOperand(0).setReg(DstReg);
1109
1110 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1111 }
1112
1113 case TargetOpcode::G_INSERT: {
1114 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001115 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1116 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001117 // Larger inserts are vectors, same-size ones should be something else by
1118 // now (split up or turned into COPYs).
1119 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
1120 return false;
1121
Amara Emersonbc03bae2018-02-18 17:03:02 +00001122 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001123 unsigned LSB = I.getOperand(3).getImm();
1124 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +00001125 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +00001126 MachineInstrBuilder(MF, I).addImm(Width - 1);
1127
Amara Emersonbc03bae2018-02-18 17:03:02 +00001128 if (DstSize < 64) {
1129 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
1130 "unexpected G_INSERT types");
1131 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1132 }
1133
Tim Northover7b6d66c2017-07-20 22:58:38 +00001134 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1135 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
1136 TII.get(AArch64::SUBREG_TO_REG))
1137 .addDef(SrcReg)
1138 .addImm(0)
1139 .addUse(I.getOperand(2).getReg())
1140 .addImm(AArch64::sub_32);
1141 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
1142 AArch64::GPR32RegClass, MRI);
1143 I.getOperand(2).setReg(SrcReg);
1144
1145 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1146 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001147 case TargetOpcode::G_FRAME_INDEX: {
1148 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +00001149 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001150 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
1151 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001152 return false;
1153 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001154 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001155
1156 // MOs for a #0 shifted immediate.
1157 I.addOperand(MachineOperand::CreateImm(0));
1158 I.addOperand(MachineOperand::CreateImm(0));
1159
1160 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1161 }
Tim Northoverbdf16242016-10-10 21:50:00 +00001162
1163 case TargetOpcode::G_GLOBAL_VALUE: {
1164 auto GV = I.getOperand(1).getGlobal();
1165 if (GV->isThreadLocal()) {
1166 // FIXME: we don't support TLS yet.
1167 return false;
1168 }
1169 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001170 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +00001171 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001172 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001173 } else if (TM.getCodeModel() == CodeModel::Large) {
1174 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +00001175 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001176 I.eraseFromParent();
1177 return true;
David Green9dd1d452018-08-22 11:31:39 +00001178 } else if (TM.getCodeModel() == CodeModel::Tiny) {
1179 I.setDesc(TII.get(AArch64::ADR));
1180 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001181 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +00001182 I.setDesc(TII.get(AArch64::MOVaddr));
1183 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1184 MachineInstrBuilder MIB(MF, I);
1185 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1186 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1187 }
1188 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1189 }
1190
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001191 case TargetOpcode::G_LOAD:
1192 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001193 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001194
Tim Northover5ae83502016-09-15 09:20:34 +00001195 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001196 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1197 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001198 return false;
1199 }
1200
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001201 auto &MemOp = **I.memoperands_begin();
1202 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001203 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001204 return false;
1205 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001206 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001207
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001208 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001209#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001210 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001211 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001212 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1213 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001214 assert(MRI.getType(PtrReg).isPointer() &&
1215 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001216#endif
1217
1218 const unsigned ValReg = I.getOperand(0).getReg();
1219 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1220
1221 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001222 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001223 if (NewOpc == I.getOpcode())
1224 return false;
1225
1226 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001227
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001228 uint64_t Offset = 0;
1229 auto *PtrMI = MRI.getVRegDef(PtrReg);
1230
1231 // Try to fold a GEP into our unsigned immediate addressing mode.
1232 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1233 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1234 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001235 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001236 const unsigned Scale = Log2_32(Size);
1237 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1238 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1239 I.getOperand(1).setReg(Ptr2Reg);
1240 PtrMI = MRI.getVRegDef(Ptr2Reg);
1241 Offset = Imm / Size;
1242 }
1243 }
1244 }
1245
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001246 // If we haven't folded anything into our addressing mode yet, try to fold
1247 // a frame index into the base+offset.
1248 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1249 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1250
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001251 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001252
1253 // If we're storing a 0, use WZR/XZR.
1254 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1255 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1256 if (I.getOpcode() == AArch64::STRWui)
1257 I.getOperand(0).setReg(AArch64::WZR);
1258 else if (I.getOpcode() == AArch64::STRXui)
1259 I.getOperand(0).setReg(AArch64::XZR);
1260 }
1261 }
1262
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001263 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1264 }
1265
Tim Northover9dd78f82017-02-08 21:22:25 +00001266 case TargetOpcode::G_SMULH:
1267 case TargetOpcode::G_UMULH: {
1268 // Reject the various things we don't support yet.
1269 if (unsupportedBinOp(I, RBI, MRI, TRI))
1270 return false;
1271
1272 const unsigned DefReg = I.getOperand(0).getReg();
1273 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1274
1275 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001276 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001277 return false;
1278 }
1279
1280 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001281 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1282 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001283 return false;
1284 }
1285
1286 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1287 : AArch64::UMULHrr;
1288 I.setDesc(TII.get(NewOpc));
1289
1290 // Now that we selected an opcode, we need to constrain the register
1291 // operands to use appropriate classes.
1292 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1293 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001294 case TargetOpcode::G_FADD:
1295 case TargetOpcode::G_FSUB:
1296 case TargetOpcode::G_FMUL:
1297 case TargetOpcode::G_FDIV:
1298
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001299 case TargetOpcode::G_OR:
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001300 case TargetOpcode::G_SHL:
1301 case TargetOpcode::G_LSHR:
1302 case TargetOpcode::G_ASHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001303 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001304 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001305 if (unsupportedBinOp(I, RBI, MRI, TRI))
1306 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001307
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001308 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001309
1310 const unsigned DefReg = I.getOperand(0).getReg();
1311 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1312
1313 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1314 if (NewOpc == I.getOpcode())
1315 return false;
1316
1317 I.setDesc(TII.get(NewOpc));
1318 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001319
1320 // Now that we selected an opcode, we need to constrain the register
1321 // operands to use appropriate classes.
1322 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1323 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001324
Tim Northover398c5f52017-02-14 20:56:29 +00001325 case TargetOpcode::G_PTR_MASK: {
1326 uint64_t Align = I.getOperand(2).getImm();
1327 if (Align >= 64 || Align == 0)
1328 return false;
1329
1330 uint64_t Mask = ~((1ULL << Align) - 1);
1331 I.setDesc(TII.get(AArch64::ANDXri));
1332 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1333
1334 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1335 }
Tim Northover037af52c2016-10-31 18:31:09 +00001336 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001337 case TargetOpcode::G_TRUNC: {
1338 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1339 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1340
1341 const unsigned DstReg = I.getOperand(0).getReg();
1342 const unsigned SrcReg = I.getOperand(1).getReg();
1343
1344 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1345 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1346
1347 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001348 LLVM_DEBUG(
1349 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001350 return false;
1351 }
1352
1353 if (DstRB.getID() == AArch64::GPRRegBankID) {
1354 const TargetRegisterClass *DstRC =
1355 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1356 if (!DstRC)
1357 return false;
1358
1359 const TargetRegisterClass *SrcRC =
1360 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1361 if (!SrcRC)
1362 return false;
1363
1364 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1365 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001366 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001367 return false;
1368 }
1369
1370 if (DstRC == SrcRC) {
1371 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001372 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1373 SrcTy == LLT::scalar(64)) {
1374 llvm_unreachable("TableGen can import this case");
1375 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001376 } else if (DstRC == &AArch64::GPR32RegClass &&
1377 SrcRC == &AArch64::GPR64RegClass) {
1378 I.getOperand(1).setSubReg(AArch64::sub_32);
1379 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001380 LLVM_DEBUG(
1381 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001382 return false;
1383 }
1384
1385 I.setDesc(TII.get(TargetOpcode::COPY));
1386 return true;
1387 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1388 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1389 I.setDesc(TII.get(AArch64::XTNv4i16));
1390 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1391 return true;
1392 }
1393 }
1394
1395 return false;
1396 }
1397
Tim Northover3d38b3a2016-10-11 20:50:21 +00001398 case TargetOpcode::G_ANYEXT: {
1399 const unsigned DstReg = I.getOperand(0).getReg();
1400 const unsigned SrcReg = I.getOperand(1).getReg();
1401
Quentin Colombetcb629a82016-10-12 03:57:49 +00001402 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1403 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001404 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1405 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001406 return false;
1407 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001408
Quentin Colombetcb629a82016-10-12 03:57:49 +00001409 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1410 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001411 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1412 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001413 return false;
1414 }
1415
1416 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1417
1418 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001419 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001420 return false;
1421 }
1422
Quentin Colombetcb629a82016-10-12 03:57:49 +00001423 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001424 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1425 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001426 return false;
1427 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001428 // At this point G_ANYEXT is just like a plain COPY, but we need
1429 // to explicitly form the 64-bit value if any.
1430 if (DstSize > 32) {
1431 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1432 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1433 .addDef(ExtSrc)
1434 .addImm(0)
1435 .addUse(SrcReg)
1436 .addImm(AArch64::sub_32);
1437 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001438 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001439 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001440 }
1441
1442 case TargetOpcode::G_ZEXT:
1443 case TargetOpcode::G_SEXT: {
1444 unsigned Opcode = I.getOpcode();
1445 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1446 SrcTy = MRI.getType(I.getOperand(1).getReg());
1447 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1448 const unsigned DefReg = I.getOperand(0).getReg();
1449 const unsigned SrcReg = I.getOperand(1).getReg();
1450 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1451
1452 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001453 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1454 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001455 return false;
1456 }
1457
1458 MachineInstr *ExtI;
1459 if (DstTy == LLT::scalar(64)) {
1460 // FIXME: Can we avoid manually doing this?
1461 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001462 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1463 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001464 return false;
1465 }
1466
1467 const unsigned SrcXReg =
1468 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1469 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1470 .addDef(SrcXReg)
1471 .addImm(0)
1472 .addUse(SrcReg)
1473 .addImm(AArch64::sub_32);
1474
1475 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1476 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1477 .addDef(DefReg)
1478 .addUse(SrcXReg)
1479 .addImm(0)
1480 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001481 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001482 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1483 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1484 .addDef(DefReg)
1485 .addUse(SrcReg)
1486 .addImm(0)
1487 .addImm(SrcTy.getSizeInBits() - 1);
1488 } else {
1489 return false;
1490 }
1491
1492 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1493
1494 I.eraseFromParent();
1495 return true;
1496 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001497
Tim Northover69271c62016-10-12 22:49:11 +00001498 case TargetOpcode::G_SITOFP:
1499 case TargetOpcode::G_UITOFP:
1500 case TargetOpcode::G_FPTOSI:
1501 case TargetOpcode::G_FPTOUI: {
1502 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1503 SrcTy = MRI.getType(I.getOperand(1).getReg());
1504 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1505 if (NewOpc == Opcode)
1506 return false;
1507
1508 I.setDesc(TII.get(NewOpc));
1509 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1510
1511 return true;
1512 }
1513
1514
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001515 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001516 // The importer is currently unable to import pointer types since they
1517 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001518 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001519
Daniel Sandersedd07842017-08-17 09:26:14 +00001520 case TargetOpcode::G_BITCAST:
1521 // Imported SelectionDAG rules can handle every bitcast except those that
1522 // bitcast from a type to the same type. Ideally, these shouldn't occur
1523 // but we might not run an optimizer that deletes them.
1524 if (MRI.getType(I.getOperand(0).getReg()) ==
1525 MRI.getType(I.getOperand(1).getReg()))
1526 return selectCopy(I, TII, MRI, TRI, RBI);
1527 return false;
1528
Tim Northover9ac0eba2016-11-08 00:45:29 +00001529 case TargetOpcode::G_SELECT: {
1530 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001531 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1532 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001533 return false;
1534 }
1535
1536 const unsigned CondReg = I.getOperand(1).getReg();
1537 const unsigned TReg = I.getOperand(2).getReg();
1538 const unsigned FReg = I.getOperand(3).getReg();
1539
1540 unsigned CSelOpc = 0;
1541
1542 if (Ty == LLT::scalar(32)) {
1543 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001544 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001545 CSelOpc = AArch64::CSELXr;
1546 } else {
1547 return false;
1548 }
1549
1550 MachineInstr &TstMI =
1551 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1552 .addDef(AArch64::WZR)
1553 .addUse(CondReg)
1554 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1555
1556 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1557 .addDef(I.getOperand(0).getReg())
1558 .addUse(TReg)
1559 .addUse(FReg)
1560 .addImm(AArch64CC::NE);
1561
1562 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1563 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1564
1565 I.eraseFromParent();
1566 return true;
1567 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001568 case TargetOpcode::G_ICMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001569 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001570 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1571 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001572 return false;
1573 }
1574
1575 unsigned CmpOpc = 0;
1576 unsigned ZReg = 0;
1577
1578 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1579 if (CmpTy == LLT::scalar(32)) {
1580 CmpOpc = AArch64::SUBSWrr;
1581 ZReg = AArch64::WZR;
1582 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1583 CmpOpc = AArch64::SUBSXrr;
1584 ZReg = AArch64::XZR;
1585 } else {
1586 return false;
1587 }
1588
Kristof Beyls22524402017-01-05 10:16:08 +00001589 // CSINC increments the result by one when the condition code is false.
1590 // Therefore, we have to invert the predicate to get an increment by 1 when
1591 // the predicate is true.
1592 const AArch64CC::CondCode invCC =
1593 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1594 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001595
1596 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1597 .addDef(ZReg)
1598 .addUse(I.getOperand(2).getReg())
1599 .addUse(I.getOperand(3).getReg());
1600
1601 MachineInstr &CSetMI =
1602 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1603 .addDef(I.getOperand(0).getReg())
1604 .addUse(AArch64::WZR)
1605 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001606 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001607
1608 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1609 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1610
1611 I.eraseFromParent();
1612 return true;
1613 }
1614
Tim Northover7dd378d2016-10-12 22:49:07 +00001615 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001616 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001617 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1618 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001619 return false;
1620 }
1621
1622 unsigned CmpOpc = 0;
1623 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1624 if (CmpTy == LLT::scalar(32)) {
1625 CmpOpc = AArch64::FCMPSrr;
1626 } else if (CmpTy == LLT::scalar(64)) {
1627 CmpOpc = AArch64::FCMPDrr;
1628 } else {
1629 return false;
1630 }
1631
1632 // FIXME: regbank
1633
1634 AArch64CC::CondCode CC1, CC2;
1635 changeFCMPPredToAArch64CC(
1636 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1637
1638 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1639 .addUse(I.getOperand(2).getReg())
1640 .addUse(I.getOperand(3).getReg());
1641
1642 const unsigned DefReg = I.getOperand(0).getReg();
1643 unsigned Def1Reg = DefReg;
1644 if (CC2 != AArch64CC::AL)
1645 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1646
1647 MachineInstr &CSetMI =
1648 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1649 .addDef(Def1Reg)
1650 .addUse(AArch64::WZR)
1651 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001652 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001653
1654 if (CC2 != AArch64CC::AL) {
1655 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1656 MachineInstr &CSet2MI =
1657 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1658 .addDef(Def2Reg)
1659 .addUse(AArch64::WZR)
1660 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001661 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001662 MachineInstr &OrMI =
1663 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1664 .addDef(DefReg)
1665 .addUse(Def1Reg)
1666 .addUse(Def2Reg);
1667 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1668 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1669 }
1670
1671 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1672 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1673
1674 I.eraseFromParent();
1675 return true;
1676 }
Tim Northovere9600d82017-02-08 17:57:27 +00001677 case TargetOpcode::G_VASTART:
1678 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1679 : selectVaStartAAPCS(I, MF, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001680 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1681 if (!I.getOperand(0).isIntrinsicID())
1682 return false;
1683 if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1684 return false;
1685 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::BRK))
1686 .addImm(1);
1687 I.eraseFromParent();
1688 return true;
Amara Emerson1e8c1642018-07-31 00:09:02 +00001689 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001690 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001691 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1692 const unsigned DstReg = I.getOperand(0).getReg();
1693 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1694 const TargetRegisterClass *DstRC =
1695 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1696 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001697 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001698 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001699 case TargetOpcode::G_BLOCK_ADDR: {
1700 if (TM.getCodeModel() == CodeModel::Large) {
1701 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1702 I.eraseFromParent();
1703 return true;
1704 } else {
1705 I.setDesc(TII.get(AArch64::MOVaddrBA));
1706 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1707 I.getOperand(0).getReg())
1708 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1709 /* Offset */ 0, AArch64II::MO_PAGE)
1710 .addBlockAddress(
1711 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1712 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1713 I.eraseFromParent();
1714 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1715 }
1716 }
Amara Emerson5ec14602018-12-10 18:44:58 +00001717 case TargetOpcode::G_BUILD_VECTOR:
1718 return selectBuildVector(I, MRI);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001719 case TargetOpcode::G_MERGE_VALUES:
1720 return selectMergeValues(I, MRI);
Jessica Paquette245047d2019-01-24 22:00:41 +00001721 case TargetOpcode::G_UNMERGE_VALUES:
1722 return selectUnmergeValues(I, MRI);
Amara Emerson1abe05c2019-02-21 20:20:16 +00001723 case TargetOpcode::G_SHUFFLE_VECTOR:
1724 return selectShuffleVector(I, MRI);
Jessica Paquette607774c2019-03-11 22:18:01 +00001725 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
1726 return selectExtractElt(I, MRI);
Jessica Paquette5aff1f42019-03-14 18:01:30 +00001727 case TargetOpcode::G_INSERT_VECTOR_ELT:
1728 return selectInsertElt(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001729 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001730
1731 return false;
1732}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001733
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001734MachineInstr *AArch64InstructionSelector::emitScalarToVector(
Amara Emerson8acb0d92019-03-04 19:16:00 +00001735 unsigned EltSize, const TargetRegisterClass *DstRC, unsigned Scalar,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001736 MachineIRBuilder &MIRBuilder) const {
1737 auto Undef = MIRBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF, {DstRC}, {});
Amara Emerson5ec14602018-12-10 18:44:58 +00001738
1739 auto BuildFn = [&](unsigned SubregIndex) {
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001740 auto Ins =
1741 MIRBuilder
1742 .buildInstr(TargetOpcode::INSERT_SUBREG, {DstRC}, {Undef, Scalar})
1743 .addImm(SubregIndex);
1744 constrainSelectedInstRegOperands(*Undef, TII, TRI, RBI);
1745 constrainSelectedInstRegOperands(*Ins, TII, TRI, RBI);
1746 return &*Ins;
Amara Emerson5ec14602018-12-10 18:44:58 +00001747 };
1748
Amara Emerson8acb0d92019-03-04 19:16:00 +00001749 switch (EltSize) {
Jessica Paquette245047d2019-01-24 22:00:41 +00001750 case 16:
1751 return BuildFn(AArch64::hsub);
Amara Emerson5ec14602018-12-10 18:44:58 +00001752 case 32:
1753 return BuildFn(AArch64::ssub);
1754 case 64:
1755 return BuildFn(AArch64::dsub);
1756 default:
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001757 return nullptr;
Amara Emerson5ec14602018-12-10 18:44:58 +00001758 }
1759}
1760
Amara Emerson8cb186c2018-12-20 01:11:04 +00001761bool AArch64InstructionSelector::selectMergeValues(
1762 MachineInstr &I, MachineRegisterInfo &MRI) const {
1763 assert(I.getOpcode() == TargetOpcode::G_MERGE_VALUES && "unexpected opcode");
1764 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1765 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1766 assert(!DstTy.isVector() && !SrcTy.isVector() && "invalid merge operation");
1767
1768 // At the moment we only support merging two s32s into an s64.
1769 if (I.getNumOperands() != 3)
1770 return false;
1771 if (DstTy.getSizeInBits() != 64 || SrcTy.getSizeInBits() != 32)
1772 return false;
1773 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1774 if (RB.getID() != AArch64::GPRRegBankID)
1775 return false;
1776
1777 auto *DstRC = &AArch64::GPR64RegClass;
1778 unsigned SubToRegDef = MRI.createVirtualRegister(DstRC);
1779 MachineInstr &SubRegMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1780 TII.get(TargetOpcode::SUBREG_TO_REG))
1781 .addDef(SubToRegDef)
1782 .addImm(0)
1783 .addUse(I.getOperand(1).getReg())
1784 .addImm(AArch64::sub_32);
1785 unsigned SubToRegDef2 = MRI.createVirtualRegister(DstRC);
1786 // Need to anyext the second scalar before we can use bfm
1787 MachineInstr &SubRegMI2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1788 TII.get(TargetOpcode::SUBREG_TO_REG))
1789 .addDef(SubToRegDef2)
1790 .addImm(0)
1791 .addUse(I.getOperand(2).getReg())
1792 .addImm(AArch64::sub_32);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001793 MachineInstr &BFM =
1794 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::BFMXri))
Amara Emerson321bfb22018-12-20 03:27:42 +00001795 .addDef(I.getOperand(0).getReg())
Amara Emerson8cb186c2018-12-20 01:11:04 +00001796 .addUse(SubToRegDef)
1797 .addUse(SubToRegDef2)
1798 .addImm(32)
1799 .addImm(31);
1800 constrainSelectedInstRegOperands(SubRegMI, TII, TRI, RBI);
1801 constrainSelectedInstRegOperands(SubRegMI2, TII, TRI, RBI);
1802 constrainSelectedInstRegOperands(BFM, TII, TRI, RBI);
1803 I.eraseFromParent();
1804 return true;
1805}
1806
Jessica Paquette607774c2019-03-11 22:18:01 +00001807static bool getLaneCopyOpcode(unsigned &CopyOpc, unsigned &ExtractSubReg,
1808 const unsigned EltSize) {
1809 // Choose a lane copy opcode and subregister based off of the size of the
1810 // vector's elements.
1811 switch (EltSize) {
1812 case 16:
1813 CopyOpc = AArch64::CPYi16;
1814 ExtractSubReg = AArch64::hsub;
1815 break;
1816 case 32:
1817 CopyOpc = AArch64::CPYi32;
1818 ExtractSubReg = AArch64::ssub;
1819 break;
1820 case 64:
1821 CopyOpc = AArch64::CPYi64;
1822 ExtractSubReg = AArch64::dsub;
1823 break;
1824 default:
1825 // Unknown size, bail out.
1826 LLVM_DEBUG(dbgs() << "Elt size '" << EltSize << "' unsupported.\n");
1827 return false;
1828 }
1829 return true;
1830}
1831
Jessica Paquettebb1aced2019-03-13 21:19:29 +00001832/// Given a register \p Reg, find the value of a constant defining \p Reg.
1833/// Return true if one could be found, and store it in \p Val. Return false
1834/// otherwise.
1835static bool getConstantValueForReg(unsigned Reg, MachineRegisterInfo &MRI,
1836 unsigned &Val) {
1837 // Look at the def of the register.
1838 MachineInstr *Def = MRI.getVRegDef(Reg);
1839 if (!Def)
1840 return false;
1841
1842 // Find the first definition which isn't a copy.
1843 if (Def->isCopy()) {
1844 Reg = Def->getOperand(1).getReg();
1845 auto It = find_if_not(MRI.reg_nodbg_instructions(Reg),
1846 [](const MachineInstr &MI) { return MI.isCopy(); });
1847 if (It == MRI.reg_instr_nodbg_end()) {
1848 LLVM_DEBUG(dbgs() << "Couldn't find non-copy def for register\n");
1849 return false;
1850 }
1851 Def = &*It;
1852 }
1853
1854 // TODO: Handle opcodes other than G_CONSTANT.
1855 if (Def->getOpcode() != TargetOpcode::G_CONSTANT) {
1856 LLVM_DEBUG(dbgs() << "VRegs defined by anything other than G_CONSTANT "
1857 "currently unsupported.\n");
1858 return false;
1859 }
1860
1861 // Return the constant value associated with the operand.
1862 Val = Def->getOperand(1).getCImm()->getLimitedValue();
1863 return true;
1864}
1865
Jessica Paquette607774c2019-03-11 22:18:01 +00001866bool AArch64InstructionSelector::selectExtractElt(
1867 MachineInstr &I, MachineRegisterInfo &MRI) const {
1868 assert(I.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT &&
1869 "unexpected opcode!");
1870 unsigned DstReg = I.getOperand(0).getReg();
1871 const LLT NarrowTy = MRI.getType(DstReg);
1872 const unsigned SrcReg = I.getOperand(1).getReg();
1873 const LLT WideTy = MRI.getType(SrcReg);
1874
1875 assert(WideTy.getSizeInBits() >= NarrowTy.getSizeInBits() &&
1876 "source register size too small!");
1877 assert(NarrowTy.isScalar() && "cannot extract vector into vector!");
1878
1879 // Need the lane index to determine the correct copy opcode.
1880 MachineOperand &LaneIdxOp = I.getOperand(2);
1881 assert(LaneIdxOp.isReg() && "Lane index operand was not a register?");
1882
1883 if (RBI.getRegBank(DstReg, MRI, TRI)->getID() != AArch64::FPRRegBankID) {
1884 LLVM_DEBUG(dbgs() << "Cannot extract into GPR.\n");
1885 return false;
1886 }
1887
Jessica Paquettebb1aced2019-03-13 21:19:29 +00001888 // Find the index to extract from.
1889 unsigned LaneIdx = 0;
1890 if (!getConstantValueForReg(LaneIdxOp.getReg(), MRI, LaneIdx))
Jessica Paquette607774c2019-03-11 22:18:01 +00001891 return false;
Jessica Paquette607774c2019-03-11 22:18:01 +00001892
Jessica Paquette607774c2019-03-11 22:18:01 +00001893 unsigned CopyOpc = 0;
1894 unsigned ExtractSubReg = 0;
1895 if (!getLaneCopyOpcode(CopyOpc, ExtractSubReg, NarrowTy.getSizeInBits())) {
1896 LLVM_DEBUG(
1897 dbgs() << "Couldn't determine lane copy opcode for instruction.\n");
1898 return false;
1899 }
1900
1901 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1902 const TargetRegisterClass *DstRC =
1903 getRegClassForTypeOnBank(NarrowTy, DstRB, RBI, true);
1904 if (!DstRC) {
1905 LLVM_DEBUG(dbgs() << "Could not determine destination register class.\n");
1906 return false;
1907 }
1908
1909 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1910 const TargetRegisterClass *SrcRC =
1911 getRegClassForTypeOnBank(WideTy, SrcRB, RBI, true);
1912 if (!SrcRC) {
1913 LLVM_DEBUG(dbgs() << "Could not determine source register class.\n");
1914 return false;
1915 }
1916
1917 // The register that we're going to copy into.
1918 unsigned InsertReg = SrcReg;
1919 MachineIRBuilder MIRBuilder(I);
1920
1921 // If the lane index is 0, we just use a subregister COPY.
1922 if (LaneIdx == 0) {
1923 unsigned CopyTo = I.getOperand(0).getReg();
1924 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1925 CopyTo)
1926 .addUse(SrcReg, 0, ExtractSubReg);
1927 RBI.constrainGenericRegister(CopyTo, *DstRC, MRI);
1928 I.eraseFromParent();
1929 return true;
1930 }
1931
1932 // Lane copies require 128-bit wide registers. If we're dealing with an
1933 // unpacked vector, then we need to move up to that width. Insert an implicit
1934 // def and a subregister insert to get us there.
1935 if (WideTy.getSizeInBits() != 128) {
1936 MachineInstr *ScalarToVector = emitScalarToVector(
1937 WideTy.getSizeInBits(), &AArch64::FPR128RegClass, SrcReg, MIRBuilder);
1938 if (!ScalarToVector)
1939 return false;
1940 InsertReg = ScalarToVector->getOperand(0).getReg();
1941 }
1942
1943 MachineInstr *LaneCopyMI =
1944 MIRBuilder.buildInstr(CopyOpc, {DstReg}, {InsertReg}).addImm(LaneIdx);
1945 constrainSelectedInstRegOperands(*LaneCopyMI, TII, TRI, RBI);
1946
1947 // Make sure that we actually constrain the initial copy.
1948 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
1949
1950 I.eraseFromParent();
1951 return true;
1952}
1953
Jessica Paquette245047d2019-01-24 22:00:41 +00001954bool AArch64InstructionSelector::selectUnmergeValues(
1955 MachineInstr &I, MachineRegisterInfo &MRI) const {
1956 assert(I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
1957 "unexpected opcode");
1958
1959 // TODO: Handle unmerging into GPRs and from scalars to scalars.
1960 if (RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI)->getID() !=
1961 AArch64::FPRRegBankID ||
1962 RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI)->getID() !=
1963 AArch64::FPRRegBankID) {
1964 LLVM_DEBUG(dbgs() << "Unmerging vector-to-gpr and scalar-to-scalar "
1965 "currently unsupported.\n");
1966 return false;
1967 }
1968
1969 // The last operand is the vector source register, and every other operand is
1970 // a register to unpack into.
1971 unsigned NumElts = I.getNumOperands() - 1;
1972 unsigned SrcReg = I.getOperand(NumElts).getReg();
1973 const LLT NarrowTy = MRI.getType(I.getOperand(0).getReg());
1974 const LLT WideTy = MRI.getType(SrcReg);
Benjamin Kramer653020d2019-01-24 23:45:07 +00001975 (void)WideTy;
Jessica Paquette245047d2019-01-24 22:00:41 +00001976 assert(WideTy.isVector() && "can only unmerge from vector types!");
1977 assert(WideTy.getSizeInBits() > NarrowTy.getSizeInBits() &&
1978 "source register size too small!");
1979
Jessica Paquette1f9bc282019-01-25 21:28:27 +00001980 // TODO: Handle unmerging into vectors.
Jessica Paquette245047d2019-01-24 22:00:41 +00001981 if (!NarrowTy.isScalar()) {
1982 LLVM_DEBUG(dbgs() << "Vector-to-vector unmerges not supported yet.\n");
1983 return false;
1984 }
1985
1986 // Choose a lane copy opcode and subregister based off of the size of the
1987 // vector's elements.
1988 unsigned CopyOpc = 0;
1989 unsigned ExtractSubReg = 0;
Jessica Paquette607774c2019-03-11 22:18:01 +00001990 if (!getLaneCopyOpcode(CopyOpc, ExtractSubReg, NarrowTy.getSizeInBits()))
Jessica Paquette245047d2019-01-24 22:00:41 +00001991 return false;
Jessica Paquette245047d2019-01-24 22:00:41 +00001992
1993 // Set up for the lane copies.
1994 MachineBasicBlock &MBB = *I.getParent();
1995
1996 // Stores the registers we'll be copying from.
1997 SmallVector<unsigned, 4> InsertRegs;
1998
1999 // We'll use the first register twice, so we only need NumElts-1 registers.
2000 unsigned NumInsertRegs = NumElts - 1;
2001
2002 // If our elements fit into exactly 128 bits, then we can copy from the source
2003 // directly. Otherwise, we need to do a bit of setup with some subregister
2004 // inserts.
2005 if (NarrowTy.getSizeInBits() * NumElts == 128) {
2006 InsertRegs = SmallVector<unsigned, 4>(NumInsertRegs, SrcReg);
2007 } else {
2008 // No. We have to perform subregister inserts. For each insert, create an
2009 // implicit def and a subregister insert, and save the register we create.
2010 for (unsigned Idx = 0; Idx < NumInsertRegs; ++Idx) {
2011 unsigned ImpDefReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
2012 MachineInstr &ImpDefMI =
2013 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
2014 ImpDefReg);
2015
2016 // Now, create the subregister insert from SrcReg.
2017 unsigned InsertReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
2018 MachineInstr &InsMI =
2019 *BuildMI(MBB, I, I.getDebugLoc(),
2020 TII.get(TargetOpcode::INSERT_SUBREG), InsertReg)
2021 .addUse(ImpDefReg)
2022 .addUse(SrcReg)
2023 .addImm(AArch64::dsub);
2024
2025 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
2026 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
2027
2028 // Save the register so that we can copy from it after.
2029 InsertRegs.push_back(InsertReg);
2030 }
2031 }
2032
2033 // Now that we've created any necessary subregister inserts, we can
2034 // create the copies.
2035 //
2036 // Perform the first copy separately as a subregister copy.
2037 unsigned CopyTo = I.getOperand(0).getReg();
2038 MachineInstr &FirstCopy =
2039 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), CopyTo)
2040 .addUse(InsertRegs[0], 0, ExtractSubReg);
2041 constrainSelectedInstRegOperands(FirstCopy, TII, TRI, RBI);
2042
2043 // Now, perform the remaining copies as vector lane copies.
2044 unsigned LaneIdx = 1;
2045 for (unsigned InsReg : InsertRegs) {
2046 unsigned CopyTo = I.getOperand(LaneIdx).getReg();
2047 MachineInstr &CopyInst =
2048 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CopyOpc), CopyTo)
2049 .addUse(InsReg)
2050 .addImm(LaneIdx);
2051 constrainSelectedInstRegOperands(CopyInst, TII, TRI, RBI);
2052 ++LaneIdx;
2053 }
2054
2055 // Separately constrain the first copy's destination. Because of the
2056 // limitation in constrainOperandRegClass, we can't guarantee that this will
2057 // actually be constrained. So, do it ourselves using the second operand.
2058 const TargetRegisterClass *RC =
2059 MRI.getRegClassOrNull(I.getOperand(1).getReg());
2060 if (!RC) {
2061 LLVM_DEBUG(dbgs() << "Couldn't constrain copy destination.\n");
2062 return false;
2063 }
2064
2065 RBI.constrainGenericRegister(CopyTo, *RC, MRI);
2066 I.eraseFromParent();
2067 return true;
2068}
2069
Amara Emerson1abe05c2019-02-21 20:20:16 +00002070void AArch64InstructionSelector::collectShuffleMaskIndices(
2071 MachineInstr &I, MachineRegisterInfo &MRI,
2072 SmallVectorImpl<int> &Idxs) const {
2073 MachineInstr *MaskDef = MRI.getVRegDef(I.getOperand(3).getReg());
2074 assert(
2075 MaskDef->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&
2076 "G_SHUFFLE_VECTOR should have a constant mask operand as G_BUILD_VECTOR");
2077 // Find the constant indices.
2078 for (unsigned i = 1, e = MaskDef->getNumOperands(); i < e; ++i) {
2079 MachineInstr *ScalarDef = MRI.getVRegDef(MaskDef->getOperand(i).getReg());
2080 assert(ScalarDef && "Could not find vreg def of shufflevec index op");
2081 // Look through copies.
2082 while (ScalarDef->getOpcode() == TargetOpcode::COPY) {
2083 ScalarDef = MRI.getVRegDef(ScalarDef->getOperand(1).getReg());
2084 assert(ScalarDef && "Could not find def of copy operand");
2085 }
2086 assert(ScalarDef->getOpcode() == TargetOpcode::G_CONSTANT);
2087 Idxs.push_back(ScalarDef->getOperand(1).getCImm()->getSExtValue());
2088 }
2089}
2090
2091unsigned
2092AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
2093 MachineFunction &MF) const {
2094 Type *CPTy = CPVal->getType()->getPointerTo();
2095 unsigned Align = MF.getDataLayout().getPrefTypeAlignment(CPTy);
2096 if (Align == 0)
2097 Align = MF.getDataLayout().getTypeAllocSize(CPTy);
2098
2099 MachineConstantPool *MCP = MF.getConstantPool();
2100 return MCP->getConstantPoolIndex(CPVal, Align);
2101}
2102
2103MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
2104 Constant *CPVal, MachineIRBuilder &MIRBuilder) const {
2105 unsigned CPIdx = emitConstantPoolEntry(CPVal, MIRBuilder.getMF());
2106
2107 auto Adrp =
2108 MIRBuilder.buildInstr(AArch64::ADRP, {&AArch64::GPR64RegClass}, {})
2109 .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002110
2111 MachineInstr *LoadMI = nullptr;
2112 switch (MIRBuilder.getDataLayout().getTypeStoreSize(CPVal->getType())) {
2113 case 16:
2114 LoadMI =
2115 &*MIRBuilder
2116 .buildInstr(AArch64::LDRQui, {&AArch64::FPR128RegClass}, {Adrp})
2117 .addConstantPoolIndex(CPIdx, 0,
2118 AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2119 break;
2120 case 8:
2121 LoadMI = &*MIRBuilder
2122 .buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp})
2123 .addConstantPoolIndex(
2124 CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2125 break;
2126 default:
2127 LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
2128 << *CPVal->getType());
2129 return nullptr;
2130 }
Amara Emerson1abe05c2019-02-21 20:20:16 +00002131 constrainSelectedInstRegOperands(*Adrp, TII, TRI, RBI);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002132 constrainSelectedInstRegOperands(*LoadMI, TII, TRI, RBI);
2133 return LoadMI;
2134}
2135
2136/// Return an <Opcode, SubregIndex> pair to do an vector elt insert of a given
2137/// size and RB.
2138static std::pair<unsigned, unsigned>
2139getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
2140 unsigned Opc, SubregIdx;
2141 if (RB.getID() == AArch64::GPRRegBankID) {
2142 if (EltSize == 32) {
2143 Opc = AArch64::INSvi32gpr;
2144 SubregIdx = AArch64::ssub;
2145 } else if (EltSize == 64) {
2146 Opc = AArch64::INSvi64gpr;
2147 SubregIdx = AArch64::dsub;
2148 } else {
2149 llvm_unreachable("invalid elt size!");
2150 }
2151 } else {
2152 if (EltSize == 8) {
2153 Opc = AArch64::INSvi8lane;
2154 SubregIdx = AArch64::bsub;
2155 } else if (EltSize == 16) {
2156 Opc = AArch64::INSvi16lane;
2157 SubregIdx = AArch64::hsub;
2158 } else if (EltSize == 32) {
2159 Opc = AArch64::INSvi32lane;
2160 SubregIdx = AArch64::ssub;
2161 } else if (EltSize == 64) {
2162 Opc = AArch64::INSvi64lane;
2163 SubregIdx = AArch64::dsub;
2164 } else {
2165 llvm_unreachable("invalid elt size!");
2166 }
2167 }
2168 return std::make_pair(Opc, SubregIdx);
2169}
2170
2171MachineInstr *AArch64InstructionSelector::emitVectorConcat(
2172 unsigned Op1, unsigned Op2, MachineIRBuilder &MIRBuilder) const {
2173 // We implement a vector concat by:
2174 // 1. Use scalar_to_vector to insert the lower vector into the larger dest
2175 // 2. Insert the upper vector into the destination's upper element
2176 // TODO: some of this code is common with G_BUILD_VECTOR handling.
2177 MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
2178
2179 const LLT Op1Ty = MRI.getType(Op1);
2180 const LLT Op2Ty = MRI.getType(Op2);
2181
2182 if (Op1Ty != Op2Ty) {
2183 LLVM_DEBUG(dbgs() << "Could not do vector concat of differing vector tys");
2184 return nullptr;
2185 }
2186 assert(Op1Ty.isVector() && "Expected a vector for vector concat");
2187
2188 if (Op1Ty.getSizeInBits() >= 128) {
2189 LLVM_DEBUG(dbgs() << "Vector concat not supported for full size vectors");
2190 return nullptr;
2191 }
2192
2193 // At the moment we just support 64 bit vector concats.
2194 if (Op1Ty.getSizeInBits() != 64) {
2195 LLVM_DEBUG(dbgs() << "Vector concat supported for 64b vectors");
2196 return nullptr;
2197 }
2198
2199 const LLT ScalarTy = LLT::scalar(Op1Ty.getSizeInBits());
2200 const RegisterBank &FPRBank = *RBI.getRegBank(Op1, MRI, TRI);
2201 const TargetRegisterClass *DstRC =
2202 getMinClassForRegBank(FPRBank, Op1Ty.getSizeInBits() * 2);
2203
2204 MachineInstr *WidenedOp1 =
2205 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op1, MIRBuilder);
2206 MachineInstr *WidenedOp2 =
2207 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op2, MIRBuilder);
2208 if (!WidenedOp1 || !WidenedOp2) {
2209 LLVM_DEBUG(dbgs() << "Could not emit a vector from scalar value");
2210 return nullptr;
2211 }
2212
2213 // Now do the insert of the upper element.
2214 unsigned InsertOpc, InsSubRegIdx;
2215 std::tie(InsertOpc, InsSubRegIdx) =
2216 getInsertVecEltOpInfo(FPRBank, ScalarTy.getSizeInBits());
2217
2218 auto InsElt =
2219 MIRBuilder
2220 .buildInstr(InsertOpc, {DstRC}, {WidenedOp1->getOperand(0).getReg()})
2221 .addImm(1) /* Lane index */
2222 .addUse(WidenedOp2->getOperand(0).getReg())
2223 .addImm(0);
2224
2225 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2226 return &*InsElt;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002227}
2228
2229bool AArch64InstructionSelector::selectShuffleVector(
2230 MachineInstr &I, MachineRegisterInfo &MRI) const {
2231 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2232 unsigned Src1Reg = I.getOperand(1).getReg();
2233 const LLT Src1Ty = MRI.getType(Src1Reg);
2234 unsigned Src2Reg = I.getOperand(2).getReg();
2235 const LLT Src2Ty = MRI.getType(Src2Reg);
2236
2237 MachineBasicBlock &MBB = *I.getParent();
2238 MachineFunction &MF = *MBB.getParent();
2239 LLVMContext &Ctx = MF.getFunction().getContext();
2240
2241 // G_SHUFFLE_VECTOR doesn't really have a strictly enforced constant mask
2242 // operand, it comes in as a normal vector value which we have to analyze to
2243 // find the mask indices.
2244 SmallVector<int, 8> Mask;
2245 collectShuffleMaskIndices(I, MRI, Mask);
2246 assert(!Mask.empty() && "Expected to find mask indices");
2247
2248 // G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
2249 // it's originated from a <1 x T> type. Those should have been lowered into
2250 // G_BUILD_VECTOR earlier.
2251 if (!Src1Ty.isVector() || !Src2Ty.isVector()) {
2252 LLVM_DEBUG(dbgs() << "Could not select a \"scalar\" G_SHUFFLE_VECTOR\n");
2253 return false;
2254 }
2255
2256 unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
2257
2258 SmallVector<Constant *, 64> CstIdxs;
2259 for (int Val : Mask) {
2260 for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
2261 unsigned Offset = Byte + Val * BytesPerElt;
2262 CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));
2263 }
2264 }
2265
Amara Emerson8acb0d92019-03-04 19:16:00 +00002266 MachineIRBuilder MIRBuilder(I);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002267
2268 // Use a constant pool to load the index vector for TBL.
2269 Constant *CPVal = ConstantVector::get(CstIdxs);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002270 MachineInstr *IndexLoad = emitLoadFromConstantPool(CPVal, MIRBuilder);
2271 if (!IndexLoad) {
2272 LLVM_DEBUG(dbgs() << "Could not load from a constant pool");
2273 return false;
2274 }
2275
Amara Emerson8acb0d92019-03-04 19:16:00 +00002276 if (DstTy.getSizeInBits() != 128) {
2277 assert(DstTy.getSizeInBits() == 64 && "Unexpected shuffle result ty");
2278 // This case can be done with TBL1.
2279 MachineInstr *Concat = emitVectorConcat(Src1Reg, Src2Reg, MIRBuilder);
2280 if (!Concat) {
2281 LLVM_DEBUG(dbgs() << "Could not do vector concat for tbl1");
2282 return false;
2283 }
2284
2285 // The constant pool load will be 64 bits, so need to convert to FPR128 reg.
2286 IndexLoad =
2287 emitScalarToVector(64, &AArch64::FPR128RegClass,
2288 IndexLoad->getOperand(0).getReg(), MIRBuilder);
2289
2290 auto TBL1 = MIRBuilder.buildInstr(
2291 AArch64::TBLv16i8One, {&AArch64::FPR128RegClass},
2292 {Concat->getOperand(0).getReg(), IndexLoad->getOperand(0).getReg()});
2293 constrainSelectedInstRegOperands(*TBL1, TII, TRI, RBI);
2294
2295 auto Copy = BuildMI(*I.getParent(), I, I.getDebugLoc(),
2296 TII.get(TargetOpcode::COPY), I.getOperand(0).getReg())
2297 .addUse(TBL1->getOperand(0).getReg(), 0, AArch64::dsub);
2298 RBI.constrainGenericRegister(Copy.getReg(0), AArch64::FPR64RegClass, MRI);
2299 I.eraseFromParent();
2300 return true;
2301 }
2302
Amara Emerson1abe05c2019-02-21 20:20:16 +00002303 // For TBL2 we need to emit a REG_SEQUENCE to tie together two consecutive
2304 // Q registers for regalloc.
2305 auto RegSeq = MIRBuilder
2306 .buildInstr(TargetOpcode::REG_SEQUENCE,
2307 {&AArch64::QQRegClass}, {Src1Reg})
2308 .addImm(AArch64::qsub0)
2309 .addUse(Src2Reg)
2310 .addImm(AArch64::qsub1);
2311
2312 auto TBL2 =
2313 MIRBuilder.buildInstr(AArch64::TBLv16i8Two, {I.getOperand(0).getReg()},
2314 {RegSeq, IndexLoad->getOperand(0).getReg()});
2315 constrainSelectedInstRegOperands(*RegSeq, TII, TRI, RBI);
2316 constrainSelectedInstRegOperands(*TBL2, TII, TRI, RBI);
2317 I.eraseFromParent();
2318 return true;
2319}
2320
Jessica Paquette16d67a32019-03-13 23:22:23 +00002321MachineInstr *AArch64InstructionSelector::emitLaneInsert(
2322 Optional<unsigned> DstReg, unsigned SrcReg, unsigned EltReg,
2323 unsigned LaneIdx, const RegisterBank &RB,
2324 MachineIRBuilder &MIRBuilder) const {
2325 MachineInstr *InsElt = nullptr;
2326 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
2327 MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
2328
2329 // Create a register to define with the insert if one wasn't passed in.
2330 if (!DstReg)
2331 DstReg = MRI.createVirtualRegister(DstRC);
2332
2333 unsigned EltSize = MRI.getType(EltReg).getSizeInBits();
2334 unsigned Opc = getInsertVecEltOpInfo(RB, EltSize).first;
2335
2336 if (RB.getID() == AArch64::FPRRegBankID) {
2337 auto InsSub = emitScalarToVector(EltSize, DstRC, EltReg, MIRBuilder);
2338 InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
2339 .addImm(LaneIdx)
2340 .addUse(InsSub->getOperand(0).getReg())
2341 .addImm(0);
2342 } else {
2343 InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
2344 .addImm(LaneIdx)
2345 .addUse(EltReg);
2346 }
2347
2348 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2349 return InsElt;
2350}
2351
Jessica Paquette5aff1f42019-03-14 18:01:30 +00002352bool AArch64InstructionSelector::selectInsertElt(
2353 MachineInstr &I, MachineRegisterInfo &MRI) const {
2354 assert(I.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT);
2355
2356 // Get information on the destination.
2357 unsigned DstReg = I.getOperand(0).getReg();
2358 const LLT DstTy = MRI.getType(DstReg);
2359 if (DstTy.getSizeInBits() < 128) {
2360 // TODO: Handle unpacked vectors.
2361 LLVM_DEBUG(dbgs() << "Unpacked vectors not supported yet!");
2362 return false;
2363 }
2364
2365 // Get information on the element we want to insert into the destination.
2366 unsigned EltReg = I.getOperand(2).getReg();
2367 const LLT EltTy = MRI.getType(EltReg);
2368 unsigned EltSize = EltTy.getSizeInBits();
2369 if (EltSize < 16 || EltSize > 64)
2370 return false; // Don't support all element types yet.
2371
2372 // Find the definition of the index. Bail out if it's not defined by a
2373 // G_CONSTANT.
2374 unsigned IdxReg = I.getOperand(3).getReg();
2375 unsigned LaneIdx = 0;
2376 if (!getConstantValueForReg(IdxReg, MRI, LaneIdx))
2377 return false;
2378
2379 // Perform the lane insert.
2380 unsigned SrcReg = I.getOperand(1).getReg();
2381 const RegisterBank &EltRB = *RBI.getRegBank(EltReg, MRI, TRI);
2382 MachineIRBuilder MIRBuilder(I);
2383 emitLaneInsert(DstReg, SrcReg, EltReg, LaneIdx, EltRB, MIRBuilder);
2384 I.eraseFromParent();
2385 return true;
2386}
2387
Amara Emerson5ec14602018-12-10 18:44:58 +00002388bool AArch64InstructionSelector::selectBuildVector(
2389 MachineInstr &I, MachineRegisterInfo &MRI) const {
2390 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
2391 // Until we port more of the optimized selections, for now just use a vector
2392 // insert sequence.
2393 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2394 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
2395 unsigned EltSize = EltTy.getSizeInBits();
Jessica Paquette245047d2019-01-24 22:00:41 +00002396 if (EltSize < 16 || EltSize > 64)
Amara Emerson5ec14602018-12-10 18:44:58 +00002397 return false; // Don't support all element types yet.
2398 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002399 MachineIRBuilder MIRBuilder(I);
Jessica Paquette245047d2019-01-24 22:00:41 +00002400
2401 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002402 MachineInstr *ScalarToVec =
Amara Emerson8acb0d92019-03-04 19:16:00 +00002403 emitScalarToVector(DstTy.getElementType().getSizeInBits(), DstRC,
2404 I.getOperand(1).getReg(), MIRBuilder);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002405 if (!ScalarToVec)
Jessica Paquette245047d2019-01-24 22:00:41 +00002406 return false;
2407
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002408 unsigned DstVec = ScalarToVec->getOperand(0).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +00002409 unsigned DstSize = DstTy.getSizeInBits();
2410
2411 // Keep track of the last MI we inserted. Later on, we might be able to save
2412 // a copy using it.
2413 MachineInstr *PrevMI = nullptr;
2414 for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
Jessica Paquette16d67a32019-03-13 23:22:23 +00002415 // Note that if we don't do a subregister copy, we can end up making an
2416 // extra register.
2417 PrevMI = &*emitLaneInsert(None, DstVec, I.getOperand(i).getReg(), i - 1, RB,
2418 MIRBuilder);
2419 DstVec = PrevMI->getOperand(0).getReg();
Amara Emerson5ec14602018-12-10 18:44:58 +00002420 }
Jessica Paquette245047d2019-01-24 22:00:41 +00002421
2422 // If DstTy's size in bits is less than 128, then emit a subregister copy
2423 // from DstVec to the last register we've defined.
2424 if (DstSize < 128) {
Jessica Paquette85ace622019-03-13 23:29:54 +00002425 // Force this to be FPR using the destination vector.
2426 const TargetRegisterClass *RC =
2427 getMinClassForRegBank(*RBI.getRegBank(DstVec, MRI, TRI), DstSize);
Jessica Paquette245047d2019-01-24 22:00:41 +00002428 if (!RC)
2429 return false;
Jessica Paquette85ace622019-03-13 23:29:54 +00002430 if (RC != &AArch64::FPR32RegClass && RC != &AArch64::FPR64RegClass) {
2431 LLVM_DEBUG(dbgs() << "Unsupported register class!\n");
2432 return false;
2433 }
2434
2435 unsigned SubReg = 0;
2436 if (!getSubRegForClass(RC, TRI, SubReg))
2437 return false;
2438 if (SubReg != AArch64::ssub && SubReg != AArch64::dsub) {
2439 LLVM_DEBUG(dbgs() << "Unsupported destination size! (" << DstSize
2440 << "\n");
2441 return false;
2442 }
Jessica Paquette245047d2019-01-24 22:00:41 +00002443
2444 unsigned Reg = MRI.createVirtualRegister(RC);
2445 unsigned DstReg = I.getOperand(0).getReg();
2446
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002447 // MIRBuilder doesn't let us create uses with subregs & flags, so use
2448 // BuildMI here instead.
Jessica Paquette245047d2019-01-24 22:00:41 +00002449 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
2450 DstReg)
2451 .addUse(DstVec, 0, SubReg);
2452 MachineOperand &RegOp = I.getOperand(1);
2453 RegOp.setReg(Reg);
2454 RBI.constrainGenericRegister(DstReg, *RC, MRI);
2455 } else {
2456 // We don't need a subregister copy. Save a copy by re-using the
2457 // destination register on the final insert.
2458 assert(PrevMI && "PrevMI was null?");
2459 PrevMI->getOperand(0).setReg(I.getOperand(0).getReg());
2460 constrainSelectedInstRegOperands(*PrevMI, TII, TRI, RBI);
2461 }
2462
Amara Emerson5ec14602018-12-10 18:44:58 +00002463 I.eraseFromParent();
2464 return true;
2465}
2466
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002467/// SelectArithImmed - Select an immediate value that can be represented as
2468/// a 12-bit value shifted left by either 0 or 12. If so, return true with
2469/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002470InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00002471AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002472 MachineInstr &MI = *Root.getParent();
2473 MachineBasicBlock &MBB = *MI.getParent();
2474 MachineFunction &MF = *MBB.getParent();
2475 MachineRegisterInfo &MRI = MF.getRegInfo();
2476
2477 // This function is called from the addsub_shifted_imm ComplexPattern,
2478 // which lists [imm] as the list of opcode it's interested in, however
2479 // we still need to check whether the operand is actually an immediate
2480 // here because the ComplexPattern opcode list is only used in
2481 // root-level opcode matching.
2482 uint64_t Immed;
2483 if (Root.isImm())
2484 Immed = Root.getImm();
2485 else if (Root.isCImm())
2486 Immed = Root.getCImm()->getZExtValue();
2487 else if (Root.isReg()) {
2488 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
2489 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002490 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002491 MachineOperand &Op1 = Def->getOperand(1);
2492 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002493 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002494 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002495 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002496 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002497
2498 unsigned ShiftAmt;
2499
2500 if (Immed >> 12 == 0) {
2501 ShiftAmt = 0;
2502 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
2503 ShiftAmt = 12;
2504 Immed = Immed >> 12;
2505 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002506 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002507
2508 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002509 return {{
2510 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
2511 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
2512 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002513}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002514
Daniel Sandersea8711b2017-10-16 03:36:29 +00002515/// Select a "register plus unscaled signed 9-bit immediate" address. This
2516/// should only match when there is an offset that is not valid for a scaled
2517/// immediate addressing mode. The "Size" argument is the size in bytes of the
2518/// memory reference, which is needed here to know what is valid for a scaled
2519/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002520InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002521AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
2522 unsigned Size) const {
2523 MachineRegisterInfo &MRI =
2524 Root.getParent()->getParent()->getParent()->getRegInfo();
2525
2526 if (!Root.isReg())
2527 return None;
2528
2529 if (!isBaseWithConstantOffset(Root, MRI))
2530 return None;
2531
2532 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2533 if (!RootDef)
2534 return None;
2535
2536 MachineOperand &OffImm = RootDef->getOperand(2);
2537 if (!OffImm.isReg())
2538 return None;
2539 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
2540 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
2541 return None;
2542 int64_t RHSC;
2543 MachineOperand &RHSOp1 = RHS->getOperand(1);
2544 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
2545 return None;
2546 RHSC = RHSOp1.getCImm()->getSExtValue();
2547
2548 // If the offset is valid as a scaled immediate, don't match here.
2549 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
2550 return None;
2551 if (RHSC >= -256 && RHSC < 256) {
2552 MachineOperand &Base = RootDef->getOperand(1);
2553 return {{
2554 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
2555 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
2556 }};
2557 }
2558 return None;
2559}
2560
2561/// Select a "register plus scaled unsigned 12-bit immediate" address. The
2562/// "Size" argument is the size in bytes of the memory reference, which
2563/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002564InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002565AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
2566 unsigned Size) const {
2567 MachineRegisterInfo &MRI =
2568 Root.getParent()->getParent()->getParent()->getRegInfo();
2569
2570 if (!Root.isReg())
2571 return None;
2572
2573 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2574 if (!RootDef)
2575 return None;
2576
2577 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
2578 return {{
2579 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
2580 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2581 }};
2582 }
2583
2584 if (isBaseWithConstantOffset(Root, MRI)) {
2585 MachineOperand &LHS = RootDef->getOperand(1);
2586 MachineOperand &RHS = RootDef->getOperand(2);
2587 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
2588 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
2589 if (LHSDef && RHSDef) {
2590 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
2591 unsigned Scale = Log2_32(Size);
2592 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
2593 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00002594 return {{
2595 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
2596 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2597 }};
2598
Daniel Sandersea8711b2017-10-16 03:36:29 +00002599 return {{
2600 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
2601 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2602 }};
2603 }
2604 }
2605 }
2606
2607 // Before falling back to our general case, check if the unscaled
2608 // instructions can handle this. If so, that's preferable.
2609 if (selectAddrModeUnscaled(Root, Size).hasValue())
2610 return None;
2611
2612 return {{
2613 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
2614 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2615 }};
2616}
2617
Volkan Kelesf7f25682018-01-16 18:44:05 +00002618void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
2619 const MachineInstr &MI) const {
2620 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2621 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
2622 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
2623 assert(CstVal && "Expected constant value");
2624 MIB.addImm(CstVal.getValue());
2625}
2626
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002627namespace llvm {
2628InstructionSelector *
2629createAArch64InstructionSelector(const AArch64TargetMachine &TM,
2630 AArch64Subtarget &Subtarget,
2631 AArch64RegisterBankInfo &RBI) {
2632 return new AArch64InstructionSelector(TM, Subtarget, RBI);
2633}
2634}