blob: b033824bfdf4022098eb9e6ec4fbb5828723b94c [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;
Amara Emerson5ec14602018-12-10 18:44:58 +000085 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson8cb186c2018-12-20 01:11:04 +000086 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette245047d2019-01-24 22:00:41 +000087 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000088
Amara Emerson1abe05c2019-02-21 20:20:16 +000089 void collectShuffleMaskIndices(MachineInstr &I, MachineRegisterInfo &MRI,
90 SmallVectorImpl<int> &Idxs) const;
91 bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette607774c2019-03-11 22:18:01 +000092 bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +000093
94 unsigned emitConstantPoolEntry(Constant *CPVal, MachineFunction &MF) const;
95 MachineInstr *emitLoadFromConstantPool(Constant *CPVal,
96 MachineIRBuilder &MIRBuilder) const;
Amara Emerson8acb0d92019-03-04 19:16:00 +000097 MachineInstr *emitVectorConcat(unsigned Op1, unsigned Op2,
98 MachineIRBuilder &MIRBuilder) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +000099
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000100 ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000101
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000102 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root,
103 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000104
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000105 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000106 return selectAddrModeUnscaled(Root, 1);
107 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000108 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000109 return selectAddrModeUnscaled(Root, 2);
110 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000111 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000112 return selectAddrModeUnscaled(Root, 4);
113 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000114 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000115 return selectAddrModeUnscaled(Root, 8);
116 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000117 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000118 return selectAddrModeUnscaled(Root, 16);
119 }
120
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000121 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root,
122 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000123 template <int Width>
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000124 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000125 return selectAddrModeIndexed(Root, Width / 8);
126 }
127
Volkan Kelesf7f25682018-01-16 18:44:05 +0000128 void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const;
129
Amara Emerson1e8c1642018-07-31 00:09:02 +0000130 // Materialize a GlobalValue or BlockAddress using a movz+movk sequence.
131 void materializeLargeCMVal(MachineInstr &I, const Value *V,
132 unsigned char OpFlags) const;
133
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000134 const AArch64TargetMachine &TM;
135 const AArch64Subtarget &STI;
136 const AArch64InstrInfo &TII;
137 const AArch64RegisterInfo &TRI;
138 const AArch64RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000139
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000140#define GET_GLOBALISEL_PREDICATES_DECL
141#include "AArch64GenGlobalISel.inc"
142#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000143
144// We declare the temporaries used by selectImpl() in the class to minimize the
145// cost of constructing placeholder values.
146#define GET_GLOBALISEL_TEMPORARIES_DECL
147#include "AArch64GenGlobalISel.inc"
148#undef GET_GLOBALISEL_TEMPORARIES_DECL
149};
150
151} // end anonymous namespace
152
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000153#define GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000154#include "AArch64GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000155#undef GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000156
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000157AArch64InstructionSelector::AArch64InstructionSelector(
Tim Northoverbdf16242016-10-10 21:50:00 +0000158 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
159 const AArch64RegisterBankInfo &RBI)
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000160 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000161 TRI(*STI.getRegisterInfo()), RBI(RBI),
162#define GET_GLOBALISEL_PREDICATES_INIT
163#include "AArch64GenGlobalISel.inc"
164#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000165#define GET_GLOBALISEL_TEMPORARIES_INIT
166#include "AArch64GenGlobalISel.inc"
167#undef GET_GLOBALISEL_TEMPORARIES_INIT
168{
169}
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000170
Tim Northoverfb8d9892016-10-12 22:49:15 +0000171// FIXME: This should be target-independent, inferred from the types declared
172// for each class in the bank.
173static const TargetRegisterClass *
174getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
Amara Emerson3838ed02018-02-02 18:03:30 +0000175 const RegisterBankInfo &RBI,
176 bool GetAllRegSet = false) {
Tim Northoverfb8d9892016-10-12 22:49:15 +0000177 if (RB.getID() == AArch64::GPRRegBankID) {
178 if (Ty.getSizeInBits() <= 32)
Amara Emerson3838ed02018-02-02 18:03:30 +0000179 return GetAllRegSet ? &AArch64::GPR32allRegClass
180 : &AArch64::GPR32RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000181 if (Ty.getSizeInBits() == 64)
Amara Emerson3838ed02018-02-02 18:03:30 +0000182 return GetAllRegSet ? &AArch64::GPR64allRegClass
183 : &AArch64::GPR64RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000184 return nullptr;
185 }
186
187 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson3838ed02018-02-02 18:03:30 +0000188 if (Ty.getSizeInBits() <= 16)
189 return &AArch64::FPR16RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000190 if (Ty.getSizeInBits() == 32)
191 return &AArch64::FPR32RegClass;
192 if (Ty.getSizeInBits() == 64)
193 return &AArch64::FPR64RegClass;
194 if (Ty.getSizeInBits() == 128)
195 return &AArch64::FPR128RegClass;
196 return nullptr;
197 }
198
199 return nullptr;
200}
201
Jessica Paquette245047d2019-01-24 22:00:41 +0000202/// Given a register bank, and size in bits, return the smallest register class
203/// that can represent that combination.
Benjamin Kramer711950c2019-02-11 15:16:21 +0000204static const TargetRegisterClass *
205getMinClassForRegBank(const RegisterBank &RB, unsigned SizeInBits,
206 bool GetAllRegSet = false) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000207 unsigned RegBankID = RB.getID();
208
209 if (RegBankID == AArch64::GPRRegBankID) {
210 if (SizeInBits <= 32)
211 return GetAllRegSet ? &AArch64::GPR32allRegClass
212 : &AArch64::GPR32RegClass;
213 if (SizeInBits == 64)
214 return GetAllRegSet ? &AArch64::GPR64allRegClass
215 : &AArch64::GPR64RegClass;
216 }
217
218 if (RegBankID == AArch64::FPRRegBankID) {
219 switch (SizeInBits) {
220 default:
221 return nullptr;
222 case 8:
223 return &AArch64::FPR8RegClass;
224 case 16:
225 return &AArch64::FPR16RegClass;
226 case 32:
227 return &AArch64::FPR32RegClass;
228 case 64:
229 return &AArch64::FPR64RegClass;
230 case 128:
231 return &AArch64::FPR128RegClass;
232 }
233 }
234
235 return nullptr;
236}
237
238/// Returns the correct subregister to use for a given register class.
239static bool getSubRegForClass(const TargetRegisterClass *RC,
240 const TargetRegisterInfo &TRI, unsigned &SubReg) {
241 switch (TRI.getRegSizeInBits(*RC)) {
242 case 8:
243 SubReg = AArch64::bsub;
244 break;
245 case 16:
246 SubReg = AArch64::hsub;
247 break;
248 case 32:
249 if (RC == &AArch64::GPR32RegClass)
250 SubReg = AArch64::sub_32;
251 else
252 SubReg = AArch64::ssub;
253 break;
254 case 64:
255 SubReg = AArch64::dsub;
256 break;
257 default:
258 LLVM_DEBUG(
259 dbgs() << "Couldn't find appropriate subregister for register class.");
260 return false;
261 }
262
263 return true;
264}
265
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000266/// Check whether \p I is a currently unsupported binary operation:
267/// - it has an unsized type
268/// - an operand is not a vreg
269/// - all operands are not in the same bank
270/// These are checks that should someday live in the verifier, but right now,
271/// these are mostly limitations of the aarch64 selector.
272static bool unsupportedBinOp(const MachineInstr &I,
273 const AArch64RegisterBankInfo &RBI,
274 const MachineRegisterInfo &MRI,
275 const AArch64RegisterInfo &TRI) {
Tim Northover0f140c72016-09-09 11:46:34 +0000276 LLT Ty = MRI.getType(I.getOperand(0).getReg());
Tim Northover32a078a2016-09-15 10:09:59 +0000277 if (!Ty.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000278 LLVM_DEBUG(dbgs() << "Generic binop register should be typed\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000279 return true;
280 }
281
282 const RegisterBank *PrevOpBank = nullptr;
283 for (auto &MO : I.operands()) {
284 // FIXME: Support non-register operands.
285 if (!MO.isReg()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000286 LLVM_DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000287 return true;
288 }
289
290 // FIXME: Can generic operations have physical registers operands? If
291 // so, this will need to be taught about that, and we'll need to get the
292 // bank out of the minimal class for the register.
293 // Either way, this needs to be documented (and possibly verified).
294 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000295 LLVM_DEBUG(dbgs() << "Generic inst has physical register operand\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000296 return true;
297 }
298
299 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI);
300 if (!OpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000301 LLVM_DEBUG(dbgs() << "Generic register has no bank or class\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000302 return true;
303 }
304
305 if (PrevOpBank && OpBank != PrevOpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000306 LLVM_DEBUG(dbgs() << "Generic inst operands have different banks\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000307 return true;
308 }
309 PrevOpBank = OpBank;
310 }
311 return false;
312}
313
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000314/// Select the AArch64 opcode for the basic binary operation \p GenericOpc
Ahmed Bougachacfb384d2017-01-23 21:10:05 +0000315/// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000316/// and of size \p OpSize.
317/// \returns \p GenericOpc if the combination is unsupported.
318static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
319 unsigned OpSize) {
320 switch (RegBankID) {
321 case AArch64::GPRRegBankID:
Ahmed Bougacha05a5f7d2017-01-25 02:41:38 +0000322 if (OpSize == 32) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000323 switch (GenericOpc) {
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000324 case TargetOpcode::G_SHL:
325 return AArch64::LSLVWr;
326 case TargetOpcode::G_LSHR:
327 return AArch64::LSRVWr;
328 case TargetOpcode::G_ASHR:
329 return AArch64::ASRVWr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000330 default:
331 return GenericOpc;
332 }
Tim Northover55782222016-10-18 20:03:48 +0000333 } else if (OpSize == 64) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000334 switch (GenericOpc) {
Tim Northover2fda4b02016-10-10 21:49:49 +0000335 case TargetOpcode::G_GEP:
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000336 return AArch64::ADDXrr;
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000337 case TargetOpcode::G_SHL:
338 return AArch64::LSLVXr;
339 case TargetOpcode::G_LSHR:
340 return AArch64::LSRVXr;
341 case TargetOpcode::G_ASHR:
342 return AArch64::ASRVXr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000343 default:
344 return GenericOpc;
345 }
346 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000347 break;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000348 case AArch64::FPRRegBankID:
349 switch (OpSize) {
350 case 32:
351 switch (GenericOpc) {
352 case TargetOpcode::G_FADD:
353 return AArch64::FADDSrr;
354 case TargetOpcode::G_FSUB:
355 return AArch64::FSUBSrr;
356 case TargetOpcode::G_FMUL:
357 return AArch64::FMULSrr;
358 case TargetOpcode::G_FDIV:
359 return AArch64::FDIVSrr;
360 default:
361 return GenericOpc;
362 }
363 case 64:
364 switch (GenericOpc) {
365 case TargetOpcode::G_FADD:
366 return AArch64::FADDDrr;
367 case TargetOpcode::G_FSUB:
368 return AArch64::FSUBDrr;
369 case TargetOpcode::G_FMUL:
370 return AArch64::FMULDrr;
371 case TargetOpcode::G_FDIV:
372 return AArch64::FDIVDrr;
Quentin Colombet0e531272016-10-11 00:21:11 +0000373 case TargetOpcode::G_OR:
374 return AArch64::ORRv8i8;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000375 default:
376 return GenericOpc;
377 }
378 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000379 break;
380 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000381 return GenericOpc;
382}
383
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000384/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
385/// appropriate for the (value) register bank \p RegBankID and of memory access
386/// size \p OpSize. This returns the variant with the base+unsigned-immediate
387/// addressing mode (e.g., LDRXui).
388/// \returns \p GenericOpc if the combination is unsupported.
389static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
390 unsigned OpSize) {
391 const bool isStore = GenericOpc == TargetOpcode::G_STORE;
392 switch (RegBankID) {
393 case AArch64::GPRRegBankID:
394 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000395 case 8:
396 return isStore ? AArch64::STRBBui : AArch64::LDRBBui;
397 case 16:
398 return isStore ? AArch64::STRHHui : AArch64::LDRHHui;
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000399 case 32:
400 return isStore ? AArch64::STRWui : AArch64::LDRWui;
401 case 64:
402 return isStore ? AArch64::STRXui : AArch64::LDRXui;
403 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000404 break;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000405 case AArch64::FPRRegBankID:
406 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000407 case 8:
408 return isStore ? AArch64::STRBui : AArch64::LDRBui;
409 case 16:
410 return isStore ? AArch64::STRHui : AArch64::LDRHui;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000411 case 32:
412 return isStore ? AArch64::STRSui : AArch64::LDRSui;
413 case 64:
414 return isStore ? AArch64::STRDui : AArch64::LDRDui;
415 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000416 break;
417 }
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000418 return GenericOpc;
419}
420
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000421#ifndef NDEBUG
Jessica Paquette245047d2019-01-24 22:00:41 +0000422/// Helper function that verifies that we have a valid copy at the end of
423/// selectCopy. Verifies that the source and dest have the expected sizes and
424/// then returns true.
425static bool isValidCopy(const MachineInstr &I, const RegisterBank &DstBank,
426 const MachineRegisterInfo &MRI,
427 const TargetRegisterInfo &TRI,
428 const RegisterBankInfo &RBI) {
429 const unsigned DstReg = I.getOperand(0).getReg();
430 const unsigned SrcReg = I.getOperand(1).getReg();
431 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
432 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Amara Emersondb211892018-02-20 05:11:57 +0000433
Jessica Paquette245047d2019-01-24 22:00:41 +0000434 // Make sure the size of the source and dest line up.
435 assert(
436 (DstSize == SrcSize ||
437 // Copies are a mean to setup initial types, the number of
438 // bits may not exactly match.
439 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && DstSize <= SrcSize) ||
440 // Copies are a mean to copy bits around, as long as we are
441 // on the same register class, that's fine. Otherwise, that
442 // means we need some SUBREG_TO_REG or AND & co.
443 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) &&
444 "Copy with different width?!");
445
446 // Check the size of the destination.
447 assert((DstSize <= 64 || DstBank.getID() == AArch64::FPRRegBankID) &&
448 "GPRs cannot get more than 64-bit width values");
449
450 return true;
451}
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000452#endif
Jessica Paquette245047d2019-01-24 22:00:41 +0000453
454/// Helper function for selectCopy. Inserts a subregister copy from
455/// \p *From to \p *To, linking it up to \p I.
456///
457/// e.g, given I = "Dst = COPY SrcReg", we'll transform that into
458///
459/// CopyReg (From class) = COPY SrcReg
460/// SubRegCopy (To class) = COPY CopyReg:SubReg
461/// Dst = COPY SubRegCopy
462static bool selectSubregisterCopy(MachineInstr &I, const TargetInstrInfo &TII,
463 MachineRegisterInfo &MRI,
464 const RegisterBankInfo &RBI, unsigned SrcReg,
465 const TargetRegisterClass *From,
466 const TargetRegisterClass *To,
467 unsigned SubReg) {
468 unsigned CopyReg = MRI.createVirtualRegister(From);
469 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::COPY), CopyReg)
470 .addUse(SrcReg);
471 unsigned SubRegCopy = MRI.createVirtualRegister(To);
472 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
473 SubRegCopy)
474 .addUse(CopyReg, 0, SubReg);
Amara Emersondb211892018-02-20 05:11:57 +0000475 MachineOperand &RegOp = I.getOperand(1);
476 RegOp.setReg(SubRegCopy);
Jessica Paquette245047d2019-01-24 22:00:41 +0000477
478 // It's possible that the destination register won't be constrained. Make
479 // sure that happens.
480 if (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()))
481 RBI.constrainGenericRegister(I.getOperand(0).getReg(), *To, MRI);
482
Amara Emersondb211892018-02-20 05:11:57 +0000483 return true;
484}
485
Quentin Colombetcb629a82016-10-12 03:57:49 +0000486static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
487 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
488 const RegisterBankInfo &RBI) {
489
490 unsigned DstReg = I.getOperand(0).getReg();
Amara Emersondb211892018-02-20 05:11:57 +0000491 unsigned SrcReg = I.getOperand(1).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +0000492 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
493 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
494 const TargetRegisterClass *DstRC = getMinClassForRegBank(
495 DstRegBank, RBI.getSizeInBits(DstReg, MRI, TRI), true);
496 if (!DstRC) {
497 LLVM_DEBUG(dbgs() << "Unexpected dest size "
498 << RBI.getSizeInBits(DstReg, MRI, TRI) << '\n');
Amara Emerson3838ed02018-02-02 18:03:30 +0000499 return false;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000500 }
501
Jessica Paquette245047d2019-01-24 22:00:41 +0000502 // A couple helpers below, for making sure that the copy we produce is valid.
503
504 // Set to true if we insert a SUBREG_TO_REG. If we do this, then we don't want
505 // to verify that the src and dst are the same size, since that's handled by
506 // the SUBREG_TO_REG.
507 bool KnownValid = false;
508
509 // Returns true, or asserts if something we don't expect happens. Instead of
510 // returning true, we return isValidCopy() to ensure that we verify the
511 // result.
Jessica Paquette76c40f82019-01-24 22:51:31 +0000512 auto CheckCopy = [&]() {
Jessica Paquette245047d2019-01-24 22:00:41 +0000513 // If we have a bitcast or something, we can't have physical registers.
514 assert(
Simon Pilgrimdea61742019-01-25 11:38:40 +0000515 (I.isCopy() ||
516 (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()) &&
517 !TargetRegisterInfo::isPhysicalRegister(I.getOperand(1).getReg()))) &&
518 "No phys reg on generic operator!");
Jessica Paquette245047d2019-01-24 22:00:41 +0000519 assert(KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI));
Jonas Hahnfeld65a401f2019-03-04 08:51:32 +0000520 (void)KnownValid;
Jessica Paquette245047d2019-01-24 22:00:41 +0000521 return true;
522 };
523
524 // Is this a copy? If so, then we may need to insert a subregister copy, or
525 // a SUBREG_TO_REG.
526 if (I.isCopy()) {
527 // Yes. Check if there's anything to fix up.
528 const TargetRegisterClass *SrcRC = getMinClassForRegBank(
529 SrcRegBank, RBI.getSizeInBits(SrcReg, MRI, TRI), true);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000530 if (!SrcRC) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000531 LLVM_DEBUG(dbgs() << "Couldn't determine source register class\n");
532 return false;
Amara Emerson7e9f3482018-02-18 17:10:49 +0000533 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000534
535 // Is this a cross-bank copy?
536 if (DstRegBank.getID() != SrcRegBank.getID()) {
537 // If we're doing a cross-bank copy on different-sized registers, we need
538 // to do a bit more work.
539 unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
540 unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
541
542 if (SrcSize > DstSize) {
543 // We're doing a cross-bank copy into a smaller register. We need a
544 // subregister copy. First, get a register class that's on the same bank
545 // as the destination, but the same size as the source.
546 const TargetRegisterClass *SubregRC =
547 getMinClassForRegBank(DstRegBank, SrcSize, true);
548 assert(SubregRC && "Didn't get a register class for subreg?");
549
550 // Get the appropriate subregister for the destination.
551 unsigned SubReg = 0;
552 if (!getSubRegForClass(DstRC, TRI, SubReg)) {
553 LLVM_DEBUG(dbgs() << "Couldn't determine subregister for copy.\n");
554 return false;
555 }
556
557 // Now, insert a subregister copy using the new register class.
558 selectSubregisterCopy(I, TII, MRI, RBI, SrcReg, SubregRC, DstRC,
559 SubReg);
560 return CheckCopy();
561 }
562
563 else if (DstRegBank.getID() == AArch64::GPRRegBankID && DstSize == 32 &&
564 SrcSize == 16) {
565 // Special case for FPR16 to GPR32.
566 // FIXME: This can probably be generalized like the above case.
567 unsigned PromoteReg =
568 MRI.createVirtualRegister(&AArch64::FPR32RegClass);
569 BuildMI(*I.getParent(), I, I.getDebugLoc(),
570 TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
571 .addImm(0)
572 .addUse(SrcReg)
573 .addImm(AArch64::hsub);
574 MachineOperand &RegOp = I.getOperand(1);
575 RegOp.setReg(PromoteReg);
576
577 // Promise that the copy is implicitly validated by the SUBREG_TO_REG.
578 KnownValid = true;
579 }
Amara Emerson7e9f3482018-02-18 17:10:49 +0000580 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000581
582 // If the destination is a physical register, then there's nothing to
583 // change, so we're done.
584 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
585 return CheckCopy();
Amara Emerson7e9f3482018-02-18 17:10:49 +0000586 }
587
Jessica Paquette245047d2019-01-24 22:00:41 +0000588 // No need to constrain SrcReg. It will get constrained when we hit another
589 // of its use or its defs. Copies do not have constraints.
590 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000591 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
592 << " operand\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000593 return false;
594 }
595 I.setDesc(TII.get(AArch64::COPY));
Jessica Paquette245047d2019-01-24 22:00:41 +0000596 return CheckCopy();
Quentin Colombetcb629a82016-10-12 03:57:49 +0000597}
598
Tim Northover69271c62016-10-12 22:49:11 +0000599static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
600 if (!DstTy.isScalar() || !SrcTy.isScalar())
601 return GenericOpc;
602
603 const unsigned DstSize = DstTy.getSizeInBits();
604 const unsigned SrcSize = SrcTy.getSizeInBits();
605
606 switch (DstSize) {
607 case 32:
608 switch (SrcSize) {
609 case 32:
610 switch (GenericOpc) {
611 case TargetOpcode::G_SITOFP:
612 return AArch64::SCVTFUWSri;
613 case TargetOpcode::G_UITOFP:
614 return AArch64::UCVTFUWSri;
615 case TargetOpcode::G_FPTOSI:
616 return AArch64::FCVTZSUWSr;
617 case TargetOpcode::G_FPTOUI:
618 return AArch64::FCVTZUUWSr;
619 default:
620 return GenericOpc;
621 }
622 case 64:
623 switch (GenericOpc) {
624 case TargetOpcode::G_SITOFP:
625 return AArch64::SCVTFUXSri;
626 case TargetOpcode::G_UITOFP:
627 return AArch64::UCVTFUXSri;
628 case TargetOpcode::G_FPTOSI:
629 return AArch64::FCVTZSUWDr;
630 case TargetOpcode::G_FPTOUI:
631 return AArch64::FCVTZUUWDr;
632 default:
633 return GenericOpc;
634 }
635 default:
636 return GenericOpc;
637 }
638 case 64:
639 switch (SrcSize) {
640 case 32:
641 switch (GenericOpc) {
642 case TargetOpcode::G_SITOFP:
643 return AArch64::SCVTFUWDri;
644 case TargetOpcode::G_UITOFP:
645 return AArch64::UCVTFUWDri;
646 case TargetOpcode::G_FPTOSI:
647 return AArch64::FCVTZSUXSr;
648 case TargetOpcode::G_FPTOUI:
649 return AArch64::FCVTZUUXSr;
650 default:
651 return GenericOpc;
652 }
653 case 64:
654 switch (GenericOpc) {
655 case TargetOpcode::G_SITOFP:
656 return AArch64::SCVTFUXDri;
657 case TargetOpcode::G_UITOFP:
658 return AArch64::UCVTFUXDri;
659 case TargetOpcode::G_FPTOSI:
660 return AArch64::FCVTZSUXDr;
661 case TargetOpcode::G_FPTOUI:
662 return AArch64::FCVTZUUXDr;
663 default:
664 return GenericOpc;
665 }
666 default:
667 return GenericOpc;
668 }
669 default:
670 return GenericOpc;
671 };
672 return GenericOpc;
673}
674
Tim Northover6c02ad52016-10-12 22:49:04 +0000675static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
676 switch (P) {
677 default:
678 llvm_unreachable("Unknown condition code!");
679 case CmpInst::ICMP_NE:
680 return AArch64CC::NE;
681 case CmpInst::ICMP_EQ:
682 return AArch64CC::EQ;
683 case CmpInst::ICMP_SGT:
684 return AArch64CC::GT;
685 case CmpInst::ICMP_SGE:
686 return AArch64CC::GE;
687 case CmpInst::ICMP_SLT:
688 return AArch64CC::LT;
689 case CmpInst::ICMP_SLE:
690 return AArch64CC::LE;
691 case CmpInst::ICMP_UGT:
692 return AArch64CC::HI;
693 case CmpInst::ICMP_UGE:
694 return AArch64CC::HS;
695 case CmpInst::ICMP_ULT:
696 return AArch64CC::LO;
697 case CmpInst::ICMP_ULE:
698 return AArch64CC::LS;
699 }
700}
701
Tim Northover7dd378d2016-10-12 22:49:07 +0000702static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
703 AArch64CC::CondCode &CondCode,
704 AArch64CC::CondCode &CondCode2) {
705 CondCode2 = AArch64CC::AL;
706 switch (P) {
707 default:
708 llvm_unreachable("Unknown FP condition!");
709 case CmpInst::FCMP_OEQ:
710 CondCode = AArch64CC::EQ;
711 break;
712 case CmpInst::FCMP_OGT:
713 CondCode = AArch64CC::GT;
714 break;
715 case CmpInst::FCMP_OGE:
716 CondCode = AArch64CC::GE;
717 break;
718 case CmpInst::FCMP_OLT:
719 CondCode = AArch64CC::MI;
720 break;
721 case CmpInst::FCMP_OLE:
722 CondCode = AArch64CC::LS;
723 break;
724 case CmpInst::FCMP_ONE:
725 CondCode = AArch64CC::MI;
726 CondCode2 = AArch64CC::GT;
727 break;
728 case CmpInst::FCMP_ORD:
729 CondCode = AArch64CC::VC;
730 break;
731 case CmpInst::FCMP_UNO:
732 CondCode = AArch64CC::VS;
733 break;
734 case CmpInst::FCMP_UEQ:
735 CondCode = AArch64CC::EQ;
736 CondCode2 = AArch64CC::VS;
737 break;
738 case CmpInst::FCMP_UGT:
739 CondCode = AArch64CC::HI;
740 break;
741 case CmpInst::FCMP_UGE:
742 CondCode = AArch64CC::PL;
743 break;
744 case CmpInst::FCMP_ULT:
745 CondCode = AArch64CC::LT;
746 break;
747 case CmpInst::FCMP_ULE:
748 CondCode = AArch64CC::LE;
749 break;
750 case CmpInst::FCMP_UNE:
751 CondCode = AArch64CC::NE;
752 break;
753 }
754}
755
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000756bool AArch64InstructionSelector::selectCompareBranch(
757 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
758
759 const unsigned CondReg = I.getOperand(0).getReg();
760 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
761 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
Aditya Nandakumar02c602e2017-07-31 17:00:16 +0000762 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC)
763 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg());
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000764 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
765 return false;
766
767 unsigned LHS = CCMI->getOperand(2).getReg();
768 unsigned RHS = CCMI->getOperand(3).getReg();
769 if (!getConstantVRegVal(RHS, MRI))
770 std::swap(RHS, LHS);
771
772 const auto RHSImm = getConstantVRegVal(RHS, MRI);
773 if (!RHSImm || *RHSImm != 0)
774 return false;
775
776 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
777 if (RB.getID() != AArch64::GPRRegBankID)
778 return false;
779
780 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
781 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
782 return false;
783
784 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
785 unsigned CBOpc = 0;
786 if (CmpWidth <= 32)
787 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
788 else if (CmpWidth == 64)
789 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
790 else
791 return false;
792
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +0000793 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
794 .addUse(LHS)
795 .addMBB(DestMBB)
796 .constrainAllUses(TII, TRI, RBI);
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000797
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000798 I.eraseFromParent();
799 return true;
800}
801
Tim Northovere9600d82017-02-08 17:57:27 +0000802bool AArch64InstructionSelector::selectVaStartAAPCS(
803 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
804 return false;
805}
806
807bool AArch64InstructionSelector::selectVaStartDarwin(
808 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
809 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
810 unsigned ListReg = I.getOperand(0).getReg();
811
812 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
813
814 auto MIB =
815 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri))
816 .addDef(ArgsAddrReg)
817 .addFrameIndex(FuncInfo->getVarArgsStackIndex())
818 .addImm(0)
819 .addImm(0);
820
821 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
822
823 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui))
824 .addUse(ArgsAddrReg)
825 .addUse(ListReg)
826 .addImm(0)
827 .addMemOperand(*I.memoperands_begin());
828
829 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
830 I.eraseFromParent();
831 return true;
832}
833
Amara Emerson1e8c1642018-07-31 00:09:02 +0000834void AArch64InstructionSelector::materializeLargeCMVal(
835 MachineInstr &I, const Value *V, unsigned char OpFlags) const {
836 MachineBasicBlock &MBB = *I.getParent();
837 MachineFunction &MF = *MBB.getParent();
838 MachineRegisterInfo &MRI = MF.getRegInfo();
839 MachineIRBuilder MIB(I);
840
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000841 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, {&AArch64::GPR64RegClass}, {});
Amara Emerson1e8c1642018-07-31 00:09:02 +0000842 MovZ->addOperand(MF, I.getOperand(1));
843 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 |
844 AArch64II::MO_NC);
845 MovZ->addOperand(MF, MachineOperand::CreateImm(0));
846 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI);
847
848 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, unsigned Offset,
849 unsigned ForceDstReg) {
850 unsigned DstReg = ForceDstReg
851 ? ForceDstReg
852 : MRI.createVirtualRegister(&AArch64::GPR64RegClass);
853 auto MovI = MIB.buildInstr(AArch64::MOVKXi).addDef(DstReg).addUse(SrcReg);
854 if (auto *GV = dyn_cast<GlobalValue>(V)) {
855 MovI->addOperand(MF, MachineOperand::CreateGA(
856 GV, MovZ->getOperand(1).getOffset(), Flags));
857 } else {
858 MovI->addOperand(
859 MF, MachineOperand::CreateBA(cast<BlockAddress>(V),
860 MovZ->getOperand(1).getOffset(), Flags));
861 }
862 MovI->addOperand(MF, MachineOperand::CreateImm(Offset));
863 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI);
864 return DstReg;
865 };
Aditya Nandakumarfef76192019-02-05 22:14:40 +0000866 unsigned DstReg = BuildMovK(MovZ.getReg(0),
Amara Emerson1e8c1642018-07-31 00:09:02 +0000867 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0);
868 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0);
869 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg());
870 return;
871}
872
Daniel Sandersf76f3152017-11-16 00:46:35 +0000873bool AArch64InstructionSelector::select(MachineInstr &I,
874 CodeGenCoverage &CoverageInfo) const {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000875 assert(I.getParent() && "Instruction should be in a basic block!");
876 assert(I.getParent()->getParent() && "Instruction should be in a function!");
877
878 MachineBasicBlock &MBB = *I.getParent();
879 MachineFunction &MF = *MBB.getParent();
880 MachineRegisterInfo &MRI = MF.getRegInfo();
881
Tim Northovercdf23f12016-10-31 18:30:59 +0000882 unsigned Opcode = I.getOpcode();
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000883 // G_PHI requires same handling as PHI
884 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
Tim Northovercdf23f12016-10-31 18:30:59 +0000885 // Certain non-generic instructions also need some special handling.
886
887 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
888 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000889
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000890 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
Tim Northover7d88da62016-11-08 00:34:06 +0000891 const unsigned DefReg = I.getOperand(0).getReg();
892 const LLT DefTy = MRI.getType(DefReg);
893
894 const TargetRegisterClass *DefRC = nullptr;
895 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
896 DefRC = TRI.getRegClass(DefReg);
897 } else {
898 const RegClassOrRegBank &RegClassOrBank =
899 MRI.getRegClassOrRegBank(DefReg);
900
901 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
902 if (!DefRC) {
903 if (!DefTy.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000904 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000905 return false;
906 }
907 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
908 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
909 if (!DefRC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000910 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000911 return false;
912 }
913 }
914 }
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000915 I.setDesc(TII.get(TargetOpcode::PHI));
Tim Northover7d88da62016-11-08 00:34:06 +0000916
917 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
918 }
919
920 if (I.isCopy())
Tim Northovercdf23f12016-10-31 18:30:59 +0000921 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000922
923 return true;
Tim Northovercdf23f12016-10-31 18:30:59 +0000924 }
925
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000926
927 if (I.getNumOperands() != I.getNumExplicitOperands()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000928 LLVM_DEBUG(
929 dbgs() << "Generic instruction has unexpected implicit operands\n");
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000930 return false;
931 }
932
Daniel Sandersf76f3152017-11-16 00:46:35 +0000933 if (selectImpl(I, CoverageInfo))
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000934 return true;
935
Tim Northover32a078a2016-09-15 10:09:59 +0000936 LLT Ty =
937 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000938
Tim Northover69271c62016-10-12 22:49:11 +0000939 switch (Opcode) {
Tim Northover5e3dbf32016-10-12 22:49:01 +0000940 case TargetOpcode::G_BRCOND: {
941 if (Ty.getSizeInBits() > 32) {
942 // We shouldn't need this on AArch64, but it would be implemented as an
943 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
944 // bit being tested is < 32.
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000945 LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
946 << ", expected at most 32-bits");
Tim Northover5e3dbf32016-10-12 22:49:01 +0000947 return false;
948 }
949
950 const unsigned CondReg = I.getOperand(0).getReg();
951 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
952
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000953 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
954 // instructions will not be produced, as they are conditional branch
955 // instructions that do not set flags.
956 bool ProduceNonFlagSettingCondBr =
957 !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening);
958 if (ProduceNonFlagSettingCondBr && selectCompareBranch(I, MF, MRI))
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000959 return true;
960
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000961 if (ProduceNonFlagSettingCondBr) {
962 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
963 .addUse(CondReg)
964 .addImm(/*bit offset=*/0)
965 .addMBB(DestMBB);
Tim Northover5e3dbf32016-10-12 22:49:01 +0000966
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000967 I.eraseFromParent();
968 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
969 } else {
970 auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
971 .addDef(AArch64::WZR)
972 .addUse(CondReg)
973 .addImm(1);
974 constrainSelectedInstRegOperands(*CMP.getInstr(), TII, TRI, RBI);
975 auto Bcc =
976 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::Bcc))
977 .addImm(AArch64CC::EQ)
978 .addMBB(DestMBB);
979
980 I.eraseFromParent();
981 return constrainSelectedInstRegOperands(*Bcc.getInstr(), TII, TRI, RBI);
982 }
Tim Northover5e3dbf32016-10-12 22:49:01 +0000983 }
984
Kristof Beyls65a12c02017-01-30 09:13:18 +0000985 case TargetOpcode::G_BRINDIRECT: {
986 I.setDesc(TII.get(AArch64::BR));
987 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
988 }
989
Tim Northover4494d692016-10-18 19:47:57 +0000990 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +0000991 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +0000992 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
993
994 const LLT s32 = LLT::scalar(32);
995 const LLT s64 = LLT::scalar(64);
996 const LLT p0 = LLT::pointer(0, 64);
997
998 const unsigned DefReg = I.getOperand(0).getReg();
999 const LLT DefTy = MRI.getType(DefReg);
1000 const unsigned DefSize = DefTy.getSizeInBits();
1001 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1002
1003 // FIXME: Redundant check, but even less readable when factored out.
1004 if (isFP) {
1005 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001006 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1007 << " constant, expected: " << s32 << " or " << s64
1008 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001009 return false;
1010 }
1011
1012 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001013 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1014 << " constant on bank: " << RB
1015 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001016 return false;
1017 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00001018
1019 // The case when we have 0.0 is covered by tablegen. Reject it here so we
1020 // can be sure tablegen works correctly and isn't rescued by this code.
1021 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
1022 return false;
Tim Northover4494d692016-10-18 19:47:57 +00001023 } else {
Daniel Sanders05540042017-08-08 10:44:31 +00001024 // s32 and s64 are covered by tablegen.
1025 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001026 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1027 << " constant, expected: " << s32 << ", " << s64
1028 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001029 return false;
1030 }
1031
1032 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001033 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1034 << " constant on bank: " << RB
1035 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001036 return false;
1037 }
1038 }
1039
1040 const unsigned MovOpc =
1041 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
1042
1043 I.setDesc(TII.get(MovOpc));
1044
1045 if (isFP) {
1046 const TargetRegisterClass &GPRRC =
1047 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
1048 const TargetRegisterClass &FPRRC =
1049 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
1050
1051 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
1052 MachineOperand &RegOp = I.getOperand(0);
1053 RegOp.setReg(DefGPRReg);
1054
1055 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1056 TII.get(AArch64::COPY))
1057 .addDef(DefReg)
1058 .addUse(DefGPRReg);
1059
1060 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001061 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +00001062 return false;
1063 }
1064
1065 MachineOperand &ImmOp = I.getOperand(1);
1066 // FIXME: Is going through int64_t always correct?
1067 ImmOp.ChangeToImmediate(
1068 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001069 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +00001070 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
1071 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001072 } else if (I.getOperand(1).isImm()) {
1073 uint64_t Val = I.getOperand(1).getImm();
1074 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +00001075 }
1076
1077 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1078 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +00001079 }
Tim Northover7b6d66c2017-07-20 22:58:38 +00001080 case TargetOpcode::G_EXTRACT: {
1081 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001082 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +00001083 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +00001084 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001085 // Larger extracts are vectors, same-size extracts should be something else
1086 // by now (either split up or simplified to a COPY).
1087 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
1088 return false;
1089
Amara Emersonbc03bae2018-02-18 17:03:02 +00001090 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001091 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
1092 Ty.getSizeInBits() - 1);
1093
Amara Emersonbc03bae2018-02-18 17:03:02 +00001094 if (SrcSize < 64) {
1095 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
1096 "unexpected G_EXTRACT types");
1097 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1098 }
1099
Tim Northover7b6d66c2017-07-20 22:58:38 +00001100 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1101 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1102 TII.get(AArch64::COPY))
1103 .addDef(I.getOperand(0).getReg())
1104 .addUse(DstReg, 0, AArch64::sub_32);
1105 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
1106 AArch64::GPR32RegClass, MRI);
1107 I.getOperand(0).setReg(DstReg);
1108
1109 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1110 }
1111
1112 case TargetOpcode::G_INSERT: {
1113 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001114 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1115 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001116 // Larger inserts are vectors, same-size ones should be something else by
1117 // now (split up or turned into COPYs).
1118 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
1119 return false;
1120
Amara Emersonbc03bae2018-02-18 17:03:02 +00001121 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001122 unsigned LSB = I.getOperand(3).getImm();
1123 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +00001124 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +00001125 MachineInstrBuilder(MF, I).addImm(Width - 1);
1126
Amara Emersonbc03bae2018-02-18 17:03:02 +00001127 if (DstSize < 64) {
1128 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
1129 "unexpected G_INSERT types");
1130 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1131 }
1132
Tim Northover7b6d66c2017-07-20 22:58:38 +00001133 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1134 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
1135 TII.get(AArch64::SUBREG_TO_REG))
1136 .addDef(SrcReg)
1137 .addImm(0)
1138 .addUse(I.getOperand(2).getReg())
1139 .addImm(AArch64::sub_32);
1140 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
1141 AArch64::GPR32RegClass, MRI);
1142 I.getOperand(2).setReg(SrcReg);
1143
1144 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1145 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001146 case TargetOpcode::G_FRAME_INDEX: {
1147 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +00001148 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001149 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
1150 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001151 return false;
1152 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001153 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001154
1155 // MOs for a #0 shifted immediate.
1156 I.addOperand(MachineOperand::CreateImm(0));
1157 I.addOperand(MachineOperand::CreateImm(0));
1158
1159 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1160 }
Tim Northoverbdf16242016-10-10 21:50:00 +00001161
1162 case TargetOpcode::G_GLOBAL_VALUE: {
1163 auto GV = I.getOperand(1).getGlobal();
1164 if (GV->isThreadLocal()) {
1165 // FIXME: we don't support TLS yet.
1166 return false;
1167 }
1168 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001169 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +00001170 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001171 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001172 } else if (TM.getCodeModel() == CodeModel::Large) {
1173 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +00001174 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001175 I.eraseFromParent();
1176 return true;
David Green9dd1d452018-08-22 11:31:39 +00001177 } else if (TM.getCodeModel() == CodeModel::Tiny) {
1178 I.setDesc(TII.get(AArch64::ADR));
1179 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001180 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +00001181 I.setDesc(TII.get(AArch64::MOVaddr));
1182 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1183 MachineInstrBuilder MIB(MF, I);
1184 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1185 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1186 }
1187 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1188 }
1189
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001190 case TargetOpcode::G_LOAD:
1191 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001192 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001193
Tim Northover5ae83502016-09-15 09:20:34 +00001194 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001195 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1196 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001197 return false;
1198 }
1199
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001200 auto &MemOp = **I.memoperands_begin();
1201 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001202 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001203 return false;
1204 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001205 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001206
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001207 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001208#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001209 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001210 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001211 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1212 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001213 assert(MRI.getType(PtrReg).isPointer() &&
1214 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001215#endif
1216
1217 const unsigned ValReg = I.getOperand(0).getReg();
1218 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1219
1220 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001221 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001222 if (NewOpc == I.getOpcode())
1223 return false;
1224
1225 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001226
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001227 uint64_t Offset = 0;
1228 auto *PtrMI = MRI.getVRegDef(PtrReg);
1229
1230 // Try to fold a GEP into our unsigned immediate addressing mode.
1231 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1232 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1233 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001234 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001235 const unsigned Scale = Log2_32(Size);
1236 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1237 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1238 I.getOperand(1).setReg(Ptr2Reg);
1239 PtrMI = MRI.getVRegDef(Ptr2Reg);
1240 Offset = Imm / Size;
1241 }
1242 }
1243 }
1244
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001245 // If we haven't folded anything into our addressing mode yet, try to fold
1246 // a frame index into the base+offset.
1247 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1248 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1249
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001250 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001251
1252 // If we're storing a 0, use WZR/XZR.
1253 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1254 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1255 if (I.getOpcode() == AArch64::STRWui)
1256 I.getOperand(0).setReg(AArch64::WZR);
1257 else if (I.getOpcode() == AArch64::STRXui)
1258 I.getOperand(0).setReg(AArch64::XZR);
1259 }
1260 }
1261
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001262 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1263 }
1264
Tim Northover9dd78f82017-02-08 21:22:25 +00001265 case TargetOpcode::G_SMULH:
1266 case TargetOpcode::G_UMULH: {
1267 // Reject the various things we don't support yet.
1268 if (unsupportedBinOp(I, RBI, MRI, TRI))
1269 return false;
1270
1271 const unsigned DefReg = I.getOperand(0).getReg();
1272 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1273
1274 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001275 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001276 return false;
1277 }
1278
1279 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001280 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1281 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001282 return false;
1283 }
1284
1285 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1286 : AArch64::UMULHrr;
1287 I.setDesc(TII.get(NewOpc));
1288
1289 // Now that we selected an opcode, we need to constrain the register
1290 // operands to use appropriate classes.
1291 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1292 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001293 case TargetOpcode::G_FADD:
1294 case TargetOpcode::G_FSUB:
1295 case TargetOpcode::G_FMUL:
1296 case TargetOpcode::G_FDIV:
1297
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001298 case TargetOpcode::G_OR:
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001299 case TargetOpcode::G_SHL:
1300 case TargetOpcode::G_LSHR:
1301 case TargetOpcode::G_ASHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001302 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001303 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001304 if (unsupportedBinOp(I, RBI, MRI, TRI))
1305 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001306
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001307 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001308
1309 const unsigned DefReg = I.getOperand(0).getReg();
1310 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1311
1312 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1313 if (NewOpc == I.getOpcode())
1314 return false;
1315
1316 I.setDesc(TII.get(NewOpc));
1317 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001318
1319 // Now that we selected an opcode, we need to constrain the register
1320 // operands to use appropriate classes.
1321 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1322 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001323
Tim Northover398c5f52017-02-14 20:56:29 +00001324 case TargetOpcode::G_PTR_MASK: {
1325 uint64_t Align = I.getOperand(2).getImm();
1326 if (Align >= 64 || Align == 0)
1327 return false;
1328
1329 uint64_t Mask = ~((1ULL << Align) - 1);
1330 I.setDesc(TII.get(AArch64::ANDXri));
1331 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1332
1333 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1334 }
Tim Northover037af52c2016-10-31 18:31:09 +00001335 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001336 case TargetOpcode::G_TRUNC: {
1337 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1338 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1339
1340 const unsigned DstReg = I.getOperand(0).getReg();
1341 const unsigned SrcReg = I.getOperand(1).getReg();
1342
1343 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1344 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1345
1346 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001347 LLVM_DEBUG(
1348 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001349 return false;
1350 }
1351
1352 if (DstRB.getID() == AArch64::GPRRegBankID) {
1353 const TargetRegisterClass *DstRC =
1354 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1355 if (!DstRC)
1356 return false;
1357
1358 const TargetRegisterClass *SrcRC =
1359 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1360 if (!SrcRC)
1361 return false;
1362
1363 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1364 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001365 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001366 return false;
1367 }
1368
1369 if (DstRC == SrcRC) {
1370 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001371 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1372 SrcTy == LLT::scalar(64)) {
1373 llvm_unreachable("TableGen can import this case");
1374 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001375 } else if (DstRC == &AArch64::GPR32RegClass &&
1376 SrcRC == &AArch64::GPR64RegClass) {
1377 I.getOperand(1).setSubReg(AArch64::sub_32);
1378 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001379 LLVM_DEBUG(
1380 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001381 return false;
1382 }
1383
1384 I.setDesc(TII.get(TargetOpcode::COPY));
1385 return true;
1386 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1387 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1388 I.setDesc(TII.get(AArch64::XTNv4i16));
1389 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1390 return true;
1391 }
1392 }
1393
1394 return false;
1395 }
1396
Tim Northover3d38b3a2016-10-11 20:50:21 +00001397 case TargetOpcode::G_ANYEXT: {
1398 const unsigned DstReg = I.getOperand(0).getReg();
1399 const unsigned SrcReg = I.getOperand(1).getReg();
1400
Quentin Colombetcb629a82016-10-12 03:57:49 +00001401 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1402 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001403 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1404 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001405 return false;
1406 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001407
Quentin Colombetcb629a82016-10-12 03:57:49 +00001408 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1409 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001410 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1411 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001412 return false;
1413 }
1414
1415 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1416
1417 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001418 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001419 return false;
1420 }
1421
Quentin Colombetcb629a82016-10-12 03:57:49 +00001422 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001423 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1424 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001425 return false;
1426 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001427 // At this point G_ANYEXT is just like a plain COPY, but we need
1428 // to explicitly form the 64-bit value if any.
1429 if (DstSize > 32) {
1430 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1431 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1432 .addDef(ExtSrc)
1433 .addImm(0)
1434 .addUse(SrcReg)
1435 .addImm(AArch64::sub_32);
1436 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001437 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001438 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001439 }
1440
1441 case TargetOpcode::G_ZEXT:
1442 case TargetOpcode::G_SEXT: {
1443 unsigned Opcode = I.getOpcode();
1444 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1445 SrcTy = MRI.getType(I.getOperand(1).getReg());
1446 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1447 const unsigned DefReg = I.getOperand(0).getReg();
1448 const unsigned SrcReg = I.getOperand(1).getReg();
1449 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1450
1451 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001452 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1453 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001454 return false;
1455 }
1456
1457 MachineInstr *ExtI;
1458 if (DstTy == LLT::scalar(64)) {
1459 // FIXME: Can we avoid manually doing this?
1460 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001461 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1462 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001463 return false;
1464 }
1465
1466 const unsigned SrcXReg =
1467 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1468 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1469 .addDef(SrcXReg)
1470 .addImm(0)
1471 .addUse(SrcReg)
1472 .addImm(AArch64::sub_32);
1473
1474 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1475 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1476 .addDef(DefReg)
1477 .addUse(SrcXReg)
1478 .addImm(0)
1479 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001480 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001481 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1482 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1483 .addDef(DefReg)
1484 .addUse(SrcReg)
1485 .addImm(0)
1486 .addImm(SrcTy.getSizeInBits() - 1);
1487 } else {
1488 return false;
1489 }
1490
1491 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1492
1493 I.eraseFromParent();
1494 return true;
1495 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001496
Tim Northover69271c62016-10-12 22:49:11 +00001497 case TargetOpcode::G_SITOFP:
1498 case TargetOpcode::G_UITOFP:
1499 case TargetOpcode::G_FPTOSI:
1500 case TargetOpcode::G_FPTOUI: {
1501 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1502 SrcTy = MRI.getType(I.getOperand(1).getReg());
1503 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1504 if (NewOpc == Opcode)
1505 return false;
1506
1507 I.setDesc(TII.get(NewOpc));
1508 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1509
1510 return true;
1511 }
1512
1513
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001514 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001515 // The importer is currently unable to import pointer types since they
1516 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001517 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001518
Daniel Sandersedd07842017-08-17 09:26:14 +00001519 case TargetOpcode::G_BITCAST:
1520 // Imported SelectionDAG rules can handle every bitcast except those that
1521 // bitcast from a type to the same type. Ideally, these shouldn't occur
1522 // but we might not run an optimizer that deletes them.
1523 if (MRI.getType(I.getOperand(0).getReg()) ==
1524 MRI.getType(I.getOperand(1).getReg()))
1525 return selectCopy(I, TII, MRI, TRI, RBI);
1526 return false;
1527
Tim Northover9ac0eba2016-11-08 00:45:29 +00001528 case TargetOpcode::G_SELECT: {
1529 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001530 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1531 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001532 return false;
1533 }
1534
1535 const unsigned CondReg = I.getOperand(1).getReg();
1536 const unsigned TReg = I.getOperand(2).getReg();
1537 const unsigned FReg = I.getOperand(3).getReg();
1538
1539 unsigned CSelOpc = 0;
1540
1541 if (Ty == LLT::scalar(32)) {
1542 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001543 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001544 CSelOpc = AArch64::CSELXr;
1545 } else {
1546 return false;
1547 }
1548
1549 MachineInstr &TstMI =
1550 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1551 .addDef(AArch64::WZR)
1552 .addUse(CondReg)
1553 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1554
1555 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1556 .addDef(I.getOperand(0).getReg())
1557 .addUse(TReg)
1558 .addUse(FReg)
1559 .addImm(AArch64CC::NE);
1560
1561 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1562 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1563
1564 I.eraseFromParent();
1565 return true;
1566 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001567 case TargetOpcode::G_ICMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001568 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001569 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1570 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001571 return false;
1572 }
1573
1574 unsigned CmpOpc = 0;
1575 unsigned ZReg = 0;
1576
1577 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1578 if (CmpTy == LLT::scalar(32)) {
1579 CmpOpc = AArch64::SUBSWrr;
1580 ZReg = AArch64::WZR;
1581 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1582 CmpOpc = AArch64::SUBSXrr;
1583 ZReg = AArch64::XZR;
1584 } else {
1585 return false;
1586 }
1587
Kristof Beyls22524402017-01-05 10:16:08 +00001588 // CSINC increments the result by one when the condition code is false.
1589 // Therefore, we have to invert the predicate to get an increment by 1 when
1590 // the predicate is true.
1591 const AArch64CC::CondCode invCC =
1592 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1593 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001594
1595 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1596 .addDef(ZReg)
1597 .addUse(I.getOperand(2).getReg())
1598 .addUse(I.getOperand(3).getReg());
1599
1600 MachineInstr &CSetMI =
1601 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1602 .addDef(I.getOperand(0).getReg())
1603 .addUse(AArch64::WZR)
1604 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001605 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001606
1607 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1608 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1609
1610 I.eraseFromParent();
1611 return true;
1612 }
1613
Tim Northover7dd378d2016-10-12 22:49:07 +00001614 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001615 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001616 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1617 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001618 return false;
1619 }
1620
1621 unsigned CmpOpc = 0;
1622 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1623 if (CmpTy == LLT::scalar(32)) {
1624 CmpOpc = AArch64::FCMPSrr;
1625 } else if (CmpTy == LLT::scalar(64)) {
1626 CmpOpc = AArch64::FCMPDrr;
1627 } else {
1628 return false;
1629 }
1630
1631 // FIXME: regbank
1632
1633 AArch64CC::CondCode CC1, CC2;
1634 changeFCMPPredToAArch64CC(
1635 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1636
1637 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1638 .addUse(I.getOperand(2).getReg())
1639 .addUse(I.getOperand(3).getReg());
1640
1641 const unsigned DefReg = I.getOperand(0).getReg();
1642 unsigned Def1Reg = DefReg;
1643 if (CC2 != AArch64CC::AL)
1644 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1645
1646 MachineInstr &CSetMI =
1647 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1648 .addDef(Def1Reg)
1649 .addUse(AArch64::WZR)
1650 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001651 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001652
1653 if (CC2 != AArch64CC::AL) {
1654 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1655 MachineInstr &CSet2MI =
1656 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1657 .addDef(Def2Reg)
1658 .addUse(AArch64::WZR)
1659 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001660 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001661 MachineInstr &OrMI =
1662 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1663 .addDef(DefReg)
1664 .addUse(Def1Reg)
1665 .addUse(Def2Reg);
1666 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1667 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1668 }
1669
1670 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1671 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1672
1673 I.eraseFromParent();
1674 return true;
1675 }
Tim Northovere9600d82017-02-08 17:57:27 +00001676 case TargetOpcode::G_VASTART:
1677 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1678 : selectVaStartAAPCS(I, MF, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001679 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1680 if (!I.getOperand(0).isIntrinsicID())
1681 return false;
1682 if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1683 return false;
1684 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::BRK))
1685 .addImm(1);
1686 I.eraseFromParent();
1687 return true;
Amara Emerson1e8c1642018-07-31 00:09:02 +00001688 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001689 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001690 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1691 const unsigned DstReg = I.getOperand(0).getReg();
1692 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1693 const TargetRegisterClass *DstRC =
1694 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1695 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001696 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001697 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001698 case TargetOpcode::G_BLOCK_ADDR: {
1699 if (TM.getCodeModel() == CodeModel::Large) {
1700 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1701 I.eraseFromParent();
1702 return true;
1703 } else {
1704 I.setDesc(TII.get(AArch64::MOVaddrBA));
1705 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1706 I.getOperand(0).getReg())
1707 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1708 /* Offset */ 0, AArch64II::MO_PAGE)
1709 .addBlockAddress(
1710 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1711 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1712 I.eraseFromParent();
1713 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1714 }
1715 }
Amara Emerson5ec14602018-12-10 18:44:58 +00001716 case TargetOpcode::G_BUILD_VECTOR:
1717 return selectBuildVector(I, MRI);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001718 case TargetOpcode::G_MERGE_VALUES:
1719 return selectMergeValues(I, MRI);
Jessica Paquette245047d2019-01-24 22:00:41 +00001720 case TargetOpcode::G_UNMERGE_VALUES:
1721 return selectUnmergeValues(I, MRI);
Amara Emerson1abe05c2019-02-21 20:20:16 +00001722 case TargetOpcode::G_SHUFFLE_VECTOR:
1723 return selectShuffleVector(I, MRI);
Jessica Paquette607774c2019-03-11 22:18:01 +00001724 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
1725 return selectExtractElt(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001726 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001727
1728 return false;
1729}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001730
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001731MachineInstr *AArch64InstructionSelector::emitScalarToVector(
Amara Emerson8acb0d92019-03-04 19:16:00 +00001732 unsigned EltSize, const TargetRegisterClass *DstRC, unsigned Scalar,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001733 MachineIRBuilder &MIRBuilder) const {
1734 auto Undef = MIRBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF, {DstRC}, {});
Amara Emerson5ec14602018-12-10 18:44:58 +00001735
1736 auto BuildFn = [&](unsigned SubregIndex) {
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001737 auto Ins =
1738 MIRBuilder
1739 .buildInstr(TargetOpcode::INSERT_SUBREG, {DstRC}, {Undef, Scalar})
1740 .addImm(SubregIndex);
1741 constrainSelectedInstRegOperands(*Undef, TII, TRI, RBI);
1742 constrainSelectedInstRegOperands(*Ins, TII, TRI, RBI);
1743 return &*Ins;
Amara Emerson5ec14602018-12-10 18:44:58 +00001744 };
1745
Amara Emerson8acb0d92019-03-04 19:16:00 +00001746 switch (EltSize) {
Jessica Paquette245047d2019-01-24 22:00:41 +00001747 case 16:
1748 return BuildFn(AArch64::hsub);
Amara Emerson5ec14602018-12-10 18:44:58 +00001749 case 32:
1750 return BuildFn(AArch64::ssub);
1751 case 64:
1752 return BuildFn(AArch64::dsub);
1753 default:
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001754 return nullptr;
Amara Emerson5ec14602018-12-10 18:44:58 +00001755 }
1756}
1757
Amara Emerson8cb186c2018-12-20 01:11:04 +00001758bool AArch64InstructionSelector::selectMergeValues(
1759 MachineInstr &I, MachineRegisterInfo &MRI) const {
1760 assert(I.getOpcode() == TargetOpcode::G_MERGE_VALUES && "unexpected opcode");
1761 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1762 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1763 assert(!DstTy.isVector() && !SrcTy.isVector() && "invalid merge operation");
1764
1765 // At the moment we only support merging two s32s into an s64.
1766 if (I.getNumOperands() != 3)
1767 return false;
1768 if (DstTy.getSizeInBits() != 64 || SrcTy.getSizeInBits() != 32)
1769 return false;
1770 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1771 if (RB.getID() != AArch64::GPRRegBankID)
1772 return false;
1773
1774 auto *DstRC = &AArch64::GPR64RegClass;
1775 unsigned SubToRegDef = MRI.createVirtualRegister(DstRC);
1776 MachineInstr &SubRegMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1777 TII.get(TargetOpcode::SUBREG_TO_REG))
1778 .addDef(SubToRegDef)
1779 .addImm(0)
1780 .addUse(I.getOperand(1).getReg())
1781 .addImm(AArch64::sub_32);
1782 unsigned SubToRegDef2 = MRI.createVirtualRegister(DstRC);
1783 // Need to anyext the second scalar before we can use bfm
1784 MachineInstr &SubRegMI2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1785 TII.get(TargetOpcode::SUBREG_TO_REG))
1786 .addDef(SubToRegDef2)
1787 .addImm(0)
1788 .addUse(I.getOperand(2).getReg())
1789 .addImm(AArch64::sub_32);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001790 MachineInstr &BFM =
1791 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::BFMXri))
Amara Emerson321bfb22018-12-20 03:27:42 +00001792 .addDef(I.getOperand(0).getReg())
Amara Emerson8cb186c2018-12-20 01:11:04 +00001793 .addUse(SubToRegDef)
1794 .addUse(SubToRegDef2)
1795 .addImm(32)
1796 .addImm(31);
1797 constrainSelectedInstRegOperands(SubRegMI, TII, TRI, RBI);
1798 constrainSelectedInstRegOperands(SubRegMI2, TII, TRI, RBI);
1799 constrainSelectedInstRegOperands(BFM, TII, TRI, RBI);
1800 I.eraseFromParent();
1801 return true;
1802}
1803
Jessica Paquette607774c2019-03-11 22:18:01 +00001804static bool getLaneCopyOpcode(unsigned &CopyOpc, unsigned &ExtractSubReg,
1805 const unsigned EltSize) {
1806 // Choose a lane copy opcode and subregister based off of the size of the
1807 // vector's elements.
1808 switch (EltSize) {
1809 case 16:
1810 CopyOpc = AArch64::CPYi16;
1811 ExtractSubReg = AArch64::hsub;
1812 break;
1813 case 32:
1814 CopyOpc = AArch64::CPYi32;
1815 ExtractSubReg = AArch64::ssub;
1816 break;
1817 case 64:
1818 CopyOpc = AArch64::CPYi64;
1819 ExtractSubReg = AArch64::dsub;
1820 break;
1821 default:
1822 // Unknown size, bail out.
1823 LLVM_DEBUG(dbgs() << "Elt size '" << EltSize << "' unsupported.\n");
1824 return false;
1825 }
1826 return true;
1827}
1828
Jessica Paquettebb1aced2019-03-13 21:19:29 +00001829/// Given a register \p Reg, find the value of a constant defining \p Reg.
1830/// Return true if one could be found, and store it in \p Val. Return false
1831/// otherwise.
1832static bool getConstantValueForReg(unsigned Reg, MachineRegisterInfo &MRI,
1833 unsigned &Val) {
1834 // Look at the def of the register.
1835 MachineInstr *Def = MRI.getVRegDef(Reg);
1836 if (!Def)
1837 return false;
1838
1839 // Find the first definition which isn't a copy.
1840 if (Def->isCopy()) {
1841 Reg = Def->getOperand(1).getReg();
1842 auto It = find_if_not(MRI.reg_nodbg_instructions(Reg),
1843 [](const MachineInstr &MI) { return MI.isCopy(); });
1844 if (It == MRI.reg_instr_nodbg_end()) {
1845 LLVM_DEBUG(dbgs() << "Couldn't find non-copy def for register\n");
1846 return false;
1847 }
1848 Def = &*It;
1849 }
1850
1851 // TODO: Handle opcodes other than G_CONSTANT.
1852 if (Def->getOpcode() != TargetOpcode::G_CONSTANT) {
1853 LLVM_DEBUG(dbgs() << "VRegs defined by anything other than G_CONSTANT "
1854 "currently unsupported.\n");
1855 return false;
1856 }
1857
1858 // Return the constant value associated with the operand.
1859 Val = Def->getOperand(1).getCImm()->getLimitedValue();
1860 return true;
1861}
1862
Jessica Paquette607774c2019-03-11 22:18:01 +00001863bool AArch64InstructionSelector::selectExtractElt(
1864 MachineInstr &I, MachineRegisterInfo &MRI) const {
1865 assert(I.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT &&
1866 "unexpected opcode!");
1867 unsigned DstReg = I.getOperand(0).getReg();
1868 const LLT NarrowTy = MRI.getType(DstReg);
1869 const unsigned SrcReg = I.getOperand(1).getReg();
1870 const LLT WideTy = MRI.getType(SrcReg);
1871
1872 assert(WideTy.getSizeInBits() >= NarrowTy.getSizeInBits() &&
1873 "source register size too small!");
1874 assert(NarrowTy.isScalar() && "cannot extract vector into vector!");
1875
1876 // Need the lane index to determine the correct copy opcode.
1877 MachineOperand &LaneIdxOp = I.getOperand(2);
1878 assert(LaneIdxOp.isReg() && "Lane index operand was not a register?");
1879
1880 if (RBI.getRegBank(DstReg, MRI, TRI)->getID() != AArch64::FPRRegBankID) {
1881 LLVM_DEBUG(dbgs() << "Cannot extract into GPR.\n");
1882 return false;
1883 }
1884
Jessica Paquettebb1aced2019-03-13 21:19:29 +00001885 // Find the index to extract from.
1886 unsigned LaneIdx = 0;
1887 if (!getConstantValueForReg(LaneIdxOp.getReg(), MRI, LaneIdx))
Jessica Paquette607774c2019-03-11 22:18:01 +00001888 return false;
Jessica Paquette607774c2019-03-11 22:18:01 +00001889
Jessica Paquette607774c2019-03-11 22:18:01 +00001890 unsigned CopyOpc = 0;
1891 unsigned ExtractSubReg = 0;
1892 if (!getLaneCopyOpcode(CopyOpc, ExtractSubReg, NarrowTy.getSizeInBits())) {
1893 LLVM_DEBUG(
1894 dbgs() << "Couldn't determine lane copy opcode for instruction.\n");
1895 return false;
1896 }
1897
1898 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1899 const TargetRegisterClass *DstRC =
1900 getRegClassForTypeOnBank(NarrowTy, DstRB, RBI, true);
1901 if (!DstRC) {
1902 LLVM_DEBUG(dbgs() << "Could not determine destination register class.\n");
1903 return false;
1904 }
1905
1906 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1907 const TargetRegisterClass *SrcRC =
1908 getRegClassForTypeOnBank(WideTy, SrcRB, RBI, true);
1909 if (!SrcRC) {
1910 LLVM_DEBUG(dbgs() << "Could not determine source register class.\n");
1911 return false;
1912 }
1913
1914 // The register that we're going to copy into.
1915 unsigned InsertReg = SrcReg;
1916 MachineIRBuilder MIRBuilder(I);
1917
1918 // If the lane index is 0, we just use a subregister COPY.
1919 if (LaneIdx == 0) {
1920 unsigned CopyTo = I.getOperand(0).getReg();
1921 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1922 CopyTo)
1923 .addUse(SrcReg, 0, ExtractSubReg);
1924 RBI.constrainGenericRegister(CopyTo, *DstRC, MRI);
1925 I.eraseFromParent();
1926 return true;
1927 }
1928
1929 // Lane copies require 128-bit wide registers. If we're dealing with an
1930 // unpacked vector, then we need to move up to that width. Insert an implicit
1931 // def and a subregister insert to get us there.
1932 if (WideTy.getSizeInBits() != 128) {
1933 MachineInstr *ScalarToVector = emitScalarToVector(
1934 WideTy.getSizeInBits(), &AArch64::FPR128RegClass, SrcReg, MIRBuilder);
1935 if (!ScalarToVector)
1936 return false;
1937 InsertReg = ScalarToVector->getOperand(0).getReg();
1938 }
1939
1940 MachineInstr *LaneCopyMI =
1941 MIRBuilder.buildInstr(CopyOpc, {DstReg}, {InsertReg}).addImm(LaneIdx);
1942 constrainSelectedInstRegOperands(*LaneCopyMI, TII, TRI, RBI);
1943
1944 // Make sure that we actually constrain the initial copy.
1945 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
1946
1947 I.eraseFromParent();
1948 return true;
1949}
1950
Jessica Paquette245047d2019-01-24 22:00:41 +00001951bool AArch64InstructionSelector::selectUnmergeValues(
1952 MachineInstr &I, MachineRegisterInfo &MRI) const {
1953 assert(I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
1954 "unexpected opcode");
1955
1956 // TODO: Handle unmerging into GPRs and from scalars to scalars.
1957 if (RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI)->getID() !=
1958 AArch64::FPRRegBankID ||
1959 RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI)->getID() !=
1960 AArch64::FPRRegBankID) {
1961 LLVM_DEBUG(dbgs() << "Unmerging vector-to-gpr and scalar-to-scalar "
1962 "currently unsupported.\n");
1963 return false;
1964 }
1965
1966 // The last operand is the vector source register, and every other operand is
1967 // a register to unpack into.
1968 unsigned NumElts = I.getNumOperands() - 1;
1969 unsigned SrcReg = I.getOperand(NumElts).getReg();
1970 const LLT NarrowTy = MRI.getType(I.getOperand(0).getReg());
1971 const LLT WideTy = MRI.getType(SrcReg);
Benjamin Kramer653020d2019-01-24 23:45:07 +00001972 (void)WideTy;
Jessica Paquette245047d2019-01-24 22:00:41 +00001973 assert(WideTy.isVector() && "can only unmerge from vector types!");
1974 assert(WideTy.getSizeInBits() > NarrowTy.getSizeInBits() &&
1975 "source register size too small!");
1976
Jessica Paquette1f9bc282019-01-25 21:28:27 +00001977 // TODO: Handle unmerging into vectors.
Jessica Paquette245047d2019-01-24 22:00:41 +00001978 if (!NarrowTy.isScalar()) {
1979 LLVM_DEBUG(dbgs() << "Vector-to-vector unmerges not supported yet.\n");
1980 return false;
1981 }
1982
1983 // Choose a lane copy opcode and subregister based off of the size of the
1984 // vector's elements.
1985 unsigned CopyOpc = 0;
1986 unsigned ExtractSubReg = 0;
Jessica Paquette607774c2019-03-11 22:18:01 +00001987 if (!getLaneCopyOpcode(CopyOpc, ExtractSubReg, NarrowTy.getSizeInBits()))
Jessica Paquette245047d2019-01-24 22:00:41 +00001988 return false;
Jessica Paquette245047d2019-01-24 22:00:41 +00001989
1990 // Set up for the lane copies.
1991 MachineBasicBlock &MBB = *I.getParent();
1992
1993 // Stores the registers we'll be copying from.
1994 SmallVector<unsigned, 4> InsertRegs;
1995
1996 // We'll use the first register twice, so we only need NumElts-1 registers.
1997 unsigned NumInsertRegs = NumElts - 1;
1998
1999 // If our elements fit into exactly 128 bits, then we can copy from the source
2000 // directly. Otherwise, we need to do a bit of setup with some subregister
2001 // inserts.
2002 if (NarrowTy.getSizeInBits() * NumElts == 128) {
2003 InsertRegs = SmallVector<unsigned, 4>(NumInsertRegs, SrcReg);
2004 } else {
2005 // No. We have to perform subregister inserts. For each insert, create an
2006 // implicit def and a subregister insert, and save the register we create.
2007 for (unsigned Idx = 0; Idx < NumInsertRegs; ++Idx) {
2008 unsigned ImpDefReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
2009 MachineInstr &ImpDefMI =
2010 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
2011 ImpDefReg);
2012
2013 // Now, create the subregister insert from SrcReg.
2014 unsigned InsertReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
2015 MachineInstr &InsMI =
2016 *BuildMI(MBB, I, I.getDebugLoc(),
2017 TII.get(TargetOpcode::INSERT_SUBREG), InsertReg)
2018 .addUse(ImpDefReg)
2019 .addUse(SrcReg)
2020 .addImm(AArch64::dsub);
2021
2022 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
2023 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
2024
2025 // Save the register so that we can copy from it after.
2026 InsertRegs.push_back(InsertReg);
2027 }
2028 }
2029
2030 // Now that we've created any necessary subregister inserts, we can
2031 // create the copies.
2032 //
2033 // Perform the first copy separately as a subregister copy.
2034 unsigned CopyTo = I.getOperand(0).getReg();
2035 MachineInstr &FirstCopy =
2036 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), CopyTo)
2037 .addUse(InsertRegs[0], 0, ExtractSubReg);
2038 constrainSelectedInstRegOperands(FirstCopy, TII, TRI, RBI);
2039
2040 // Now, perform the remaining copies as vector lane copies.
2041 unsigned LaneIdx = 1;
2042 for (unsigned InsReg : InsertRegs) {
2043 unsigned CopyTo = I.getOperand(LaneIdx).getReg();
2044 MachineInstr &CopyInst =
2045 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CopyOpc), CopyTo)
2046 .addUse(InsReg)
2047 .addImm(LaneIdx);
2048 constrainSelectedInstRegOperands(CopyInst, TII, TRI, RBI);
2049 ++LaneIdx;
2050 }
2051
2052 // Separately constrain the first copy's destination. Because of the
2053 // limitation in constrainOperandRegClass, we can't guarantee that this will
2054 // actually be constrained. So, do it ourselves using the second operand.
2055 const TargetRegisterClass *RC =
2056 MRI.getRegClassOrNull(I.getOperand(1).getReg());
2057 if (!RC) {
2058 LLVM_DEBUG(dbgs() << "Couldn't constrain copy destination.\n");
2059 return false;
2060 }
2061
2062 RBI.constrainGenericRegister(CopyTo, *RC, MRI);
2063 I.eraseFromParent();
2064 return true;
2065}
2066
Amara Emerson1abe05c2019-02-21 20:20:16 +00002067void AArch64InstructionSelector::collectShuffleMaskIndices(
2068 MachineInstr &I, MachineRegisterInfo &MRI,
2069 SmallVectorImpl<int> &Idxs) const {
2070 MachineInstr *MaskDef = MRI.getVRegDef(I.getOperand(3).getReg());
2071 assert(
2072 MaskDef->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&
2073 "G_SHUFFLE_VECTOR should have a constant mask operand as G_BUILD_VECTOR");
2074 // Find the constant indices.
2075 for (unsigned i = 1, e = MaskDef->getNumOperands(); i < e; ++i) {
2076 MachineInstr *ScalarDef = MRI.getVRegDef(MaskDef->getOperand(i).getReg());
2077 assert(ScalarDef && "Could not find vreg def of shufflevec index op");
2078 // Look through copies.
2079 while (ScalarDef->getOpcode() == TargetOpcode::COPY) {
2080 ScalarDef = MRI.getVRegDef(ScalarDef->getOperand(1).getReg());
2081 assert(ScalarDef && "Could not find def of copy operand");
2082 }
2083 assert(ScalarDef->getOpcode() == TargetOpcode::G_CONSTANT);
2084 Idxs.push_back(ScalarDef->getOperand(1).getCImm()->getSExtValue());
2085 }
2086}
2087
2088unsigned
2089AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
2090 MachineFunction &MF) const {
2091 Type *CPTy = CPVal->getType()->getPointerTo();
2092 unsigned Align = MF.getDataLayout().getPrefTypeAlignment(CPTy);
2093 if (Align == 0)
2094 Align = MF.getDataLayout().getTypeAllocSize(CPTy);
2095
2096 MachineConstantPool *MCP = MF.getConstantPool();
2097 return MCP->getConstantPoolIndex(CPVal, Align);
2098}
2099
2100MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
2101 Constant *CPVal, MachineIRBuilder &MIRBuilder) const {
2102 unsigned CPIdx = emitConstantPoolEntry(CPVal, MIRBuilder.getMF());
2103
2104 auto Adrp =
2105 MIRBuilder.buildInstr(AArch64::ADRP, {&AArch64::GPR64RegClass}, {})
2106 .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002107
2108 MachineInstr *LoadMI = nullptr;
2109 switch (MIRBuilder.getDataLayout().getTypeStoreSize(CPVal->getType())) {
2110 case 16:
2111 LoadMI =
2112 &*MIRBuilder
2113 .buildInstr(AArch64::LDRQui, {&AArch64::FPR128RegClass}, {Adrp})
2114 .addConstantPoolIndex(CPIdx, 0,
2115 AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2116 break;
2117 case 8:
2118 LoadMI = &*MIRBuilder
2119 .buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp})
2120 .addConstantPoolIndex(
2121 CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2122 break;
2123 default:
2124 LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
2125 << *CPVal->getType());
2126 return nullptr;
2127 }
Amara Emerson1abe05c2019-02-21 20:20:16 +00002128 constrainSelectedInstRegOperands(*Adrp, TII, TRI, RBI);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002129 constrainSelectedInstRegOperands(*LoadMI, TII, TRI, RBI);
2130 return LoadMI;
2131}
2132
2133/// Return an <Opcode, SubregIndex> pair to do an vector elt insert of a given
2134/// size and RB.
2135static std::pair<unsigned, unsigned>
2136getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
2137 unsigned Opc, SubregIdx;
2138 if (RB.getID() == AArch64::GPRRegBankID) {
2139 if (EltSize == 32) {
2140 Opc = AArch64::INSvi32gpr;
2141 SubregIdx = AArch64::ssub;
2142 } else if (EltSize == 64) {
2143 Opc = AArch64::INSvi64gpr;
2144 SubregIdx = AArch64::dsub;
2145 } else {
2146 llvm_unreachable("invalid elt size!");
2147 }
2148 } else {
2149 if (EltSize == 8) {
2150 Opc = AArch64::INSvi8lane;
2151 SubregIdx = AArch64::bsub;
2152 } else if (EltSize == 16) {
2153 Opc = AArch64::INSvi16lane;
2154 SubregIdx = AArch64::hsub;
2155 } else if (EltSize == 32) {
2156 Opc = AArch64::INSvi32lane;
2157 SubregIdx = AArch64::ssub;
2158 } else if (EltSize == 64) {
2159 Opc = AArch64::INSvi64lane;
2160 SubregIdx = AArch64::dsub;
2161 } else {
2162 llvm_unreachable("invalid elt size!");
2163 }
2164 }
2165 return std::make_pair(Opc, SubregIdx);
2166}
2167
2168MachineInstr *AArch64InstructionSelector::emitVectorConcat(
2169 unsigned Op1, unsigned Op2, MachineIRBuilder &MIRBuilder) const {
2170 // We implement a vector concat by:
2171 // 1. Use scalar_to_vector to insert the lower vector into the larger dest
2172 // 2. Insert the upper vector into the destination's upper element
2173 // TODO: some of this code is common with G_BUILD_VECTOR handling.
2174 MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
2175
2176 const LLT Op1Ty = MRI.getType(Op1);
2177 const LLT Op2Ty = MRI.getType(Op2);
2178
2179 if (Op1Ty != Op2Ty) {
2180 LLVM_DEBUG(dbgs() << "Could not do vector concat of differing vector tys");
2181 return nullptr;
2182 }
2183 assert(Op1Ty.isVector() && "Expected a vector for vector concat");
2184
2185 if (Op1Ty.getSizeInBits() >= 128) {
2186 LLVM_DEBUG(dbgs() << "Vector concat not supported for full size vectors");
2187 return nullptr;
2188 }
2189
2190 // At the moment we just support 64 bit vector concats.
2191 if (Op1Ty.getSizeInBits() != 64) {
2192 LLVM_DEBUG(dbgs() << "Vector concat supported for 64b vectors");
2193 return nullptr;
2194 }
2195
2196 const LLT ScalarTy = LLT::scalar(Op1Ty.getSizeInBits());
2197 const RegisterBank &FPRBank = *RBI.getRegBank(Op1, MRI, TRI);
2198 const TargetRegisterClass *DstRC =
2199 getMinClassForRegBank(FPRBank, Op1Ty.getSizeInBits() * 2);
2200
2201 MachineInstr *WidenedOp1 =
2202 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op1, MIRBuilder);
2203 MachineInstr *WidenedOp2 =
2204 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op2, MIRBuilder);
2205 if (!WidenedOp1 || !WidenedOp2) {
2206 LLVM_DEBUG(dbgs() << "Could not emit a vector from scalar value");
2207 return nullptr;
2208 }
2209
2210 // Now do the insert of the upper element.
2211 unsigned InsertOpc, InsSubRegIdx;
2212 std::tie(InsertOpc, InsSubRegIdx) =
2213 getInsertVecEltOpInfo(FPRBank, ScalarTy.getSizeInBits());
2214
2215 auto InsElt =
2216 MIRBuilder
2217 .buildInstr(InsertOpc, {DstRC}, {WidenedOp1->getOperand(0).getReg()})
2218 .addImm(1) /* Lane index */
2219 .addUse(WidenedOp2->getOperand(0).getReg())
2220 .addImm(0);
2221
2222 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2223 return &*InsElt;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002224}
2225
2226bool AArch64InstructionSelector::selectShuffleVector(
2227 MachineInstr &I, MachineRegisterInfo &MRI) const {
2228 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2229 unsigned Src1Reg = I.getOperand(1).getReg();
2230 const LLT Src1Ty = MRI.getType(Src1Reg);
2231 unsigned Src2Reg = I.getOperand(2).getReg();
2232 const LLT Src2Ty = MRI.getType(Src2Reg);
2233
2234 MachineBasicBlock &MBB = *I.getParent();
2235 MachineFunction &MF = *MBB.getParent();
2236 LLVMContext &Ctx = MF.getFunction().getContext();
2237
2238 // G_SHUFFLE_VECTOR doesn't really have a strictly enforced constant mask
2239 // operand, it comes in as a normal vector value which we have to analyze to
2240 // find the mask indices.
2241 SmallVector<int, 8> Mask;
2242 collectShuffleMaskIndices(I, MRI, Mask);
2243 assert(!Mask.empty() && "Expected to find mask indices");
2244
2245 // G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
2246 // it's originated from a <1 x T> type. Those should have been lowered into
2247 // G_BUILD_VECTOR earlier.
2248 if (!Src1Ty.isVector() || !Src2Ty.isVector()) {
2249 LLVM_DEBUG(dbgs() << "Could not select a \"scalar\" G_SHUFFLE_VECTOR\n");
2250 return false;
2251 }
2252
2253 unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
2254
2255 SmallVector<Constant *, 64> CstIdxs;
2256 for (int Val : Mask) {
2257 for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
2258 unsigned Offset = Byte + Val * BytesPerElt;
2259 CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));
2260 }
2261 }
2262
Amara Emerson8acb0d92019-03-04 19:16:00 +00002263 MachineIRBuilder MIRBuilder(I);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002264
2265 // Use a constant pool to load the index vector for TBL.
2266 Constant *CPVal = ConstantVector::get(CstIdxs);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002267 MachineInstr *IndexLoad = emitLoadFromConstantPool(CPVal, MIRBuilder);
2268 if (!IndexLoad) {
2269 LLVM_DEBUG(dbgs() << "Could not load from a constant pool");
2270 return false;
2271 }
2272
Amara Emerson8acb0d92019-03-04 19:16:00 +00002273 if (DstTy.getSizeInBits() != 128) {
2274 assert(DstTy.getSizeInBits() == 64 && "Unexpected shuffle result ty");
2275 // This case can be done with TBL1.
2276 MachineInstr *Concat = emitVectorConcat(Src1Reg, Src2Reg, MIRBuilder);
2277 if (!Concat) {
2278 LLVM_DEBUG(dbgs() << "Could not do vector concat for tbl1");
2279 return false;
2280 }
2281
2282 // The constant pool load will be 64 bits, so need to convert to FPR128 reg.
2283 IndexLoad =
2284 emitScalarToVector(64, &AArch64::FPR128RegClass,
2285 IndexLoad->getOperand(0).getReg(), MIRBuilder);
2286
2287 auto TBL1 = MIRBuilder.buildInstr(
2288 AArch64::TBLv16i8One, {&AArch64::FPR128RegClass},
2289 {Concat->getOperand(0).getReg(), IndexLoad->getOperand(0).getReg()});
2290 constrainSelectedInstRegOperands(*TBL1, TII, TRI, RBI);
2291
2292 auto Copy = BuildMI(*I.getParent(), I, I.getDebugLoc(),
2293 TII.get(TargetOpcode::COPY), I.getOperand(0).getReg())
2294 .addUse(TBL1->getOperand(0).getReg(), 0, AArch64::dsub);
2295 RBI.constrainGenericRegister(Copy.getReg(0), AArch64::FPR64RegClass, MRI);
2296 I.eraseFromParent();
2297 return true;
2298 }
2299
Amara Emerson1abe05c2019-02-21 20:20:16 +00002300 // For TBL2 we need to emit a REG_SEQUENCE to tie together two consecutive
2301 // Q registers for regalloc.
2302 auto RegSeq = MIRBuilder
2303 .buildInstr(TargetOpcode::REG_SEQUENCE,
2304 {&AArch64::QQRegClass}, {Src1Reg})
2305 .addImm(AArch64::qsub0)
2306 .addUse(Src2Reg)
2307 .addImm(AArch64::qsub1);
2308
2309 auto TBL2 =
2310 MIRBuilder.buildInstr(AArch64::TBLv16i8Two, {I.getOperand(0).getReg()},
2311 {RegSeq, IndexLoad->getOperand(0).getReg()});
2312 constrainSelectedInstRegOperands(*RegSeq, TII, TRI, RBI);
2313 constrainSelectedInstRegOperands(*TBL2, TII, TRI, RBI);
2314 I.eraseFromParent();
2315 return true;
2316}
2317
Jessica Paquette16d67a32019-03-13 23:22:23 +00002318MachineInstr *AArch64InstructionSelector::emitLaneInsert(
2319 Optional<unsigned> DstReg, unsigned SrcReg, unsigned EltReg,
2320 unsigned LaneIdx, const RegisterBank &RB,
2321 MachineIRBuilder &MIRBuilder) const {
2322 MachineInstr *InsElt = nullptr;
2323 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
2324 MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
2325
2326 // Create a register to define with the insert if one wasn't passed in.
2327 if (!DstReg)
2328 DstReg = MRI.createVirtualRegister(DstRC);
2329
2330 unsigned EltSize = MRI.getType(EltReg).getSizeInBits();
2331 unsigned Opc = getInsertVecEltOpInfo(RB, EltSize).first;
2332
2333 if (RB.getID() == AArch64::FPRRegBankID) {
2334 auto InsSub = emitScalarToVector(EltSize, DstRC, EltReg, MIRBuilder);
2335 InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
2336 .addImm(LaneIdx)
2337 .addUse(InsSub->getOperand(0).getReg())
2338 .addImm(0);
2339 } else {
2340 InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
2341 .addImm(LaneIdx)
2342 .addUse(EltReg);
2343 }
2344
2345 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2346 return InsElt;
2347}
2348
Amara Emerson5ec14602018-12-10 18:44:58 +00002349bool AArch64InstructionSelector::selectBuildVector(
2350 MachineInstr &I, MachineRegisterInfo &MRI) const {
2351 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
2352 // Until we port more of the optimized selections, for now just use a vector
2353 // insert sequence.
2354 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2355 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
2356 unsigned EltSize = EltTy.getSizeInBits();
Jessica Paquette245047d2019-01-24 22:00:41 +00002357 if (EltSize < 16 || EltSize > 64)
Amara Emerson5ec14602018-12-10 18:44:58 +00002358 return false; // Don't support all element types yet.
2359 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002360 MachineIRBuilder MIRBuilder(I);
Jessica Paquette245047d2019-01-24 22:00:41 +00002361
2362 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002363 MachineInstr *ScalarToVec =
Amara Emerson8acb0d92019-03-04 19:16:00 +00002364 emitScalarToVector(DstTy.getElementType().getSizeInBits(), DstRC,
2365 I.getOperand(1).getReg(), MIRBuilder);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002366 if (!ScalarToVec)
Jessica Paquette245047d2019-01-24 22:00:41 +00002367 return false;
2368
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002369 unsigned DstVec = ScalarToVec->getOperand(0).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +00002370 unsigned DstSize = DstTy.getSizeInBits();
2371
2372 // Keep track of the last MI we inserted. Later on, we might be able to save
2373 // a copy using it.
2374 MachineInstr *PrevMI = nullptr;
2375 for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
Jessica Paquette16d67a32019-03-13 23:22:23 +00002376 // Note that if we don't do a subregister copy, we can end up making an
2377 // extra register.
2378 PrevMI = &*emitLaneInsert(None, DstVec, I.getOperand(i).getReg(), i - 1, RB,
2379 MIRBuilder);
2380 DstVec = PrevMI->getOperand(0).getReg();
Amara Emerson5ec14602018-12-10 18:44:58 +00002381 }
Jessica Paquette245047d2019-01-24 22:00:41 +00002382
2383 // If DstTy's size in bits is less than 128, then emit a subregister copy
2384 // from DstVec to the last register we've defined.
2385 if (DstSize < 128) {
Jessica Paquette85ace622019-03-13 23:29:54 +00002386 // Force this to be FPR using the destination vector.
2387 const TargetRegisterClass *RC =
2388 getMinClassForRegBank(*RBI.getRegBank(DstVec, MRI, TRI), DstSize);
Jessica Paquette245047d2019-01-24 22:00:41 +00002389 if (!RC)
2390 return false;
Jessica Paquette85ace622019-03-13 23:29:54 +00002391 if (RC != &AArch64::FPR32RegClass && RC != &AArch64::FPR64RegClass) {
2392 LLVM_DEBUG(dbgs() << "Unsupported register class!\n");
2393 return false;
2394 }
2395
2396 unsigned SubReg = 0;
2397 if (!getSubRegForClass(RC, TRI, SubReg))
2398 return false;
2399 if (SubReg != AArch64::ssub && SubReg != AArch64::dsub) {
2400 LLVM_DEBUG(dbgs() << "Unsupported destination size! (" << DstSize
2401 << "\n");
2402 return false;
2403 }
Jessica Paquette245047d2019-01-24 22:00:41 +00002404
2405 unsigned Reg = MRI.createVirtualRegister(RC);
2406 unsigned DstReg = I.getOperand(0).getReg();
2407
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002408 // MIRBuilder doesn't let us create uses with subregs & flags, so use
2409 // BuildMI here instead.
Jessica Paquette245047d2019-01-24 22:00:41 +00002410 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
2411 DstReg)
2412 .addUse(DstVec, 0, SubReg);
2413 MachineOperand &RegOp = I.getOperand(1);
2414 RegOp.setReg(Reg);
2415 RBI.constrainGenericRegister(DstReg, *RC, MRI);
2416 } else {
2417 // We don't need a subregister copy. Save a copy by re-using the
2418 // destination register on the final insert.
2419 assert(PrevMI && "PrevMI was null?");
2420 PrevMI->getOperand(0).setReg(I.getOperand(0).getReg());
2421 constrainSelectedInstRegOperands(*PrevMI, TII, TRI, RBI);
2422 }
2423
Amara Emerson5ec14602018-12-10 18:44:58 +00002424 I.eraseFromParent();
2425 return true;
2426}
2427
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002428/// SelectArithImmed - Select an immediate value that can be represented as
2429/// a 12-bit value shifted left by either 0 or 12. If so, return true with
2430/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002431InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00002432AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002433 MachineInstr &MI = *Root.getParent();
2434 MachineBasicBlock &MBB = *MI.getParent();
2435 MachineFunction &MF = *MBB.getParent();
2436 MachineRegisterInfo &MRI = MF.getRegInfo();
2437
2438 // This function is called from the addsub_shifted_imm ComplexPattern,
2439 // which lists [imm] as the list of opcode it's interested in, however
2440 // we still need to check whether the operand is actually an immediate
2441 // here because the ComplexPattern opcode list is only used in
2442 // root-level opcode matching.
2443 uint64_t Immed;
2444 if (Root.isImm())
2445 Immed = Root.getImm();
2446 else if (Root.isCImm())
2447 Immed = Root.getCImm()->getZExtValue();
2448 else if (Root.isReg()) {
2449 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
2450 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002451 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002452 MachineOperand &Op1 = Def->getOperand(1);
2453 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002454 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002455 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002456 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002457 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002458
2459 unsigned ShiftAmt;
2460
2461 if (Immed >> 12 == 0) {
2462 ShiftAmt = 0;
2463 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
2464 ShiftAmt = 12;
2465 Immed = Immed >> 12;
2466 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002467 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002468
2469 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002470 return {{
2471 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
2472 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
2473 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002474}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002475
Daniel Sandersea8711b2017-10-16 03:36:29 +00002476/// Select a "register plus unscaled signed 9-bit immediate" address. This
2477/// should only match when there is an offset that is not valid for a scaled
2478/// immediate addressing mode. The "Size" argument is the size in bytes of the
2479/// memory reference, which is needed here to know what is valid for a scaled
2480/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002481InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002482AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
2483 unsigned Size) const {
2484 MachineRegisterInfo &MRI =
2485 Root.getParent()->getParent()->getParent()->getRegInfo();
2486
2487 if (!Root.isReg())
2488 return None;
2489
2490 if (!isBaseWithConstantOffset(Root, MRI))
2491 return None;
2492
2493 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2494 if (!RootDef)
2495 return None;
2496
2497 MachineOperand &OffImm = RootDef->getOperand(2);
2498 if (!OffImm.isReg())
2499 return None;
2500 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
2501 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
2502 return None;
2503 int64_t RHSC;
2504 MachineOperand &RHSOp1 = RHS->getOperand(1);
2505 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
2506 return None;
2507 RHSC = RHSOp1.getCImm()->getSExtValue();
2508
2509 // If the offset is valid as a scaled immediate, don't match here.
2510 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
2511 return None;
2512 if (RHSC >= -256 && RHSC < 256) {
2513 MachineOperand &Base = RootDef->getOperand(1);
2514 return {{
2515 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
2516 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
2517 }};
2518 }
2519 return None;
2520}
2521
2522/// Select a "register plus scaled unsigned 12-bit immediate" address. The
2523/// "Size" argument is the size in bytes of the memory reference, which
2524/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002525InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002526AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
2527 unsigned Size) const {
2528 MachineRegisterInfo &MRI =
2529 Root.getParent()->getParent()->getParent()->getRegInfo();
2530
2531 if (!Root.isReg())
2532 return None;
2533
2534 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2535 if (!RootDef)
2536 return None;
2537
2538 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
2539 return {{
2540 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
2541 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2542 }};
2543 }
2544
2545 if (isBaseWithConstantOffset(Root, MRI)) {
2546 MachineOperand &LHS = RootDef->getOperand(1);
2547 MachineOperand &RHS = RootDef->getOperand(2);
2548 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
2549 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
2550 if (LHSDef && RHSDef) {
2551 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
2552 unsigned Scale = Log2_32(Size);
2553 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
2554 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00002555 return {{
2556 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
2557 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2558 }};
2559
Daniel Sandersea8711b2017-10-16 03:36:29 +00002560 return {{
2561 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
2562 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2563 }};
2564 }
2565 }
2566 }
2567
2568 // Before falling back to our general case, check if the unscaled
2569 // instructions can handle this. If so, that's preferable.
2570 if (selectAddrModeUnscaled(Root, Size).hasValue())
2571 return None;
2572
2573 return {{
2574 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
2575 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2576 }};
2577}
2578
Volkan Kelesf7f25682018-01-16 18:44:05 +00002579void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
2580 const MachineInstr &MI) const {
2581 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2582 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
2583 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
2584 assert(CstVal && "Expected constant value");
2585 MIB.addImm(CstVal.getValue());
2586}
2587
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002588namespace llvm {
2589InstructionSelector *
2590createAArch64InstructionSelector(const AArch64TargetMachine &TM,
2591 AArch64Subtarget &Subtarget,
2592 AArch64RegisterBankInfo &RBI) {
2593 return new AArch64InstructionSelector(TM, Subtarget, RBI);
2594}
2595}