blob: 7f40d83bcd2c7916ac4a65872c6427869b49b905 [file] [log] [blame]
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001//===- AArch64InstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for
10/// AArch64.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000014#include "AArch64InstrInfo.h"
Tim Northovere9600d82017-02-08 17:57:27 +000015#include "AArch64MachineFunctionInfo.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000016#include "AArch64RegisterBankInfo.h"
17#include "AArch64RegisterInfo.h"
18#include "AArch64Subtarget.h"
Tim Northoverbdf16242016-10-10 21:50:00 +000019#include "AArch64TargetMachine.h"
Tim Northover9ac0eba2016-11-08 00:45:29 +000020#include "MCTargetDesc/AArch64AddressingModes.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000021#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
David Blaikie62651302017-10-26 23:39:54 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Amara Emerson1e8c1642018-07-31 00:09:02 +000023#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Aditya Nandakumar75ad9cc2017-04-19 20:48:50 +000024#include "llvm/CodeGen/GlobalISel/Utils.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000025#include "llvm/CodeGen/MachineBasicBlock.h"
26#include "llvm/CodeGen/MachineFunction.h"
27#include "llvm/CodeGen/MachineInstr.h"
28#include "llvm/CodeGen/MachineInstrBuilder.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000029#include "llvm/CodeGen/MachineOperand.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000030#include "llvm/CodeGen/MachineRegisterInfo.h"
31#include "llvm/IR/Type.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/Support/raw_ostream.h"
34
35#define DEBUG_TYPE "aarch64-isel"
36
37using namespace llvm;
38
Daniel Sanders0b5293f2017-04-06 09:49:34 +000039namespace {
40
Daniel Sanderse7b0d662017-04-21 15:59:56 +000041#define GET_GLOBALISEL_PREDICATE_BITSET
42#include "AArch64GenGlobalISel.inc"
43#undef GET_GLOBALISEL_PREDICATE_BITSET
44
Daniel Sanders0b5293f2017-04-06 09:49:34 +000045class AArch64InstructionSelector : public InstructionSelector {
46public:
47 AArch64InstructionSelector(const AArch64TargetMachine &TM,
48 const AArch64Subtarget &STI,
49 const AArch64RegisterBankInfo &RBI);
50
Daniel Sandersf76f3152017-11-16 00:46:35 +000051 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000052 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000053
54private:
55 /// tblgen-erated 'select' implementation, used as the initial selector for
56 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000057 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000058
59 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF,
60 MachineRegisterInfo &MRI) const;
61 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
62 MachineRegisterInfo &MRI) const;
63
64 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
65 MachineRegisterInfo &MRI) const;
66
Amara Emerson5ec14602018-12-10 18:44:58 +000067 // Helper to generate an equivalent of scalar_to_vector into a new register,
68 // returned via 'Dst'.
69 bool emitScalarToVector(unsigned &Dst, const LLT DstTy,
70 const TargetRegisterClass *DstRC, unsigned Scalar,
71 MachineBasicBlock &MBB,
72 MachineBasicBlock::iterator MBBI,
73 MachineRegisterInfo &MRI) const;
74 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson8cb186c2018-12-20 01:11:04 +000075 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000076
Daniel Sanders1e4569f2017-10-20 20:55:29 +000077 ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000078
Daniel Sanders1e4569f2017-10-20 20:55:29 +000079 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root,
80 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +000081
Daniel Sanders1e4569f2017-10-20 20:55:29 +000082 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000083 return selectAddrModeUnscaled(Root, 1);
84 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000085 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000086 return selectAddrModeUnscaled(Root, 2);
87 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000088 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000089 return selectAddrModeUnscaled(Root, 4);
90 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000091 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000092 return selectAddrModeUnscaled(Root, 8);
93 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000094 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000095 return selectAddrModeUnscaled(Root, 16);
96 }
97
Daniel Sanders1e4569f2017-10-20 20:55:29 +000098 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root,
99 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000100 template <int Width>
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000101 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000102 return selectAddrModeIndexed(Root, Width / 8);
103 }
104
Volkan Kelesf7f25682018-01-16 18:44:05 +0000105 void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const;
106
Amara Emerson1e8c1642018-07-31 00:09:02 +0000107 // Materialize a GlobalValue or BlockAddress using a movz+movk sequence.
108 void materializeLargeCMVal(MachineInstr &I, const Value *V,
109 unsigned char OpFlags) const;
110
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000111 const AArch64TargetMachine &TM;
112 const AArch64Subtarget &STI;
113 const AArch64InstrInfo &TII;
114 const AArch64RegisterInfo &TRI;
115 const AArch64RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000116
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000117#define GET_GLOBALISEL_PREDICATES_DECL
118#include "AArch64GenGlobalISel.inc"
119#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000120
121// We declare the temporaries used by selectImpl() in the class to minimize the
122// cost of constructing placeholder values.
123#define GET_GLOBALISEL_TEMPORARIES_DECL
124#include "AArch64GenGlobalISel.inc"
125#undef GET_GLOBALISEL_TEMPORARIES_DECL
126};
127
128} // end anonymous namespace
129
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000130#define GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000131#include "AArch64GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000132#undef GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000133
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000134AArch64InstructionSelector::AArch64InstructionSelector(
Tim Northoverbdf16242016-10-10 21:50:00 +0000135 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
136 const AArch64RegisterBankInfo &RBI)
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000137 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000138 TRI(*STI.getRegisterInfo()), RBI(RBI),
139#define GET_GLOBALISEL_PREDICATES_INIT
140#include "AArch64GenGlobalISel.inc"
141#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000142#define GET_GLOBALISEL_TEMPORARIES_INIT
143#include "AArch64GenGlobalISel.inc"
144#undef GET_GLOBALISEL_TEMPORARIES_INIT
145{
146}
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000147
Tim Northoverfb8d9892016-10-12 22:49:15 +0000148// FIXME: This should be target-independent, inferred from the types declared
149// for each class in the bank.
150static const TargetRegisterClass *
151getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
Amara Emerson3838ed02018-02-02 18:03:30 +0000152 const RegisterBankInfo &RBI,
153 bool GetAllRegSet = false) {
Tim Northoverfb8d9892016-10-12 22:49:15 +0000154 if (RB.getID() == AArch64::GPRRegBankID) {
155 if (Ty.getSizeInBits() <= 32)
Amara Emerson3838ed02018-02-02 18:03:30 +0000156 return GetAllRegSet ? &AArch64::GPR32allRegClass
157 : &AArch64::GPR32RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000158 if (Ty.getSizeInBits() == 64)
Amara Emerson3838ed02018-02-02 18:03:30 +0000159 return GetAllRegSet ? &AArch64::GPR64allRegClass
160 : &AArch64::GPR64RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000161 return nullptr;
162 }
163
164 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson3838ed02018-02-02 18:03:30 +0000165 if (Ty.getSizeInBits() <= 16)
166 return &AArch64::FPR16RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000167 if (Ty.getSizeInBits() == 32)
168 return &AArch64::FPR32RegClass;
169 if (Ty.getSizeInBits() == 64)
170 return &AArch64::FPR64RegClass;
171 if (Ty.getSizeInBits() == 128)
172 return &AArch64::FPR128RegClass;
173 return nullptr;
174 }
175
176 return nullptr;
177}
178
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000179/// Check whether \p I is a currently unsupported binary operation:
180/// - it has an unsized type
181/// - an operand is not a vreg
182/// - all operands are not in the same bank
183/// These are checks that should someday live in the verifier, but right now,
184/// these are mostly limitations of the aarch64 selector.
185static bool unsupportedBinOp(const MachineInstr &I,
186 const AArch64RegisterBankInfo &RBI,
187 const MachineRegisterInfo &MRI,
188 const AArch64RegisterInfo &TRI) {
Tim Northover0f140c72016-09-09 11:46:34 +0000189 LLT Ty = MRI.getType(I.getOperand(0).getReg());
Tim Northover32a078a2016-09-15 10:09:59 +0000190 if (!Ty.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000191 LLVM_DEBUG(dbgs() << "Generic binop register should be typed\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000192 return true;
193 }
194
195 const RegisterBank *PrevOpBank = nullptr;
196 for (auto &MO : I.operands()) {
197 // FIXME: Support non-register operands.
198 if (!MO.isReg()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000199 LLVM_DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000200 return true;
201 }
202
203 // FIXME: Can generic operations have physical registers operands? If
204 // so, this will need to be taught about that, and we'll need to get the
205 // bank out of the minimal class for the register.
206 // Either way, this needs to be documented (and possibly verified).
207 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000208 LLVM_DEBUG(dbgs() << "Generic inst has physical register operand\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000209 return true;
210 }
211
212 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI);
213 if (!OpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000214 LLVM_DEBUG(dbgs() << "Generic register has no bank or class\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000215 return true;
216 }
217
218 if (PrevOpBank && OpBank != PrevOpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000219 LLVM_DEBUG(dbgs() << "Generic inst operands have different banks\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000220 return true;
221 }
222 PrevOpBank = OpBank;
223 }
224 return false;
225}
226
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000227/// Select the AArch64 opcode for the basic binary operation \p GenericOpc
Ahmed Bougachacfb384d2017-01-23 21:10:05 +0000228/// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000229/// and of size \p OpSize.
230/// \returns \p GenericOpc if the combination is unsupported.
231static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
232 unsigned OpSize) {
233 switch (RegBankID) {
234 case AArch64::GPRRegBankID:
Ahmed Bougacha05a5f7d2017-01-25 02:41:38 +0000235 if (OpSize == 32) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000236 switch (GenericOpc) {
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000237 case TargetOpcode::G_SHL:
238 return AArch64::LSLVWr;
239 case TargetOpcode::G_LSHR:
240 return AArch64::LSRVWr;
241 case TargetOpcode::G_ASHR:
242 return AArch64::ASRVWr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000243 default:
244 return GenericOpc;
245 }
Tim Northover55782222016-10-18 20:03:48 +0000246 } else if (OpSize == 64) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000247 switch (GenericOpc) {
Tim Northover2fda4b02016-10-10 21:49:49 +0000248 case TargetOpcode::G_GEP:
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000249 return AArch64::ADDXrr;
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000250 case TargetOpcode::G_SHL:
251 return AArch64::LSLVXr;
252 case TargetOpcode::G_LSHR:
253 return AArch64::LSRVXr;
254 case TargetOpcode::G_ASHR:
255 return AArch64::ASRVXr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000256 default:
257 return GenericOpc;
258 }
259 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000260 break;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000261 case AArch64::FPRRegBankID:
262 switch (OpSize) {
263 case 32:
264 switch (GenericOpc) {
265 case TargetOpcode::G_FADD:
266 return AArch64::FADDSrr;
267 case TargetOpcode::G_FSUB:
268 return AArch64::FSUBSrr;
269 case TargetOpcode::G_FMUL:
270 return AArch64::FMULSrr;
271 case TargetOpcode::G_FDIV:
272 return AArch64::FDIVSrr;
273 default:
274 return GenericOpc;
275 }
276 case 64:
277 switch (GenericOpc) {
278 case TargetOpcode::G_FADD:
279 return AArch64::FADDDrr;
280 case TargetOpcode::G_FSUB:
281 return AArch64::FSUBDrr;
282 case TargetOpcode::G_FMUL:
283 return AArch64::FMULDrr;
284 case TargetOpcode::G_FDIV:
285 return AArch64::FDIVDrr;
Quentin Colombet0e531272016-10-11 00:21:11 +0000286 case TargetOpcode::G_OR:
287 return AArch64::ORRv8i8;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000288 default:
289 return GenericOpc;
290 }
291 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000292 break;
293 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000294 return GenericOpc;
295}
296
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000297/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
298/// appropriate for the (value) register bank \p RegBankID and of memory access
299/// size \p OpSize. This returns the variant with the base+unsigned-immediate
300/// addressing mode (e.g., LDRXui).
301/// \returns \p GenericOpc if the combination is unsupported.
302static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
303 unsigned OpSize) {
304 const bool isStore = GenericOpc == TargetOpcode::G_STORE;
305 switch (RegBankID) {
306 case AArch64::GPRRegBankID:
307 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000308 case 8:
309 return isStore ? AArch64::STRBBui : AArch64::LDRBBui;
310 case 16:
311 return isStore ? AArch64::STRHHui : AArch64::LDRHHui;
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000312 case 32:
313 return isStore ? AArch64::STRWui : AArch64::LDRWui;
314 case 64:
315 return isStore ? AArch64::STRXui : AArch64::LDRXui;
316 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000317 break;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000318 case AArch64::FPRRegBankID:
319 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000320 case 8:
321 return isStore ? AArch64::STRBui : AArch64::LDRBui;
322 case 16:
323 return isStore ? AArch64::STRHui : AArch64::LDRHui;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000324 case 32:
325 return isStore ? AArch64::STRSui : AArch64::LDRSui;
326 case 64:
327 return isStore ? AArch64::STRDui : AArch64::LDRDui;
328 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000329 break;
330 }
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000331 return GenericOpc;
332}
333
Amara Emersondb211892018-02-20 05:11:57 +0000334static bool selectFP16CopyFromGPR32(MachineInstr &I, const TargetInstrInfo &TII,
335 MachineRegisterInfo &MRI, unsigned SrcReg) {
336 // Copies from gpr32 to fpr16 need to use a sub-register copy.
337 unsigned CopyReg = MRI.createVirtualRegister(&AArch64::FPR32RegClass);
338 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::COPY))
339 .addDef(CopyReg)
340 .addUse(SrcReg);
341 unsigned SubRegCopy = MRI.createVirtualRegister(&AArch64::FPR16RegClass);
342 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY))
343 .addDef(SubRegCopy)
344 .addUse(CopyReg, 0, AArch64::hsub);
345
346 MachineOperand &RegOp = I.getOperand(1);
347 RegOp.setReg(SubRegCopy);
348 return true;
349}
350
Quentin Colombetcb629a82016-10-12 03:57:49 +0000351static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
352 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
353 const RegisterBankInfo &RBI) {
354
355 unsigned DstReg = I.getOperand(0).getReg();
Amara Emersondb211892018-02-20 05:11:57 +0000356 unsigned SrcReg = I.getOperand(1).getReg();
357
Quentin Colombetcb629a82016-10-12 03:57:49 +0000358 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
Amara Emersondb211892018-02-20 05:11:57 +0000359 if (TRI.getRegClass(AArch64::FPR16RegClassID)->contains(DstReg) &&
360 !TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
361 const RegisterBank &RegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
362 const TargetRegisterClass *SrcRC = getRegClassForTypeOnBank(
363 MRI.getType(SrcReg), RegBank, RBI, /* GetAllRegSet */ true);
364 if (SrcRC == &AArch64::GPR32allRegClass)
365 return selectFP16CopyFromGPR32(I, TII, MRI, SrcReg);
366 }
Quentin Colombetcb629a82016-10-12 03:57:49 +0000367 assert(I.isCopy() && "Generic operators do not allow physical registers");
368 return true;
369 }
370
371 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
372 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
Amara Emerson3838ed02018-02-02 18:03:30 +0000373 (void)DstSize;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000374 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
375 (void)SrcSize;
376 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
377 "No phys reg on generic operators");
378 assert(
379 (DstSize == SrcSize ||
380 // Copies are a mean to setup initial types, the number of
381 // bits may not exactly match.
382 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
383 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI)) ||
384 // Copies are a mean to copy bits around, as long as we are
385 // on the same register class, that's fine. Otherwise, that
386 // means we need some SUBREG_TO_REG or AND & co.
387 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) &&
388 "Copy with different width?!");
389 assert((DstSize <= 64 || RegBank.getID() == AArch64::FPRRegBankID) &&
390 "GPRs cannot get more than 64-bit width values");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000391
Amara Emerson3838ed02018-02-02 18:03:30 +0000392 const TargetRegisterClass *RC = getRegClassForTypeOnBank(
393 MRI.getType(DstReg), RegBank, RBI, /* GetAllRegSet */ true);
394 if (!RC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000395 LLVM_DEBUG(dbgs() << "Unexpected bitcast size " << DstSize << '\n');
Amara Emerson3838ed02018-02-02 18:03:30 +0000396 return false;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000397 }
398
Amara Emerson7e9f3482018-02-18 17:10:49 +0000399 if (!TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
Amara Emersondb211892018-02-20 05:11:57 +0000400 const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(SrcReg);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000401 const TargetRegisterClass *SrcRC =
402 RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
403 const RegisterBank *RB = nullptr;
404 if (!SrcRC) {
405 RB = RegClassOrBank.get<const RegisterBank *>();
406 SrcRC = getRegClassForTypeOnBank(MRI.getType(SrcReg), *RB, RBI, true);
407 }
408 // Copies from fpr16 to gpr32 need to use SUBREG_TO_REG.
409 if (RC == &AArch64::GPR32allRegClass && SrcRC == &AArch64::FPR16RegClass) {
410 unsigned PromoteReg = MRI.createVirtualRegister(&AArch64::FPR32RegClass);
411 BuildMI(*I.getParent(), I, I.getDebugLoc(),
412 TII.get(AArch64::SUBREG_TO_REG))
413 .addDef(PromoteReg)
414 .addImm(0)
415 .addUse(SrcReg)
416 .addImm(AArch64::hsub);
417 MachineOperand &RegOp = I.getOperand(1);
418 RegOp.setReg(PromoteReg);
Amara Emersondb211892018-02-20 05:11:57 +0000419 } else if (RC == &AArch64::FPR16RegClass &&
420 SrcRC == &AArch64::GPR32allRegClass) {
421 selectFP16CopyFromGPR32(I, TII, MRI, SrcReg);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000422 }
423 }
424
Quentin Colombetcb629a82016-10-12 03:57:49 +0000425 // No need to constrain SrcReg. It will get constrained when
426 // we hit another of its use or its defs.
427 // Copies do not have constraints.
428 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000429 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
430 << " operand\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000431 return false;
432 }
433 I.setDesc(TII.get(AArch64::COPY));
434 return true;
435}
436
Tim Northover69271c62016-10-12 22:49:11 +0000437static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
438 if (!DstTy.isScalar() || !SrcTy.isScalar())
439 return GenericOpc;
440
441 const unsigned DstSize = DstTy.getSizeInBits();
442 const unsigned SrcSize = SrcTy.getSizeInBits();
443
444 switch (DstSize) {
445 case 32:
446 switch (SrcSize) {
447 case 32:
448 switch (GenericOpc) {
449 case TargetOpcode::G_SITOFP:
450 return AArch64::SCVTFUWSri;
451 case TargetOpcode::G_UITOFP:
452 return AArch64::UCVTFUWSri;
453 case TargetOpcode::G_FPTOSI:
454 return AArch64::FCVTZSUWSr;
455 case TargetOpcode::G_FPTOUI:
456 return AArch64::FCVTZUUWSr;
457 default:
458 return GenericOpc;
459 }
460 case 64:
461 switch (GenericOpc) {
462 case TargetOpcode::G_SITOFP:
463 return AArch64::SCVTFUXSri;
464 case TargetOpcode::G_UITOFP:
465 return AArch64::UCVTFUXSri;
466 case TargetOpcode::G_FPTOSI:
467 return AArch64::FCVTZSUWDr;
468 case TargetOpcode::G_FPTOUI:
469 return AArch64::FCVTZUUWDr;
470 default:
471 return GenericOpc;
472 }
473 default:
474 return GenericOpc;
475 }
476 case 64:
477 switch (SrcSize) {
478 case 32:
479 switch (GenericOpc) {
480 case TargetOpcode::G_SITOFP:
481 return AArch64::SCVTFUWDri;
482 case TargetOpcode::G_UITOFP:
483 return AArch64::UCVTFUWDri;
484 case TargetOpcode::G_FPTOSI:
485 return AArch64::FCVTZSUXSr;
486 case TargetOpcode::G_FPTOUI:
487 return AArch64::FCVTZUUXSr;
488 default:
489 return GenericOpc;
490 }
491 case 64:
492 switch (GenericOpc) {
493 case TargetOpcode::G_SITOFP:
494 return AArch64::SCVTFUXDri;
495 case TargetOpcode::G_UITOFP:
496 return AArch64::UCVTFUXDri;
497 case TargetOpcode::G_FPTOSI:
498 return AArch64::FCVTZSUXDr;
499 case TargetOpcode::G_FPTOUI:
500 return AArch64::FCVTZUUXDr;
501 default:
502 return GenericOpc;
503 }
504 default:
505 return GenericOpc;
506 }
507 default:
508 return GenericOpc;
509 };
510 return GenericOpc;
511}
512
Tim Northover6c02ad52016-10-12 22:49:04 +0000513static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
514 switch (P) {
515 default:
516 llvm_unreachable("Unknown condition code!");
517 case CmpInst::ICMP_NE:
518 return AArch64CC::NE;
519 case CmpInst::ICMP_EQ:
520 return AArch64CC::EQ;
521 case CmpInst::ICMP_SGT:
522 return AArch64CC::GT;
523 case CmpInst::ICMP_SGE:
524 return AArch64CC::GE;
525 case CmpInst::ICMP_SLT:
526 return AArch64CC::LT;
527 case CmpInst::ICMP_SLE:
528 return AArch64CC::LE;
529 case CmpInst::ICMP_UGT:
530 return AArch64CC::HI;
531 case CmpInst::ICMP_UGE:
532 return AArch64CC::HS;
533 case CmpInst::ICMP_ULT:
534 return AArch64CC::LO;
535 case CmpInst::ICMP_ULE:
536 return AArch64CC::LS;
537 }
538}
539
Tim Northover7dd378d2016-10-12 22:49:07 +0000540static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
541 AArch64CC::CondCode &CondCode,
542 AArch64CC::CondCode &CondCode2) {
543 CondCode2 = AArch64CC::AL;
544 switch (P) {
545 default:
546 llvm_unreachable("Unknown FP condition!");
547 case CmpInst::FCMP_OEQ:
548 CondCode = AArch64CC::EQ;
549 break;
550 case CmpInst::FCMP_OGT:
551 CondCode = AArch64CC::GT;
552 break;
553 case CmpInst::FCMP_OGE:
554 CondCode = AArch64CC::GE;
555 break;
556 case CmpInst::FCMP_OLT:
557 CondCode = AArch64CC::MI;
558 break;
559 case CmpInst::FCMP_OLE:
560 CondCode = AArch64CC::LS;
561 break;
562 case CmpInst::FCMP_ONE:
563 CondCode = AArch64CC::MI;
564 CondCode2 = AArch64CC::GT;
565 break;
566 case CmpInst::FCMP_ORD:
567 CondCode = AArch64CC::VC;
568 break;
569 case CmpInst::FCMP_UNO:
570 CondCode = AArch64CC::VS;
571 break;
572 case CmpInst::FCMP_UEQ:
573 CondCode = AArch64CC::EQ;
574 CondCode2 = AArch64CC::VS;
575 break;
576 case CmpInst::FCMP_UGT:
577 CondCode = AArch64CC::HI;
578 break;
579 case CmpInst::FCMP_UGE:
580 CondCode = AArch64CC::PL;
581 break;
582 case CmpInst::FCMP_ULT:
583 CondCode = AArch64CC::LT;
584 break;
585 case CmpInst::FCMP_ULE:
586 CondCode = AArch64CC::LE;
587 break;
588 case CmpInst::FCMP_UNE:
589 CondCode = AArch64CC::NE;
590 break;
591 }
592}
593
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000594bool AArch64InstructionSelector::selectCompareBranch(
595 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
596
597 const unsigned CondReg = I.getOperand(0).getReg();
598 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
599 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
Aditya Nandakumar02c602e2017-07-31 17:00:16 +0000600 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC)
601 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg());
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000602 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
603 return false;
604
605 unsigned LHS = CCMI->getOperand(2).getReg();
606 unsigned RHS = CCMI->getOperand(3).getReg();
607 if (!getConstantVRegVal(RHS, MRI))
608 std::swap(RHS, LHS);
609
610 const auto RHSImm = getConstantVRegVal(RHS, MRI);
611 if (!RHSImm || *RHSImm != 0)
612 return false;
613
614 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
615 if (RB.getID() != AArch64::GPRRegBankID)
616 return false;
617
618 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
619 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
620 return false;
621
622 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
623 unsigned CBOpc = 0;
624 if (CmpWidth <= 32)
625 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
626 else if (CmpWidth == 64)
627 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
628 else
629 return false;
630
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +0000631 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
632 .addUse(LHS)
633 .addMBB(DestMBB)
634 .constrainAllUses(TII, TRI, RBI);
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000635
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000636 I.eraseFromParent();
637 return true;
638}
639
Tim Northovere9600d82017-02-08 17:57:27 +0000640bool AArch64InstructionSelector::selectVaStartAAPCS(
641 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
642 return false;
643}
644
645bool AArch64InstructionSelector::selectVaStartDarwin(
646 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
647 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
648 unsigned ListReg = I.getOperand(0).getReg();
649
650 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
651
652 auto MIB =
653 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri))
654 .addDef(ArgsAddrReg)
655 .addFrameIndex(FuncInfo->getVarArgsStackIndex())
656 .addImm(0)
657 .addImm(0);
658
659 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
660
661 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui))
662 .addUse(ArgsAddrReg)
663 .addUse(ListReg)
664 .addImm(0)
665 .addMemOperand(*I.memoperands_begin());
666
667 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
668 I.eraseFromParent();
669 return true;
670}
671
Amara Emerson1e8c1642018-07-31 00:09:02 +0000672void AArch64InstructionSelector::materializeLargeCMVal(
673 MachineInstr &I, const Value *V, unsigned char OpFlags) const {
674 MachineBasicBlock &MBB = *I.getParent();
675 MachineFunction &MF = *MBB.getParent();
676 MachineRegisterInfo &MRI = MF.getRegInfo();
677 MachineIRBuilder MIB(I);
678
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000679 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, {&AArch64::GPR64RegClass}, {});
Amara Emerson1e8c1642018-07-31 00:09:02 +0000680 MovZ->addOperand(MF, I.getOperand(1));
681 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 |
682 AArch64II::MO_NC);
683 MovZ->addOperand(MF, MachineOperand::CreateImm(0));
684 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI);
685
686 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, unsigned Offset,
687 unsigned ForceDstReg) {
688 unsigned DstReg = ForceDstReg
689 ? ForceDstReg
690 : MRI.createVirtualRegister(&AArch64::GPR64RegClass);
691 auto MovI = MIB.buildInstr(AArch64::MOVKXi).addDef(DstReg).addUse(SrcReg);
692 if (auto *GV = dyn_cast<GlobalValue>(V)) {
693 MovI->addOperand(MF, MachineOperand::CreateGA(
694 GV, MovZ->getOperand(1).getOffset(), Flags));
695 } else {
696 MovI->addOperand(
697 MF, MachineOperand::CreateBA(cast<BlockAddress>(V),
698 MovZ->getOperand(1).getOffset(), Flags));
699 }
700 MovI->addOperand(MF, MachineOperand::CreateImm(Offset));
701 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI);
702 return DstReg;
703 };
704 unsigned DstReg = BuildMovK(MovZ->getOperand(0).getReg(),
705 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0);
706 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0);
707 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg());
708 return;
709}
710
Daniel Sandersf76f3152017-11-16 00:46:35 +0000711bool AArch64InstructionSelector::select(MachineInstr &I,
712 CodeGenCoverage &CoverageInfo) const {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000713 assert(I.getParent() && "Instruction should be in a basic block!");
714 assert(I.getParent()->getParent() && "Instruction should be in a function!");
715
716 MachineBasicBlock &MBB = *I.getParent();
717 MachineFunction &MF = *MBB.getParent();
718 MachineRegisterInfo &MRI = MF.getRegInfo();
719
Tim Northovercdf23f12016-10-31 18:30:59 +0000720 unsigned Opcode = I.getOpcode();
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000721 // G_PHI requires same handling as PHI
722 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
Tim Northovercdf23f12016-10-31 18:30:59 +0000723 // Certain non-generic instructions also need some special handling.
724
725 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
726 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000727
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000728 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
Tim Northover7d88da62016-11-08 00:34:06 +0000729 const unsigned DefReg = I.getOperand(0).getReg();
730 const LLT DefTy = MRI.getType(DefReg);
731
732 const TargetRegisterClass *DefRC = nullptr;
733 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
734 DefRC = TRI.getRegClass(DefReg);
735 } else {
736 const RegClassOrRegBank &RegClassOrBank =
737 MRI.getRegClassOrRegBank(DefReg);
738
739 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
740 if (!DefRC) {
741 if (!DefTy.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000742 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000743 return false;
744 }
745 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
746 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
747 if (!DefRC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000748 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000749 return false;
750 }
751 }
752 }
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000753 I.setDesc(TII.get(TargetOpcode::PHI));
Tim Northover7d88da62016-11-08 00:34:06 +0000754
755 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
756 }
757
758 if (I.isCopy())
Tim Northovercdf23f12016-10-31 18:30:59 +0000759 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000760
761 return true;
Tim Northovercdf23f12016-10-31 18:30:59 +0000762 }
763
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000764
765 if (I.getNumOperands() != I.getNumExplicitOperands()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000766 LLVM_DEBUG(
767 dbgs() << "Generic instruction has unexpected implicit operands\n");
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000768 return false;
769 }
770
Daniel Sandersf76f3152017-11-16 00:46:35 +0000771 if (selectImpl(I, CoverageInfo))
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000772 return true;
773
Tim Northover32a078a2016-09-15 10:09:59 +0000774 LLT Ty =
775 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000776
Tim Northover69271c62016-10-12 22:49:11 +0000777 switch (Opcode) {
Tim Northover5e3dbf32016-10-12 22:49:01 +0000778 case TargetOpcode::G_BRCOND: {
779 if (Ty.getSizeInBits() > 32) {
780 // We shouldn't need this on AArch64, but it would be implemented as an
781 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
782 // bit being tested is < 32.
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000783 LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
784 << ", expected at most 32-bits");
Tim Northover5e3dbf32016-10-12 22:49:01 +0000785 return false;
786 }
787
788 const unsigned CondReg = I.getOperand(0).getReg();
789 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
790
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000791 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
792 // instructions will not be produced, as they are conditional branch
793 // instructions that do not set flags.
794 bool ProduceNonFlagSettingCondBr =
795 !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening);
796 if (ProduceNonFlagSettingCondBr && selectCompareBranch(I, MF, MRI))
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000797 return true;
798
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000799 if (ProduceNonFlagSettingCondBr) {
800 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
801 .addUse(CondReg)
802 .addImm(/*bit offset=*/0)
803 .addMBB(DestMBB);
Tim Northover5e3dbf32016-10-12 22:49:01 +0000804
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000805 I.eraseFromParent();
806 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
807 } else {
808 auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
809 .addDef(AArch64::WZR)
810 .addUse(CondReg)
811 .addImm(1);
812 constrainSelectedInstRegOperands(*CMP.getInstr(), TII, TRI, RBI);
813 auto Bcc =
814 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::Bcc))
815 .addImm(AArch64CC::EQ)
816 .addMBB(DestMBB);
817
818 I.eraseFromParent();
819 return constrainSelectedInstRegOperands(*Bcc.getInstr(), TII, TRI, RBI);
820 }
Tim Northover5e3dbf32016-10-12 22:49:01 +0000821 }
822
Kristof Beyls65a12c02017-01-30 09:13:18 +0000823 case TargetOpcode::G_BRINDIRECT: {
824 I.setDesc(TII.get(AArch64::BR));
825 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
826 }
827
Tim Northover4494d692016-10-18 19:47:57 +0000828 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +0000829 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +0000830 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
831
832 const LLT s32 = LLT::scalar(32);
833 const LLT s64 = LLT::scalar(64);
834 const LLT p0 = LLT::pointer(0, 64);
835
836 const unsigned DefReg = I.getOperand(0).getReg();
837 const LLT DefTy = MRI.getType(DefReg);
838 const unsigned DefSize = DefTy.getSizeInBits();
839 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
840
841 // FIXME: Redundant check, but even less readable when factored out.
842 if (isFP) {
843 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000844 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
845 << " constant, expected: " << s32 << " or " << s64
846 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +0000847 return false;
848 }
849
850 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000851 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
852 << " constant on bank: " << RB
853 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +0000854 return false;
855 }
Daniel Sanders11300ce2017-10-13 21:28:03 +0000856
857 // The case when we have 0.0 is covered by tablegen. Reject it here so we
858 // can be sure tablegen works correctly and isn't rescued by this code.
859 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
860 return false;
Tim Northover4494d692016-10-18 19:47:57 +0000861 } else {
Daniel Sanders05540042017-08-08 10:44:31 +0000862 // s32 and s64 are covered by tablegen.
863 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000864 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
865 << " constant, expected: " << s32 << ", " << s64
866 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +0000867 return false;
868 }
869
870 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000871 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
872 << " constant on bank: " << RB
873 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +0000874 return false;
875 }
876 }
877
878 const unsigned MovOpc =
879 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
880
881 I.setDesc(TII.get(MovOpc));
882
883 if (isFP) {
884 const TargetRegisterClass &GPRRC =
885 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
886 const TargetRegisterClass &FPRRC =
887 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
888
889 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
890 MachineOperand &RegOp = I.getOperand(0);
891 RegOp.setReg(DefGPRReg);
892
893 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
894 TII.get(AArch64::COPY))
895 .addDef(DefReg)
896 .addUse(DefGPRReg);
897
898 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000899 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +0000900 return false;
901 }
902
903 MachineOperand &ImmOp = I.getOperand(1);
904 // FIXME: Is going through int64_t always correct?
905 ImmOp.ChangeToImmediate(
906 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000907 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +0000908 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
909 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000910 } else if (I.getOperand(1).isImm()) {
911 uint64_t Val = I.getOperand(1).getImm();
912 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +0000913 }
914
915 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
916 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +0000917 }
Tim Northover7b6d66c2017-07-20 22:58:38 +0000918 case TargetOpcode::G_EXTRACT: {
919 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +0000920 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +0000921 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +0000922 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +0000923 // Larger extracts are vectors, same-size extracts should be something else
924 // by now (either split up or simplified to a COPY).
925 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
926 return false;
927
Amara Emersonbc03bae2018-02-18 17:03:02 +0000928 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +0000929 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
930 Ty.getSizeInBits() - 1);
931
Amara Emersonbc03bae2018-02-18 17:03:02 +0000932 if (SrcSize < 64) {
933 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
934 "unexpected G_EXTRACT types");
935 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
936 }
937
Tim Northover7b6d66c2017-07-20 22:58:38 +0000938 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
939 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
940 TII.get(AArch64::COPY))
941 .addDef(I.getOperand(0).getReg())
942 .addUse(DstReg, 0, AArch64::sub_32);
943 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
944 AArch64::GPR32RegClass, MRI);
945 I.getOperand(0).setReg(DstReg);
946
947 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
948 }
949
950 case TargetOpcode::G_INSERT: {
951 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +0000952 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
953 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +0000954 // Larger inserts are vectors, same-size ones should be something else by
955 // now (split up or turned into COPYs).
956 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
957 return false;
958
Amara Emersonbc03bae2018-02-18 17:03:02 +0000959 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +0000960 unsigned LSB = I.getOperand(3).getImm();
961 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +0000962 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +0000963 MachineInstrBuilder(MF, I).addImm(Width - 1);
964
Amara Emersonbc03bae2018-02-18 17:03:02 +0000965 if (DstSize < 64) {
966 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
967 "unexpected G_INSERT types");
968 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
969 }
970
Tim Northover7b6d66c2017-07-20 22:58:38 +0000971 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
972 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
973 TII.get(AArch64::SUBREG_TO_REG))
974 .addDef(SrcReg)
975 .addImm(0)
976 .addUse(I.getOperand(2).getReg())
977 .addImm(AArch64::sub_32);
978 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
979 AArch64::GPR32RegClass, MRI);
980 I.getOperand(2).setReg(SrcReg);
981
982 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
983 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000984 case TargetOpcode::G_FRAME_INDEX: {
985 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +0000986 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000987 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
988 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000989 return false;
990 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000991 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000992
993 // MOs for a #0 shifted immediate.
994 I.addOperand(MachineOperand::CreateImm(0));
995 I.addOperand(MachineOperand::CreateImm(0));
996
997 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
998 }
Tim Northoverbdf16242016-10-10 21:50:00 +0000999
1000 case TargetOpcode::G_GLOBAL_VALUE: {
1001 auto GV = I.getOperand(1).getGlobal();
1002 if (GV->isThreadLocal()) {
1003 // FIXME: we don't support TLS yet.
1004 return false;
1005 }
1006 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001007 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +00001008 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001009 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001010 } else if (TM.getCodeModel() == CodeModel::Large) {
1011 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +00001012 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001013 I.eraseFromParent();
1014 return true;
David Green9dd1d452018-08-22 11:31:39 +00001015 } else if (TM.getCodeModel() == CodeModel::Tiny) {
1016 I.setDesc(TII.get(AArch64::ADR));
1017 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001018 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +00001019 I.setDesc(TII.get(AArch64::MOVaddr));
1020 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1021 MachineInstrBuilder MIB(MF, I);
1022 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1023 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1024 }
1025 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1026 }
1027
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001028 case TargetOpcode::G_LOAD:
1029 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001030 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001031
Tim Northover5ae83502016-09-15 09:20:34 +00001032 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001033 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1034 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001035 return false;
1036 }
1037
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001038 auto &MemOp = **I.memoperands_begin();
1039 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001040 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001041 return false;
1042 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001043 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001044
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001045 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001046#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001047 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001048 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001049 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1050 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001051 assert(MRI.getType(PtrReg).isPointer() &&
1052 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001053#endif
1054
1055 const unsigned ValReg = I.getOperand(0).getReg();
1056 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1057
1058 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001059 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001060 if (NewOpc == I.getOpcode())
1061 return false;
1062
1063 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001064
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001065 uint64_t Offset = 0;
1066 auto *PtrMI = MRI.getVRegDef(PtrReg);
1067
1068 // Try to fold a GEP into our unsigned immediate addressing mode.
1069 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1070 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1071 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001072 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001073 const unsigned Scale = Log2_32(Size);
1074 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1075 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1076 I.getOperand(1).setReg(Ptr2Reg);
1077 PtrMI = MRI.getVRegDef(Ptr2Reg);
1078 Offset = Imm / Size;
1079 }
1080 }
1081 }
1082
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001083 // If we haven't folded anything into our addressing mode yet, try to fold
1084 // a frame index into the base+offset.
1085 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1086 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1087
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001088 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001089
1090 // If we're storing a 0, use WZR/XZR.
1091 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1092 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1093 if (I.getOpcode() == AArch64::STRWui)
1094 I.getOperand(0).setReg(AArch64::WZR);
1095 else if (I.getOpcode() == AArch64::STRXui)
1096 I.getOperand(0).setReg(AArch64::XZR);
1097 }
1098 }
1099
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001100 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1101 }
1102
Tim Northover9dd78f82017-02-08 21:22:25 +00001103 case TargetOpcode::G_SMULH:
1104 case TargetOpcode::G_UMULH: {
1105 // Reject the various things we don't support yet.
1106 if (unsupportedBinOp(I, RBI, MRI, TRI))
1107 return false;
1108
1109 const unsigned DefReg = I.getOperand(0).getReg();
1110 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1111
1112 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001113 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001114 return false;
1115 }
1116
1117 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001118 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1119 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001120 return false;
1121 }
1122
1123 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1124 : AArch64::UMULHrr;
1125 I.setDesc(TII.get(NewOpc));
1126
1127 // Now that we selected an opcode, we need to constrain the register
1128 // operands to use appropriate classes.
1129 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1130 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001131 case TargetOpcode::G_FADD:
1132 case TargetOpcode::G_FSUB:
1133 case TargetOpcode::G_FMUL:
1134 case TargetOpcode::G_FDIV:
1135
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001136 case TargetOpcode::G_OR:
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001137 case TargetOpcode::G_SHL:
1138 case TargetOpcode::G_LSHR:
1139 case TargetOpcode::G_ASHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001140 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001141 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001142 if (unsupportedBinOp(I, RBI, MRI, TRI))
1143 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001144
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001145 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001146
1147 const unsigned DefReg = I.getOperand(0).getReg();
1148 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1149
1150 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1151 if (NewOpc == I.getOpcode())
1152 return false;
1153
1154 I.setDesc(TII.get(NewOpc));
1155 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001156
1157 // Now that we selected an opcode, we need to constrain the register
1158 // operands to use appropriate classes.
1159 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1160 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001161
Tim Northover398c5f52017-02-14 20:56:29 +00001162 case TargetOpcode::G_PTR_MASK: {
1163 uint64_t Align = I.getOperand(2).getImm();
1164 if (Align >= 64 || Align == 0)
1165 return false;
1166
1167 uint64_t Mask = ~((1ULL << Align) - 1);
1168 I.setDesc(TII.get(AArch64::ANDXri));
1169 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1170
1171 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1172 }
Tim Northover037af52c2016-10-31 18:31:09 +00001173 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001174 case TargetOpcode::G_TRUNC: {
1175 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1176 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1177
1178 const unsigned DstReg = I.getOperand(0).getReg();
1179 const unsigned SrcReg = I.getOperand(1).getReg();
1180
1181 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1182 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1183
1184 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001185 LLVM_DEBUG(
1186 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001187 return false;
1188 }
1189
1190 if (DstRB.getID() == AArch64::GPRRegBankID) {
1191 const TargetRegisterClass *DstRC =
1192 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1193 if (!DstRC)
1194 return false;
1195
1196 const TargetRegisterClass *SrcRC =
1197 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1198 if (!SrcRC)
1199 return false;
1200
1201 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1202 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001203 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001204 return false;
1205 }
1206
1207 if (DstRC == SrcRC) {
1208 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001209 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1210 SrcTy == LLT::scalar(64)) {
1211 llvm_unreachable("TableGen can import this case");
1212 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001213 } else if (DstRC == &AArch64::GPR32RegClass &&
1214 SrcRC == &AArch64::GPR64RegClass) {
1215 I.getOperand(1).setSubReg(AArch64::sub_32);
1216 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001217 LLVM_DEBUG(
1218 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001219 return false;
1220 }
1221
1222 I.setDesc(TII.get(TargetOpcode::COPY));
1223 return true;
1224 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1225 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1226 I.setDesc(TII.get(AArch64::XTNv4i16));
1227 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1228 return true;
1229 }
1230 }
1231
1232 return false;
1233 }
1234
Tim Northover3d38b3a2016-10-11 20:50:21 +00001235 case TargetOpcode::G_ANYEXT: {
1236 const unsigned DstReg = I.getOperand(0).getReg();
1237 const unsigned SrcReg = I.getOperand(1).getReg();
1238
Quentin Colombetcb629a82016-10-12 03:57:49 +00001239 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1240 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001241 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1242 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001243 return false;
1244 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001245
Quentin Colombetcb629a82016-10-12 03:57:49 +00001246 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1247 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001248 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1249 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001250 return false;
1251 }
1252
1253 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1254
1255 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001256 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001257 return false;
1258 }
1259
Quentin Colombetcb629a82016-10-12 03:57:49 +00001260 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001261 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1262 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001263 return false;
1264 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001265 // At this point G_ANYEXT is just like a plain COPY, but we need
1266 // to explicitly form the 64-bit value if any.
1267 if (DstSize > 32) {
1268 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1269 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1270 .addDef(ExtSrc)
1271 .addImm(0)
1272 .addUse(SrcReg)
1273 .addImm(AArch64::sub_32);
1274 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001275 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001276 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001277 }
1278
1279 case TargetOpcode::G_ZEXT:
1280 case TargetOpcode::G_SEXT: {
1281 unsigned Opcode = I.getOpcode();
1282 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1283 SrcTy = MRI.getType(I.getOperand(1).getReg());
1284 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1285 const unsigned DefReg = I.getOperand(0).getReg();
1286 const unsigned SrcReg = I.getOperand(1).getReg();
1287 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1288
1289 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001290 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1291 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001292 return false;
1293 }
1294
1295 MachineInstr *ExtI;
1296 if (DstTy == LLT::scalar(64)) {
1297 // FIXME: Can we avoid manually doing this?
1298 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001299 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1300 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001301 return false;
1302 }
1303
1304 const unsigned SrcXReg =
1305 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1306 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1307 .addDef(SrcXReg)
1308 .addImm(0)
1309 .addUse(SrcReg)
1310 .addImm(AArch64::sub_32);
1311
1312 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1313 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1314 .addDef(DefReg)
1315 .addUse(SrcXReg)
1316 .addImm(0)
1317 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001318 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001319 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1320 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1321 .addDef(DefReg)
1322 .addUse(SrcReg)
1323 .addImm(0)
1324 .addImm(SrcTy.getSizeInBits() - 1);
1325 } else {
1326 return false;
1327 }
1328
1329 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1330
1331 I.eraseFromParent();
1332 return true;
1333 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001334
Tim Northover69271c62016-10-12 22:49:11 +00001335 case TargetOpcode::G_SITOFP:
1336 case TargetOpcode::G_UITOFP:
1337 case TargetOpcode::G_FPTOSI:
1338 case TargetOpcode::G_FPTOUI: {
1339 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1340 SrcTy = MRI.getType(I.getOperand(1).getReg());
1341 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1342 if (NewOpc == Opcode)
1343 return false;
1344
1345 I.setDesc(TII.get(NewOpc));
1346 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1347
1348 return true;
1349 }
1350
1351
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001352 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001353 // The importer is currently unable to import pointer types since they
1354 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001355 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001356
Daniel Sandersedd07842017-08-17 09:26:14 +00001357 case TargetOpcode::G_BITCAST:
1358 // Imported SelectionDAG rules can handle every bitcast except those that
1359 // bitcast from a type to the same type. Ideally, these shouldn't occur
1360 // but we might not run an optimizer that deletes them.
1361 if (MRI.getType(I.getOperand(0).getReg()) ==
1362 MRI.getType(I.getOperand(1).getReg()))
1363 return selectCopy(I, TII, MRI, TRI, RBI);
1364 return false;
1365
Tim Northover9ac0eba2016-11-08 00:45:29 +00001366 case TargetOpcode::G_SELECT: {
1367 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001368 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1369 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001370 return false;
1371 }
1372
1373 const unsigned CondReg = I.getOperand(1).getReg();
1374 const unsigned TReg = I.getOperand(2).getReg();
1375 const unsigned FReg = I.getOperand(3).getReg();
1376
1377 unsigned CSelOpc = 0;
1378
1379 if (Ty == LLT::scalar(32)) {
1380 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001381 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001382 CSelOpc = AArch64::CSELXr;
1383 } else {
1384 return false;
1385 }
1386
1387 MachineInstr &TstMI =
1388 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1389 .addDef(AArch64::WZR)
1390 .addUse(CondReg)
1391 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1392
1393 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1394 .addDef(I.getOperand(0).getReg())
1395 .addUse(TReg)
1396 .addUse(FReg)
1397 .addImm(AArch64CC::NE);
1398
1399 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1400 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1401
1402 I.eraseFromParent();
1403 return true;
1404 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001405 case TargetOpcode::G_ICMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001406 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001407 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1408 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001409 return false;
1410 }
1411
1412 unsigned CmpOpc = 0;
1413 unsigned ZReg = 0;
1414
1415 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1416 if (CmpTy == LLT::scalar(32)) {
1417 CmpOpc = AArch64::SUBSWrr;
1418 ZReg = AArch64::WZR;
1419 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1420 CmpOpc = AArch64::SUBSXrr;
1421 ZReg = AArch64::XZR;
1422 } else {
1423 return false;
1424 }
1425
Kristof Beyls22524402017-01-05 10:16:08 +00001426 // CSINC increments the result by one when the condition code is false.
1427 // Therefore, we have to invert the predicate to get an increment by 1 when
1428 // the predicate is true.
1429 const AArch64CC::CondCode invCC =
1430 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1431 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001432
1433 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1434 .addDef(ZReg)
1435 .addUse(I.getOperand(2).getReg())
1436 .addUse(I.getOperand(3).getReg());
1437
1438 MachineInstr &CSetMI =
1439 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1440 .addDef(I.getOperand(0).getReg())
1441 .addUse(AArch64::WZR)
1442 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001443 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001444
1445 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1446 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1447
1448 I.eraseFromParent();
1449 return true;
1450 }
1451
Tim Northover7dd378d2016-10-12 22:49:07 +00001452 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001453 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001454 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1455 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001456 return false;
1457 }
1458
1459 unsigned CmpOpc = 0;
1460 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1461 if (CmpTy == LLT::scalar(32)) {
1462 CmpOpc = AArch64::FCMPSrr;
1463 } else if (CmpTy == LLT::scalar(64)) {
1464 CmpOpc = AArch64::FCMPDrr;
1465 } else {
1466 return false;
1467 }
1468
1469 // FIXME: regbank
1470
1471 AArch64CC::CondCode CC1, CC2;
1472 changeFCMPPredToAArch64CC(
1473 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1474
1475 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1476 .addUse(I.getOperand(2).getReg())
1477 .addUse(I.getOperand(3).getReg());
1478
1479 const unsigned DefReg = I.getOperand(0).getReg();
1480 unsigned Def1Reg = DefReg;
1481 if (CC2 != AArch64CC::AL)
1482 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1483
1484 MachineInstr &CSetMI =
1485 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1486 .addDef(Def1Reg)
1487 .addUse(AArch64::WZR)
1488 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001489 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001490
1491 if (CC2 != AArch64CC::AL) {
1492 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1493 MachineInstr &CSet2MI =
1494 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1495 .addDef(Def2Reg)
1496 .addUse(AArch64::WZR)
1497 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001498 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001499 MachineInstr &OrMI =
1500 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1501 .addDef(DefReg)
1502 .addUse(Def1Reg)
1503 .addUse(Def2Reg);
1504 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1505 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1506 }
1507
1508 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1509 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1510
1511 I.eraseFromParent();
1512 return true;
1513 }
Tim Northovere9600d82017-02-08 17:57:27 +00001514 case TargetOpcode::G_VASTART:
1515 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1516 : selectVaStartAAPCS(I, MF, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001517 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1518 if (!I.getOperand(0).isIntrinsicID())
1519 return false;
1520 if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1521 return false;
1522 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::BRK))
1523 .addImm(1);
1524 I.eraseFromParent();
1525 return true;
Amara Emerson1e8c1642018-07-31 00:09:02 +00001526 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001527 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001528 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1529 const unsigned DstReg = I.getOperand(0).getReg();
1530 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1531 const TargetRegisterClass *DstRC =
1532 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1533 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001534 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001535 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001536 case TargetOpcode::G_BLOCK_ADDR: {
1537 if (TM.getCodeModel() == CodeModel::Large) {
1538 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1539 I.eraseFromParent();
1540 return true;
1541 } else {
1542 I.setDesc(TII.get(AArch64::MOVaddrBA));
1543 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1544 I.getOperand(0).getReg())
1545 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1546 /* Offset */ 0, AArch64II::MO_PAGE)
1547 .addBlockAddress(
1548 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1549 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1550 I.eraseFromParent();
1551 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1552 }
1553 }
Amara Emerson5ec14602018-12-10 18:44:58 +00001554 case TargetOpcode::G_BUILD_VECTOR:
1555 return selectBuildVector(I, MRI);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001556 case TargetOpcode::G_MERGE_VALUES:
1557 return selectMergeValues(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001558 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001559
1560 return false;
1561}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001562
Amara Emerson5ec14602018-12-10 18:44:58 +00001563bool AArch64InstructionSelector::emitScalarToVector(
1564 unsigned &Dst, const LLT DstTy, const TargetRegisterClass *DstRC,
1565 unsigned Scalar, MachineBasicBlock &MBB,
1566 MachineBasicBlock::iterator MBBI, MachineRegisterInfo &MRI) const {
1567 Dst = MRI.createVirtualRegister(DstRC);
1568
1569 unsigned UndefVec = MRI.createVirtualRegister(DstRC);
1570 MachineInstr &UndefMI = *BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1571 TII.get(TargetOpcode::IMPLICIT_DEF))
1572 .addDef(UndefVec);
1573
1574 auto BuildFn = [&](unsigned SubregIndex) {
1575 MachineInstr &InsMI = *BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1576 TII.get(TargetOpcode::INSERT_SUBREG))
1577 .addDef(Dst)
1578 .addUse(UndefVec)
1579 .addUse(Scalar)
1580 .addImm(SubregIndex);
1581 constrainSelectedInstRegOperands(UndefMI, TII, TRI, RBI);
1582 return constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1583 };
1584
1585 switch (DstTy.getElementType().getSizeInBits()) {
1586 case 32:
1587 return BuildFn(AArch64::ssub);
1588 case 64:
1589 return BuildFn(AArch64::dsub);
1590 default:
1591 return false;
1592 }
1593}
1594
Amara Emerson8cb186c2018-12-20 01:11:04 +00001595bool AArch64InstructionSelector::selectMergeValues(
1596 MachineInstr &I, MachineRegisterInfo &MRI) const {
1597 assert(I.getOpcode() == TargetOpcode::G_MERGE_VALUES && "unexpected opcode");
1598 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1599 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1600 assert(!DstTy.isVector() && !SrcTy.isVector() && "invalid merge operation");
1601
1602 // At the moment we only support merging two s32s into an s64.
1603 if (I.getNumOperands() != 3)
1604 return false;
1605 if (DstTy.getSizeInBits() != 64 || SrcTy.getSizeInBits() != 32)
1606 return false;
1607 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1608 if (RB.getID() != AArch64::GPRRegBankID)
1609 return false;
1610
1611 auto *DstRC = &AArch64::GPR64RegClass;
1612 unsigned SubToRegDef = MRI.createVirtualRegister(DstRC);
1613 MachineInstr &SubRegMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1614 TII.get(TargetOpcode::SUBREG_TO_REG))
1615 .addDef(SubToRegDef)
1616 .addImm(0)
1617 .addUse(I.getOperand(1).getReg())
1618 .addImm(AArch64::sub_32);
1619 unsigned SubToRegDef2 = MRI.createVirtualRegister(DstRC);
1620 // Need to anyext the second scalar before we can use bfm
1621 MachineInstr &SubRegMI2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1622 TII.get(TargetOpcode::SUBREG_TO_REG))
1623 .addDef(SubToRegDef2)
1624 .addImm(0)
1625 .addUse(I.getOperand(2).getReg())
1626 .addImm(AArch64::sub_32);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001627 MachineInstr &BFM =
1628 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::BFMXri))
Amara Emerson321bfb22018-12-20 03:27:42 +00001629 .addDef(I.getOperand(0).getReg())
Amara Emerson8cb186c2018-12-20 01:11:04 +00001630 .addUse(SubToRegDef)
1631 .addUse(SubToRegDef2)
1632 .addImm(32)
1633 .addImm(31);
1634 constrainSelectedInstRegOperands(SubRegMI, TII, TRI, RBI);
1635 constrainSelectedInstRegOperands(SubRegMI2, TII, TRI, RBI);
1636 constrainSelectedInstRegOperands(BFM, TII, TRI, RBI);
1637 I.eraseFromParent();
1638 return true;
1639}
1640
Amara Emerson5ec14602018-12-10 18:44:58 +00001641bool AArch64InstructionSelector::selectBuildVector(
1642 MachineInstr &I, MachineRegisterInfo &MRI) const {
1643 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
1644 // Until we port more of the optimized selections, for now just use a vector
1645 // insert sequence.
1646 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1647 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
1648 unsigned EltSize = EltTy.getSizeInBits();
1649 if (EltSize < 32 || EltSize > 64)
1650 return false; // Don't support all element types yet.
1651 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1652 unsigned Opc;
1653 unsigned SubregIdx;
1654 if (RB.getID() == AArch64::GPRRegBankID) {
1655 if (EltSize == 32) {
1656 Opc = AArch64::INSvi32gpr;
1657 SubregIdx = AArch64::ssub;
1658 } else {
1659 Opc = AArch64::INSvi64gpr;
1660 SubregIdx = AArch64::dsub;
1661 }
1662 } else {
1663 if (EltSize == 32) {
1664 Opc = AArch64::INSvi32lane;
1665 SubregIdx = AArch64::ssub;
1666 } else {
1667 Opc = AArch64::INSvi64lane;
1668 SubregIdx = AArch64::dsub;
1669 }
1670 }
1671
1672 if (EltSize * DstTy.getNumElements() != 128)
1673 return false; // Don't handle unpacked vectors yet.
1674
1675 unsigned DstVec = 0;
1676 const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
1677 DstTy, RBI.getRegBank(AArch64::FPRRegBankID), RBI);
1678 emitScalarToVector(DstVec, DstTy, DstRC, I.getOperand(1).getReg(),
1679 *I.getParent(), I.getIterator(), MRI);
1680 for (unsigned i = 2, e = DstTy.getSizeInBits() / EltSize + 1; i < e; ++i) {
1681 unsigned InsDef;
1682 // For the last insert re-use the dst reg of the G_BUILD_VECTOR.
1683 if (i + 1 < e)
1684 InsDef = MRI.createVirtualRegister(DstRC);
1685 else
1686 InsDef = I.getOperand(0).getReg();
1687 unsigned LaneIdx = i - 1;
1688 if (RB.getID() == AArch64::FPRRegBankID) {
1689 unsigned ImpDef = MRI.createVirtualRegister(DstRC);
1690 MachineInstr &ImpDefMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1691 TII.get(TargetOpcode::IMPLICIT_DEF))
1692 .addDef(ImpDef);
1693 unsigned InsSubDef = MRI.createVirtualRegister(DstRC);
1694 MachineInstr &InsSubMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1695 TII.get(TargetOpcode::INSERT_SUBREG))
1696 .addDef(InsSubDef)
1697 .addUse(ImpDef)
1698 .addUse(I.getOperand(i).getReg())
1699 .addImm(SubregIdx);
1700 MachineInstr &InsEltMI =
1701 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
1702 .addDef(InsDef)
1703 .addUse(DstVec)
1704 .addImm(LaneIdx)
1705 .addUse(InsSubDef)
1706 .addImm(0);
1707 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
1708 constrainSelectedInstRegOperands(InsSubMI, TII, TRI, RBI);
1709 constrainSelectedInstRegOperands(InsEltMI, TII, TRI, RBI);
1710 DstVec = InsDef;
1711 } else {
1712 MachineInstr &InsMI =
1713 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
1714 .addDef(InsDef)
1715 .addUse(DstVec)
1716 .addImm(LaneIdx)
1717 .addUse(I.getOperand(i).getReg());
1718 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1719 DstVec = InsDef;
1720 }
1721 }
1722 I.eraseFromParent();
1723 return true;
1724}
1725
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001726/// SelectArithImmed - Select an immediate value that can be represented as
1727/// a 12-bit value shifted left by either 0 or 12. If so, return true with
1728/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001729InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00001730AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001731 MachineInstr &MI = *Root.getParent();
1732 MachineBasicBlock &MBB = *MI.getParent();
1733 MachineFunction &MF = *MBB.getParent();
1734 MachineRegisterInfo &MRI = MF.getRegInfo();
1735
1736 // This function is called from the addsub_shifted_imm ComplexPattern,
1737 // which lists [imm] as the list of opcode it's interested in, however
1738 // we still need to check whether the operand is actually an immediate
1739 // here because the ComplexPattern opcode list is only used in
1740 // root-level opcode matching.
1741 uint64_t Immed;
1742 if (Root.isImm())
1743 Immed = Root.getImm();
1744 else if (Root.isCImm())
1745 Immed = Root.getCImm()->getZExtValue();
1746 else if (Root.isReg()) {
1747 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
1748 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001749 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00001750 MachineOperand &Op1 = Def->getOperand(1);
1751 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001752 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00001753 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001754 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001755 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001756
1757 unsigned ShiftAmt;
1758
1759 if (Immed >> 12 == 0) {
1760 ShiftAmt = 0;
1761 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
1762 ShiftAmt = 12;
1763 Immed = Immed >> 12;
1764 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001765 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001766
1767 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001768 return {{
1769 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
1770 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
1771 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001772}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001773
Daniel Sandersea8711b2017-10-16 03:36:29 +00001774/// Select a "register plus unscaled signed 9-bit immediate" address. This
1775/// should only match when there is an offset that is not valid for a scaled
1776/// immediate addressing mode. The "Size" argument is the size in bytes of the
1777/// memory reference, which is needed here to know what is valid for a scaled
1778/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001779InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00001780AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
1781 unsigned Size) const {
1782 MachineRegisterInfo &MRI =
1783 Root.getParent()->getParent()->getParent()->getRegInfo();
1784
1785 if (!Root.isReg())
1786 return None;
1787
1788 if (!isBaseWithConstantOffset(Root, MRI))
1789 return None;
1790
1791 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
1792 if (!RootDef)
1793 return None;
1794
1795 MachineOperand &OffImm = RootDef->getOperand(2);
1796 if (!OffImm.isReg())
1797 return None;
1798 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
1799 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
1800 return None;
1801 int64_t RHSC;
1802 MachineOperand &RHSOp1 = RHS->getOperand(1);
1803 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
1804 return None;
1805 RHSC = RHSOp1.getCImm()->getSExtValue();
1806
1807 // If the offset is valid as a scaled immediate, don't match here.
1808 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
1809 return None;
1810 if (RHSC >= -256 && RHSC < 256) {
1811 MachineOperand &Base = RootDef->getOperand(1);
1812 return {{
1813 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
1814 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
1815 }};
1816 }
1817 return None;
1818}
1819
1820/// Select a "register plus scaled unsigned 12-bit immediate" address. The
1821/// "Size" argument is the size in bytes of the memory reference, which
1822/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001823InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00001824AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
1825 unsigned Size) const {
1826 MachineRegisterInfo &MRI =
1827 Root.getParent()->getParent()->getParent()->getRegInfo();
1828
1829 if (!Root.isReg())
1830 return None;
1831
1832 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
1833 if (!RootDef)
1834 return None;
1835
1836 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
1837 return {{
1838 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
1839 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
1840 }};
1841 }
1842
1843 if (isBaseWithConstantOffset(Root, MRI)) {
1844 MachineOperand &LHS = RootDef->getOperand(1);
1845 MachineOperand &RHS = RootDef->getOperand(2);
1846 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
1847 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
1848 if (LHSDef && RHSDef) {
1849 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
1850 unsigned Scale = Log2_32(Size);
1851 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
1852 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00001853 return {{
1854 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
1855 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
1856 }};
1857
Daniel Sandersea8711b2017-10-16 03:36:29 +00001858 return {{
1859 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
1860 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
1861 }};
1862 }
1863 }
1864 }
1865
1866 // Before falling back to our general case, check if the unscaled
1867 // instructions can handle this. If so, that's preferable.
1868 if (selectAddrModeUnscaled(Root, Size).hasValue())
1869 return None;
1870
1871 return {{
1872 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
1873 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
1874 }};
1875}
1876
Volkan Kelesf7f25682018-01-16 18:44:05 +00001877void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
1878 const MachineInstr &MI) const {
1879 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1880 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
1881 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
1882 assert(CstVal && "Expected constant value");
1883 MIB.addImm(CstVal.getValue());
1884}
1885
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001886namespace llvm {
1887InstructionSelector *
1888createAArch64InstructionSelector(const AArch64TargetMachine &TM,
1889 AArch64Subtarget &Subtarget,
1890 AArch64RegisterBankInfo &RBI) {
1891 return new AArch64InstructionSelector(TM, Subtarget, RBI);
1892}
1893}