blob: 3741dcdcd547ba4cdb7b33e96f6cf86470c53c47 [file] [log] [blame]
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001//===- AArch64InstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the targeting of the InstructionSelector class for
11/// AArch64.
12/// \todo This should be generated by TableGen.
13//===----------------------------------------------------------------------===//
14
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000015#include "AArch64InstrInfo.h"
Tim Northovere9600d82017-02-08 17:57:27 +000016#include "AArch64MachineFunctionInfo.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000017#include "AArch64RegisterBankInfo.h"
18#include "AArch64RegisterInfo.h"
19#include "AArch64Subtarget.h"
Tim Northoverbdf16242016-10-10 21:50:00 +000020#include "AArch64TargetMachine.h"
Tim Northover9ac0eba2016-11-08 00:45:29 +000021#include "MCTargetDesc/AArch64AddressingModes.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
David Blaikie62651302017-10-26 23:39:54 +000023#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Amara Emerson1e8c1642018-07-31 00:09:02 +000024#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Aditya Nandakumar75ad9cc2017-04-19 20:48:50 +000025#include "llvm/CodeGen/GlobalISel/Utils.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000026#include "llvm/CodeGen/MachineBasicBlock.h"
27#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'.
70 bool emitScalarToVector(unsigned &Dst, const LLT DstTy,
71 const TargetRegisterClass *DstRC, unsigned Scalar,
72 MachineBasicBlock &MBB,
73 MachineBasicBlock::iterator MBBI,
74 MachineRegisterInfo &MRI) const;
75 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
76
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
679 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, &AArch64::GPR64RegClass);
680 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
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000791 if (selectCompareBranch(I, MF, MRI))
792 return true;
793
Tim Northover5e3dbf32016-10-12 22:49:01 +0000794 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
795 .addUse(CondReg)
796 .addImm(/*bit offset=*/0)
797 .addMBB(DestMBB);
798
799 I.eraseFromParent();
800 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
801 }
802
Kristof Beyls65a12c02017-01-30 09:13:18 +0000803 case TargetOpcode::G_BRINDIRECT: {
804 I.setDesc(TII.get(AArch64::BR));
805 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
806 }
807
Tim Northover4494d692016-10-18 19:47:57 +0000808 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +0000809 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +0000810 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
811
812 const LLT s32 = LLT::scalar(32);
813 const LLT s64 = LLT::scalar(64);
814 const LLT p0 = LLT::pointer(0, 64);
815
816 const unsigned DefReg = I.getOperand(0).getReg();
817 const LLT DefTy = MRI.getType(DefReg);
818 const unsigned DefSize = DefTy.getSizeInBits();
819 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
820
821 // FIXME: Redundant check, but even less readable when factored out.
822 if (isFP) {
823 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000824 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
825 << " constant, expected: " << s32 << " or " << s64
826 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +0000827 return false;
828 }
829
830 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000831 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
832 << " constant on bank: " << RB
833 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +0000834 return false;
835 }
Daniel Sanders11300ce2017-10-13 21:28:03 +0000836
837 // The case when we have 0.0 is covered by tablegen. Reject it here so we
838 // can be sure tablegen works correctly and isn't rescued by this code.
839 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
840 return false;
Tim Northover4494d692016-10-18 19:47:57 +0000841 } else {
Daniel Sanders05540042017-08-08 10:44:31 +0000842 // s32 and s64 are covered by tablegen.
843 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000844 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
845 << " constant, expected: " << s32 << ", " << s64
846 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +0000847 return false;
848 }
849
850 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000851 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
852 << " constant on bank: " << RB
853 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +0000854 return false;
855 }
856 }
857
858 const unsigned MovOpc =
859 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
860
861 I.setDesc(TII.get(MovOpc));
862
863 if (isFP) {
864 const TargetRegisterClass &GPRRC =
865 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
866 const TargetRegisterClass &FPRRC =
867 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
868
869 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
870 MachineOperand &RegOp = I.getOperand(0);
871 RegOp.setReg(DefGPRReg);
872
873 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
874 TII.get(AArch64::COPY))
875 .addDef(DefReg)
876 .addUse(DefGPRReg);
877
878 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000879 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +0000880 return false;
881 }
882
883 MachineOperand &ImmOp = I.getOperand(1);
884 // FIXME: Is going through int64_t always correct?
885 ImmOp.ChangeToImmediate(
886 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000887 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +0000888 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
889 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000890 } else if (I.getOperand(1).isImm()) {
891 uint64_t Val = I.getOperand(1).getImm();
892 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +0000893 }
894
895 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
896 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +0000897 }
Tim Northover7b6d66c2017-07-20 22:58:38 +0000898 case TargetOpcode::G_EXTRACT: {
899 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +0000900 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +0000901 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +0000902 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +0000903 // Larger extracts are vectors, same-size extracts should be something else
904 // by now (either split up or simplified to a COPY).
905 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
906 return false;
907
Amara Emersonbc03bae2018-02-18 17:03:02 +0000908 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +0000909 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
910 Ty.getSizeInBits() - 1);
911
Amara Emersonbc03bae2018-02-18 17:03:02 +0000912 if (SrcSize < 64) {
913 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
914 "unexpected G_EXTRACT types");
915 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
916 }
917
Tim Northover7b6d66c2017-07-20 22:58:38 +0000918 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
919 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
920 TII.get(AArch64::COPY))
921 .addDef(I.getOperand(0).getReg())
922 .addUse(DstReg, 0, AArch64::sub_32);
923 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
924 AArch64::GPR32RegClass, MRI);
925 I.getOperand(0).setReg(DstReg);
926
927 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
928 }
929
930 case TargetOpcode::G_INSERT: {
931 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +0000932 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
933 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +0000934 // Larger inserts are vectors, same-size ones should be something else by
935 // now (split up or turned into COPYs).
936 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
937 return false;
938
Amara Emersonbc03bae2018-02-18 17:03:02 +0000939 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +0000940 unsigned LSB = I.getOperand(3).getImm();
941 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +0000942 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +0000943 MachineInstrBuilder(MF, I).addImm(Width - 1);
944
Amara Emersonbc03bae2018-02-18 17:03:02 +0000945 if (DstSize < 64) {
946 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
947 "unexpected G_INSERT types");
948 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
949 }
950
Tim Northover7b6d66c2017-07-20 22:58:38 +0000951 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
952 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
953 TII.get(AArch64::SUBREG_TO_REG))
954 .addDef(SrcReg)
955 .addImm(0)
956 .addUse(I.getOperand(2).getReg())
957 .addImm(AArch64::sub_32);
958 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
959 AArch64::GPR32RegClass, MRI);
960 I.getOperand(2).setReg(SrcReg);
961
962 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
963 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000964 case TargetOpcode::G_FRAME_INDEX: {
965 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +0000966 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000967 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
968 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000969 return false;
970 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000971 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +0000972
973 // MOs for a #0 shifted immediate.
974 I.addOperand(MachineOperand::CreateImm(0));
975 I.addOperand(MachineOperand::CreateImm(0));
976
977 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
978 }
Tim Northoverbdf16242016-10-10 21:50:00 +0000979
980 case TargetOpcode::G_GLOBAL_VALUE: {
981 auto GV = I.getOperand(1).getGlobal();
982 if (GV->isThreadLocal()) {
983 // FIXME: we don't support TLS yet.
984 return false;
985 }
986 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +0000987 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +0000988 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +0000989 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +0000990 } else if (TM.getCodeModel() == CodeModel::Large) {
991 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +0000992 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +0000993 I.eraseFromParent();
994 return true;
David Green9dd1d452018-08-22 11:31:39 +0000995 } else if (TM.getCodeModel() == CodeModel::Tiny) {
996 I.setDesc(TII.get(AArch64::ADR));
997 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +0000998 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +0000999 I.setDesc(TII.get(AArch64::MOVaddr));
1000 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1001 MachineInstrBuilder MIB(MF, I);
1002 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1003 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1004 }
1005 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1006 }
1007
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001008 case TargetOpcode::G_LOAD:
1009 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001010 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001011
Tim Northover5ae83502016-09-15 09:20:34 +00001012 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001013 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1014 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001015 return false;
1016 }
1017
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001018 auto &MemOp = **I.memoperands_begin();
1019 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001020 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001021 return false;
1022 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001023 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001024
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001025 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001026#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001027 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001028 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001029 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1030 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001031 assert(MRI.getType(PtrReg).isPointer() &&
1032 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001033#endif
1034
1035 const unsigned ValReg = I.getOperand(0).getReg();
1036 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1037
1038 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001039 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001040 if (NewOpc == I.getOpcode())
1041 return false;
1042
1043 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001044
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001045 uint64_t Offset = 0;
1046 auto *PtrMI = MRI.getVRegDef(PtrReg);
1047
1048 // Try to fold a GEP into our unsigned immediate addressing mode.
1049 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1050 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1051 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001052 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001053 const unsigned Scale = Log2_32(Size);
1054 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1055 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1056 I.getOperand(1).setReg(Ptr2Reg);
1057 PtrMI = MRI.getVRegDef(Ptr2Reg);
1058 Offset = Imm / Size;
1059 }
1060 }
1061 }
1062
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001063 // If we haven't folded anything into our addressing mode yet, try to fold
1064 // a frame index into the base+offset.
1065 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1066 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1067
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001068 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001069
1070 // If we're storing a 0, use WZR/XZR.
1071 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1072 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1073 if (I.getOpcode() == AArch64::STRWui)
1074 I.getOperand(0).setReg(AArch64::WZR);
1075 else if (I.getOpcode() == AArch64::STRXui)
1076 I.getOperand(0).setReg(AArch64::XZR);
1077 }
1078 }
1079
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001080 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1081 }
1082
Tim Northover9dd78f82017-02-08 21:22:25 +00001083 case TargetOpcode::G_SMULH:
1084 case TargetOpcode::G_UMULH: {
1085 // Reject the various things we don't support yet.
1086 if (unsupportedBinOp(I, RBI, MRI, TRI))
1087 return false;
1088
1089 const unsigned DefReg = I.getOperand(0).getReg();
1090 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1091
1092 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001093 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001094 return false;
1095 }
1096
1097 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001098 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1099 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001100 return false;
1101 }
1102
1103 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1104 : AArch64::UMULHrr;
1105 I.setDesc(TII.get(NewOpc));
1106
1107 // Now that we selected an opcode, we need to constrain the register
1108 // operands to use appropriate classes.
1109 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1110 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001111 case TargetOpcode::G_FADD:
1112 case TargetOpcode::G_FSUB:
1113 case TargetOpcode::G_FMUL:
1114 case TargetOpcode::G_FDIV:
1115
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001116 case TargetOpcode::G_OR:
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001117 case TargetOpcode::G_SHL:
1118 case TargetOpcode::G_LSHR:
1119 case TargetOpcode::G_ASHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001120 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001121 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001122 if (unsupportedBinOp(I, RBI, MRI, TRI))
1123 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001124
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001125 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001126
1127 const unsigned DefReg = I.getOperand(0).getReg();
1128 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1129
1130 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1131 if (NewOpc == I.getOpcode())
1132 return false;
1133
1134 I.setDesc(TII.get(NewOpc));
1135 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001136
1137 // Now that we selected an opcode, we need to constrain the register
1138 // operands to use appropriate classes.
1139 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1140 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001141
Tim Northover398c5f52017-02-14 20:56:29 +00001142 case TargetOpcode::G_PTR_MASK: {
1143 uint64_t Align = I.getOperand(2).getImm();
1144 if (Align >= 64 || Align == 0)
1145 return false;
1146
1147 uint64_t Mask = ~((1ULL << Align) - 1);
1148 I.setDesc(TII.get(AArch64::ANDXri));
1149 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1150
1151 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1152 }
Tim Northover037af52c2016-10-31 18:31:09 +00001153 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001154 case TargetOpcode::G_TRUNC: {
1155 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1156 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1157
1158 const unsigned DstReg = I.getOperand(0).getReg();
1159 const unsigned SrcReg = I.getOperand(1).getReg();
1160
1161 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1162 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1163
1164 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001165 LLVM_DEBUG(
1166 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001167 return false;
1168 }
1169
1170 if (DstRB.getID() == AArch64::GPRRegBankID) {
1171 const TargetRegisterClass *DstRC =
1172 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1173 if (!DstRC)
1174 return false;
1175
1176 const TargetRegisterClass *SrcRC =
1177 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1178 if (!SrcRC)
1179 return false;
1180
1181 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1182 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001183 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001184 return false;
1185 }
1186
1187 if (DstRC == SrcRC) {
1188 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001189 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1190 SrcTy == LLT::scalar(64)) {
1191 llvm_unreachable("TableGen can import this case");
1192 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001193 } else if (DstRC == &AArch64::GPR32RegClass &&
1194 SrcRC == &AArch64::GPR64RegClass) {
1195 I.getOperand(1).setSubReg(AArch64::sub_32);
1196 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001197 LLVM_DEBUG(
1198 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001199 return false;
1200 }
1201
1202 I.setDesc(TII.get(TargetOpcode::COPY));
1203 return true;
1204 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1205 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1206 I.setDesc(TII.get(AArch64::XTNv4i16));
1207 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1208 return true;
1209 }
1210 }
1211
1212 return false;
1213 }
1214
Tim Northover3d38b3a2016-10-11 20:50:21 +00001215 case TargetOpcode::G_ANYEXT: {
1216 const unsigned DstReg = I.getOperand(0).getReg();
1217 const unsigned SrcReg = I.getOperand(1).getReg();
1218
Quentin Colombetcb629a82016-10-12 03:57:49 +00001219 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1220 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001221 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1222 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001223 return false;
1224 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001225
Quentin Colombetcb629a82016-10-12 03:57:49 +00001226 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1227 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001228 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1229 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001230 return false;
1231 }
1232
1233 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1234
1235 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001236 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001237 return false;
1238 }
1239
Quentin Colombetcb629a82016-10-12 03:57:49 +00001240 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001241 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1242 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001243 return false;
1244 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001245 // At this point G_ANYEXT is just like a plain COPY, but we need
1246 // to explicitly form the 64-bit value if any.
1247 if (DstSize > 32) {
1248 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1249 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1250 .addDef(ExtSrc)
1251 .addImm(0)
1252 .addUse(SrcReg)
1253 .addImm(AArch64::sub_32);
1254 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001255 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001256 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001257 }
1258
1259 case TargetOpcode::G_ZEXT:
1260 case TargetOpcode::G_SEXT: {
1261 unsigned Opcode = I.getOpcode();
1262 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1263 SrcTy = MRI.getType(I.getOperand(1).getReg());
1264 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1265 const unsigned DefReg = I.getOperand(0).getReg();
1266 const unsigned SrcReg = I.getOperand(1).getReg();
1267 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1268
1269 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001270 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1271 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001272 return false;
1273 }
1274
1275 MachineInstr *ExtI;
1276 if (DstTy == LLT::scalar(64)) {
1277 // FIXME: Can we avoid manually doing this?
1278 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001279 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1280 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001281 return false;
1282 }
1283
1284 const unsigned SrcXReg =
1285 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1286 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1287 .addDef(SrcXReg)
1288 .addImm(0)
1289 .addUse(SrcReg)
1290 .addImm(AArch64::sub_32);
1291
1292 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1293 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1294 .addDef(DefReg)
1295 .addUse(SrcXReg)
1296 .addImm(0)
1297 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001298 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001299 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1300 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1301 .addDef(DefReg)
1302 .addUse(SrcReg)
1303 .addImm(0)
1304 .addImm(SrcTy.getSizeInBits() - 1);
1305 } else {
1306 return false;
1307 }
1308
1309 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1310
1311 I.eraseFromParent();
1312 return true;
1313 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001314
Tim Northover69271c62016-10-12 22:49:11 +00001315 case TargetOpcode::G_SITOFP:
1316 case TargetOpcode::G_UITOFP:
1317 case TargetOpcode::G_FPTOSI:
1318 case TargetOpcode::G_FPTOUI: {
1319 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1320 SrcTy = MRI.getType(I.getOperand(1).getReg());
1321 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1322 if (NewOpc == Opcode)
1323 return false;
1324
1325 I.setDesc(TII.get(NewOpc));
1326 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1327
1328 return true;
1329 }
1330
1331
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001332 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001333 // The importer is currently unable to import pointer types since they
1334 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001335 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001336
Daniel Sandersedd07842017-08-17 09:26:14 +00001337 case TargetOpcode::G_BITCAST:
1338 // Imported SelectionDAG rules can handle every bitcast except those that
1339 // bitcast from a type to the same type. Ideally, these shouldn't occur
1340 // but we might not run an optimizer that deletes them.
1341 if (MRI.getType(I.getOperand(0).getReg()) ==
1342 MRI.getType(I.getOperand(1).getReg()))
1343 return selectCopy(I, TII, MRI, TRI, RBI);
1344 return false;
1345
Tim Northover9ac0eba2016-11-08 00:45:29 +00001346 case TargetOpcode::G_SELECT: {
1347 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001348 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1349 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001350 return false;
1351 }
1352
1353 const unsigned CondReg = I.getOperand(1).getReg();
1354 const unsigned TReg = I.getOperand(2).getReg();
1355 const unsigned FReg = I.getOperand(3).getReg();
1356
1357 unsigned CSelOpc = 0;
1358
1359 if (Ty == LLT::scalar(32)) {
1360 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001361 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001362 CSelOpc = AArch64::CSELXr;
1363 } else {
1364 return false;
1365 }
1366
1367 MachineInstr &TstMI =
1368 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1369 .addDef(AArch64::WZR)
1370 .addUse(CondReg)
1371 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1372
1373 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1374 .addDef(I.getOperand(0).getReg())
1375 .addUse(TReg)
1376 .addUse(FReg)
1377 .addImm(AArch64CC::NE);
1378
1379 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1380 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1381
1382 I.eraseFromParent();
1383 return true;
1384 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001385 case TargetOpcode::G_ICMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001386 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001387 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1388 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001389 return false;
1390 }
1391
1392 unsigned CmpOpc = 0;
1393 unsigned ZReg = 0;
1394
1395 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1396 if (CmpTy == LLT::scalar(32)) {
1397 CmpOpc = AArch64::SUBSWrr;
1398 ZReg = AArch64::WZR;
1399 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1400 CmpOpc = AArch64::SUBSXrr;
1401 ZReg = AArch64::XZR;
1402 } else {
1403 return false;
1404 }
1405
Kristof Beyls22524402017-01-05 10:16:08 +00001406 // CSINC increments the result by one when the condition code is false.
1407 // Therefore, we have to invert the predicate to get an increment by 1 when
1408 // the predicate is true.
1409 const AArch64CC::CondCode invCC =
1410 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1411 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001412
1413 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1414 .addDef(ZReg)
1415 .addUse(I.getOperand(2).getReg())
1416 .addUse(I.getOperand(3).getReg());
1417
1418 MachineInstr &CSetMI =
1419 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1420 .addDef(I.getOperand(0).getReg())
1421 .addUse(AArch64::WZR)
1422 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001423 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001424
1425 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1426 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1427
1428 I.eraseFromParent();
1429 return true;
1430 }
1431
Tim Northover7dd378d2016-10-12 22:49:07 +00001432 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001433 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001434 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1435 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001436 return false;
1437 }
1438
1439 unsigned CmpOpc = 0;
1440 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1441 if (CmpTy == LLT::scalar(32)) {
1442 CmpOpc = AArch64::FCMPSrr;
1443 } else if (CmpTy == LLT::scalar(64)) {
1444 CmpOpc = AArch64::FCMPDrr;
1445 } else {
1446 return false;
1447 }
1448
1449 // FIXME: regbank
1450
1451 AArch64CC::CondCode CC1, CC2;
1452 changeFCMPPredToAArch64CC(
1453 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1454
1455 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1456 .addUse(I.getOperand(2).getReg())
1457 .addUse(I.getOperand(3).getReg());
1458
1459 const unsigned DefReg = I.getOperand(0).getReg();
1460 unsigned Def1Reg = DefReg;
1461 if (CC2 != AArch64CC::AL)
1462 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1463
1464 MachineInstr &CSetMI =
1465 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1466 .addDef(Def1Reg)
1467 .addUse(AArch64::WZR)
1468 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001469 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001470
1471 if (CC2 != AArch64CC::AL) {
1472 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1473 MachineInstr &CSet2MI =
1474 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1475 .addDef(Def2Reg)
1476 .addUse(AArch64::WZR)
1477 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001478 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001479 MachineInstr &OrMI =
1480 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1481 .addDef(DefReg)
1482 .addUse(Def1Reg)
1483 .addUse(Def2Reg);
1484 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1485 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1486 }
1487
1488 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1489 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1490
1491 I.eraseFromParent();
1492 return true;
1493 }
Tim Northovere9600d82017-02-08 17:57:27 +00001494 case TargetOpcode::G_VASTART:
1495 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1496 : selectVaStartAAPCS(I, MF, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001497 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1498 if (!I.getOperand(0).isIntrinsicID())
1499 return false;
1500 if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1501 return false;
1502 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::BRK))
1503 .addImm(1);
1504 I.eraseFromParent();
1505 return true;
Amara Emerson1e8c1642018-07-31 00:09:02 +00001506 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001507 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001508 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1509 const unsigned DstReg = I.getOperand(0).getReg();
1510 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1511 const TargetRegisterClass *DstRC =
1512 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1513 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001514 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001515 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001516 case TargetOpcode::G_BLOCK_ADDR: {
1517 if (TM.getCodeModel() == CodeModel::Large) {
1518 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1519 I.eraseFromParent();
1520 return true;
1521 } else {
1522 I.setDesc(TII.get(AArch64::MOVaddrBA));
1523 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1524 I.getOperand(0).getReg())
1525 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1526 /* Offset */ 0, AArch64II::MO_PAGE)
1527 .addBlockAddress(
1528 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1529 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1530 I.eraseFromParent();
1531 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1532 }
1533 }
Amara Emerson5ec14602018-12-10 18:44:58 +00001534 case TargetOpcode::G_BUILD_VECTOR:
1535 return selectBuildVector(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001536 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001537
1538 return false;
1539}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001540
Amara Emerson5ec14602018-12-10 18:44:58 +00001541bool AArch64InstructionSelector::emitScalarToVector(
1542 unsigned &Dst, const LLT DstTy, const TargetRegisterClass *DstRC,
1543 unsigned Scalar, MachineBasicBlock &MBB,
1544 MachineBasicBlock::iterator MBBI, MachineRegisterInfo &MRI) const {
1545 Dst = MRI.createVirtualRegister(DstRC);
1546
1547 unsigned UndefVec = MRI.createVirtualRegister(DstRC);
1548 MachineInstr &UndefMI = *BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1549 TII.get(TargetOpcode::IMPLICIT_DEF))
1550 .addDef(UndefVec);
1551
1552 auto BuildFn = [&](unsigned SubregIndex) {
1553 MachineInstr &InsMI = *BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1554 TII.get(TargetOpcode::INSERT_SUBREG))
1555 .addDef(Dst)
1556 .addUse(UndefVec)
1557 .addUse(Scalar)
1558 .addImm(SubregIndex);
1559 constrainSelectedInstRegOperands(UndefMI, TII, TRI, RBI);
1560 return constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1561 };
1562
1563 switch (DstTy.getElementType().getSizeInBits()) {
1564 case 32:
1565 return BuildFn(AArch64::ssub);
1566 case 64:
1567 return BuildFn(AArch64::dsub);
1568 default:
1569 return false;
1570 }
1571}
1572
1573bool AArch64InstructionSelector::selectBuildVector(
1574 MachineInstr &I, MachineRegisterInfo &MRI) const {
1575 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
1576 // Until we port more of the optimized selections, for now just use a vector
1577 // insert sequence.
1578 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1579 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
1580 unsigned EltSize = EltTy.getSizeInBits();
1581 if (EltSize < 32 || EltSize > 64)
1582 return false; // Don't support all element types yet.
1583 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1584 unsigned Opc;
1585 unsigned SubregIdx;
1586 if (RB.getID() == AArch64::GPRRegBankID) {
1587 if (EltSize == 32) {
1588 Opc = AArch64::INSvi32gpr;
1589 SubregIdx = AArch64::ssub;
1590 } else {
1591 Opc = AArch64::INSvi64gpr;
1592 SubregIdx = AArch64::dsub;
1593 }
1594 } else {
1595 if (EltSize == 32) {
1596 Opc = AArch64::INSvi32lane;
1597 SubregIdx = AArch64::ssub;
1598 } else {
1599 Opc = AArch64::INSvi64lane;
1600 SubregIdx = AArch64::dsub;
1601 }
1602 }
1603
1604 if (EltSize * DstTy.getNumElements() != 128)
1605 return false; // Don't handle unpacked vectors yet.
1606
1607 unsigned DstVec = 0;
1608 const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
1609 DstTy, RBI.getRegBank(AArch64::FPRRegBankID), RBI);
1610 emitScalarToVector(DstVec, DstTy, DstRC, I.getOperand(1).getReg(),
1611 *I.getParent(), I.getIterator(), MRI);
1612 for (unsigned i = 2, e = DstTy.getSizeInBits() / EltSize + 1; i < e; ++i) {
1613 unsigned InsDef;
1614 // For the last insert re-use the dst reg of the G_BUILD_VECTOR.
1615 if (i + 1 < e)
1616 InsDef = MRI.createVirtualRegister(DstRC);
1617 else
1618 InsDef = I.getOperand(0).getReg();
1619 unsigned LaneIdx = i - 1;
1620 if (RB.getID() == AArch64::FPRRegBankID) {
1621 unsigned ImpDef = MRI.createVirtualRegister(DstRC);
1622 MachineInstr &ImpDefMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1623 TII.get(TargetOpcode::IMPLICIT_DEF))
1624 .addDef(ImpDef);
1625 unsigned InsSubDef = MRI.createVirtualRegister(DstRC);
1626 MachineInstr &InsSubMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1627 TII.get(TargetOpcode::INSERT_SUBREG))
1628 .addDef(InsSubDef)
1629 .addUse(ImpDef)
1630 .addUse(I.getOperand(i).getReg())
1631 .addImm(SubregIdx);
1632 MachineInstr &InsEltMI =
1633 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
1634 .addDef(InsDef)
1635 .addUse(DstVec)
1636 .addImm(LaneIdx)
1637 .addUse(InsSubDef)
1638 .addImm(0);
1639 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
1640 constrainSelectedInstRegOperands(InsSubMI, TII, TRI, RBI);
1641 constrainSelectedInstRegOperands(InsEltMI, TII, TRI, RBI);
1642 DstVec = InsDef;
1643 } else {
1644 MachineInstr &InsMI =
1645 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
1646 .addDef(InsDef)
1647 .addUse(DstVec)
1648 .addImm(LaneIdx)
1649 .addUse(I.getOperand(i).getReg());
1650 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1651 DstVec = InsDef;
1652 }
1653 }
1654 I.eraseFromParent();
1655 return true;
1656}
1657
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001658/// SelectArithImmed - Select an immediate value that can be represented as
1659/// a 12-bit value shifted left by either 0 or 12. If so, return true with
1660/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001661InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00001662AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001663 MachineInstr &MI = *Root.getParent();
1664 MachineBasicBlock &MBB = *MI.getParent();
1665 MachineFunction &MF = *MBB.getParent();
1666 MachineRegisterInfo &MRI = MF.getRegInfo();
1667
1668 // This function is called from the addsub_shifted_imm ComplexPattern,
1669 // which lists [imm] as the list of opcode it's interested in, however
1670 // we still need to check whether the operand is actually an immediate
1671 // here because the ComplexPattern opcode list is only used in
1672 // root-level opcode matching.
1673 uint64_t Immed;
1674 if (Root.isImm())
1675 Immed = Root.getImm();
1676 else if (Root.isCImm())
1677 Immed = Root.getCImm()->getZExtValue();
1678 else if (Root.isReg()) {
1679 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
1680 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001681 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00001682 MachineOperand &Op1 = Def->getOperand(1);
1683 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001684 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00001685 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001686 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001687 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001688
1689 unsigned ShiftAmt;
1690
1691 if (Immed >> 12 == 0) {
1692 ShiftAmt = 0;
1693 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
1694 ShiftAmt = 12;
1695 Immed = Immed >> 12;
1696 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001697 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001698
1699 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001700 return {{
1701 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
1702 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
1703 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001704}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001705
Daniel Sandersea8711b2017-10-16 03:36:29 +00001706/// Select a "register plus unscaled signed 9-bit immediate" address. This
1707/// should only match when there is an offset that is not valid for a scaled
1708/// immediate addressing mode. The "Size" argument is the size in bytes of the
1709/// memory reference, which is needed here to know what is valid for a scaled
1710/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001711InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00001712AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
1713 unsigned Size) const {
1714 MachineRegisterInfo &MRI =
1715 Root.getParent()->getParent()->getParent()->getRegInfo();
1716
1717 if (!Root.isReg())
1718 return None;
1719
1720 if (!isBaseWithConstantOffset(Root, MRI))
1721 return None;
1722
1723 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
1724 if (!RootDef)
1725 return None;
1726
1727 MachineOperand &OffImm = RootDef->getOperand(2);
1728 if (!OffImm.isReg())
1729 return None;
1730 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
1731 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
1732 return None;
1733 int64_t RHSC;
1734 MachineOperand &RHSOp1 = RHS->getOperand(1);
1735 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
1736 return None;
1737 RHSC = RHSOp1.getCImm()->getSExtValue();
1738
1739 // If the offset is valid as a scaled immediate, don't match here.
1740 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
1741 return None;
1742 if (RHSC >= -256 && RHSC < 256) {
1743 MachineOperand &Base = RootDef->getOperand(1);
1744 return {{
1745 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
1746 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
1747 }};
1748 }
1749 return None;
1750}
1751
1752/// Select a "register plus scaled unsigned 12-bit immediate" address. The
1753/// "Size" argument is the size in bytes of the memory reference, which
1754/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001755InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00001756AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
1757 unsigned Size) const {
1758 MachineRegisterInfo &MRI =
1759 Root.getParent()->getParent()->getParent()->getRegInfo();
1760
1761 if (!Root.isReg())
1762 return None;
1763
1764 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
1765 if (!RootDef)
1766 return None;
1767
1768 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
1769 return {{
1770 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
1771 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
1772 }};
1773 }
1774
1775 if (isBaseWithConstantOffset(Root, MRI)) {
1776 MachineOperand &LHS = RootDef->getOperand(1);
1777 MachineOperand &RHS = RootDef->getOperand(2);
1778 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
1779 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
1780 if (LHSDef && RHSDef) {
1781 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
1782 unsigned Scale = Log2_32(Size);
1783 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
1784 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00001785 return {{
1786 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
1787 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
1788 }};
1789
Daniel Sandersea8711b2017-10-16 03:36:29 +00001790 return {{
1791 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
1792 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
1793 }};
1794 }
1795 }
1796 }
1797
1798 // Before falling back to our general case, check if the unscaled
1799 // instructions can handle this. If so, that's preferable.
1800 if (selectAddrModeUnscaled(Root, Size).hasValue())
1801 return None;
1802
1803 return {{
1804 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
1805 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
1806 }};
1807}
1808
Volkan Kelesf7f25682018-01-16 18:44:05 +00001809void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
1810 const MachineInstr &MI) const {
1811 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1812 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
1813 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
1814 assert(CstVal && "Expected constant value");
1815 MIB.addImm(CstVal.getValue());
1816}
1817
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001818namespace llvm {
1819InstructionSelector *
1820createAArch64InstructionSelector(const AArch64TargetMachine &TM,
1821 AArch64Subtarget &Subtarget,
1822 AArch64RegisterBankInfo &RBI) {
1823 return new AArch64InstructionSelector(TM, Subtarget, RBI);
1824}
1825}