blob: afbf5d5e23de271eefdd0c6037596d006eebfe51 [file] [log] [blame]
Eugene Zelenko60433b62017-10-05 00:33:50 +00001//===- X86InstructionSelector.cpp -----------------------------------------===//
Igor Bregerf7359d82017-02-22 12:25:09 +00002//
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/// X86.
12/// \todo This should be generated by TableGen.
13//===----------------------------------------------------------------------===//
14
Eugene Zelenko60433b62017-10-05 00:33:50 +000015#include "MCTargetDesc/X86BaseInfo.h"
Igor Bregera8ba5722017-03-23 15:25:57 +000016#include "X86InstrBuilder.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000017#include "X86InstrInfo.h"
18#include "X86RegisterBankInfo.h"
19#include "X86RegisterInfo.h"
20#include "X86Subtarget.h"
21#include "X86TargetMachine.h"
Igor Breger3b97ea32017-04-12 12:54:54 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000023#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
24#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
Igor Breger28f290f2017-05-17 12:48:08 +000025#include "llvm/CodeGen/GlobalISel/Utils.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000026#include "llvm/CodeGen/MachineBasicBlock.h"
Igor Breger21200ed2017-09-17 08:08:13 +000027#include "llvm/CodeGen/MachineConstantPool.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000028#include "llvm/CodeGen/MachineFunction.h"
29#include "llvm/CodeGen/MachineInstr.h"
30#include "llvm/CodeGen/MachineInstrBuilder.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000031#include "llvm/CodeGen/MachineMemOperand.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000032#include "llvm/CodeGen/MachineOperand.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000033#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000034#include "llvm/CodeGen/TargetOpcodes.h"
35#include "llvm/CodeGen/TargetRegisterInfo.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000036#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/InstrTypes.h"
38#include "llvm/Support/AtomicOrdering.h"
39#include "llvm/Support/CodeGen.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000040#include "llvm/Support/Debug.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000041#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/LowLevelTypeImpl.h"
43#include "llvm/Support/MathExtras.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000044#include "llvm/Support/raw_ostream.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000045#include <cassert>
46#include <cstdint>
47#include <tuple>
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000048
David Blaikie62651302017-10-26 23:39:54 +000049#define DEBUG_TYPE "X86-isel"
50
Igor Bregerf7359d82017-02-22 12:25:09 +000051using namespace llvm;
52
Daniel Sanders0b5293f2017-04-06 09:49:34 +000053namespace {
54
Daniel Sanderse7b0d662017-04-21 15:59:56 +000055#define GET_GLOBALISEL_PREDICATE_BITSET
56#include "X86GenGlobalISel.inc"
57#undef GET_GLOBALISEL_PREDICATE_BITSET
58
Daniel Sanders0b5293f2017-04-06 09:49:34 +000059class X86InstructionSelector : public InstructionSelector {
60public:
Daniel Sanderse7b0d662017-04-21 15:59:56 +000061 X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
Daniel Sanders0b5293f2017-04-06 09:49:34 +000062 const X86RegisterBankInfo &RBI);
63
Daniel Sandersf76f3152017-11-16 00:46:35 +000064 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000065 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000066
67private:
68 /// tblgen-erated 'select' implementation, used as the initial selector for
69 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000070 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000071
Hiroshi Inouebb703e82017-07-02 03:24:54 +000072 // TODO: remove after supported by Tablegen-erated instruction selection.
Igor Breger21200ed2017-09-17 08:08:13 +000073 unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
Daniel Sanders0b5293f2017-04-06 09:49:34 +000074 uint64_t Alignment) const;
75
Daniel Sanders0b5293f2017-04-06 09:49:34 +000076 bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
77 MachineFunction &MF) const;
Igor Breger810c6252017-05-08 09:40:43 +000078 bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
79 MachineFunction &MF) const;
Igor Breger717bd362017-07-02 08:58:29 +000080 bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
81 MachineFunction &MF) const;
Igor Breger3b97ea32017-04-12 12:54:54 +000082 bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
83 MachineFunction &MF) const;
Alexander Ivchenko46e07e32018-02-28 09:18:47 +000084 bool selectTruncOrPtrToInt(MachineInstr &I, MachineRegisterInfo &MRI,
85 MachineFunction &MF) const;
Igor Bregerfda31e62017-05-10 06:52:58 +000086 bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
87 MachineFunction &MF) const;
Igor Breger1f143642017-09-11 09:41:13 +000088 bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
89 MachineFunction &MF) const;
Igor Bregerc7b59772017-05-11 07:17:40 +000090 bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
91 MachineFunction &MF) const;
Igor Breger28f290f2017-05-17 12:48:08 +000092 bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
93 MachineFunction &MF) const;
Igor Breger1dcd5e82017-06-20 09:15:10 +000094 bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
Igor Bregerb186a692017-07-02 08:15:49 +000095 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
Daniel Sandersf76f3152017-11-16 00:46:35 +000096 MachineFunction &MF,
97 CodeGenCoverage &CoverageInfo) const;
Igor Breger0cddd342017-06-29 12:08:28 +000098 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
Daniel Sandersf76f3152017-11-16 00:46:35 +000099 MachineFunction &MF,
100 CodeGenCoverage &CoverageInfo) const;
Igor Breger1c29be72017-06-22 09:43:35 +0000101 bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
102 MachineFunction &MF) const;
Igor Bregerf5035d62017-06-25 11:42:17 +0000103 bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
104 MachineFunction &MF) const;
Igor Breger685889c2017-08-21 10:51:54 +0000105 bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
106 MachineFunction &MF) const;
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000107 bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
108 const unsigned DstReg,
109 const TargetRegisterClass *DstRC,
110 const unsigned SrcReg,
111 const TargetRegisterClass *SrcRC) const;
Igor Breger21200ed2017-09-17 08:08:13 +0000112 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
113 MachineFunction &MF) const;
Igor Breger2661ae42017-09-04 09:06:45 +0000114 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
Igor Breger1c29be72017-06-22 09:43:35 +0000115
116 // emit insert subreg instruction and insert it before MachineInstr &I
117 bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
118 MachineRegisterInfo &MRI, MachineFunction &MF) const;
Igor Bregerf5035d62017-06-25 11:42:17 +0000119 // emit extract subreg instruction and insert it before MachineInstr &I
120 bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
121 MachineRegisterInfo &MRI, MachineFunction &MF) const;
Igor Breger1dcd5e82017-06-20 09:15:10 +0000122
123 const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
124 const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
125 MachineRegisterInfo &MRI) const;
Igor Breger28f290f2017-05-17 12:48:08 +0000126
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000127 const X86TargetMachine &TM;
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000128 const X86Subtarget &STI;
129 const X86InstrInfo &TII;
130 const X86RegisterInfo &TRI;
131 const X86RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000132
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000133#define GET_GLOBALISEL_PREDICATES_DECL
134#include "X86GenGlobalISel.inc"
135#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000136
137#define GET_GLOBALISEL_TEMPORARIES_DECL
138#include "X86GenGlobalISel.inc"
139#undef GET_GLOBALISEL_TEMPORARIES_DECL
140};
141
142} // end anonymous namespace
143
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000144#define GET_GLOBALISEL_IMPL
Igor Bregerf7359d82017-02-22 12:25:09 +0000145#include "X86GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000146#undef GET_GLOBALISEL_IMPL
Igor Bregerf7359d82017-02-22 12:25:09 +0000147
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000148X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
149 const X86Subtarget &STI,
Igor Bregerf7359d82017-02-22 12:25:09 +0000150 const X86RegisterBankInfo &RBI)
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000151 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000152 TRI(*STI.getRegisterInfo()), RBI(RBI),
153#define GET_GLOBALISEL_PREDICATES_INIT
154#include "X86GenGlobalISel.inc"
155#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000156#define GET_GLOBALISEL_TEMPORARIES_INIT
157#include "X86GenGlobalISel.inc"
158#undef GET_GLOBALISEL_TEMPORARIES_INIT
159{
160}
Igor Bregerf7359d82017-02-22 12:25:09 +0000161
162// FIXME: This should be target-independent, inferred from the types declared
163// for each class in the bank.
Igor Breger1dcd5e82017-06-20 09:15:10 +0000164const TargetRegisterClass *
165X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000166 if (RB.getID() == X86::GPRRegBankID) {
Igor Breger4fdf1e42017-04-19 11:34:59 +0000167 if (Ty.getSizeInBits() <= 8)
168 return &X86::GR8RegClass;
169 if (Ty.getSizeInBits() == 16)
170 return &X86::GR16RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000171 if (Ty.getSizeInBits() == 32)
Igor Bregerf7359d82017-02-22 12:25:09 +0000172 return &X86::GR32RegClass;
173 if (Ty.getSizeInBits() == 64)
174 return &X86::GR64RegClass;
175 }
Igor Breger321cf3c2017-03-03 08:06:46 +0000176 if (RB.getID() == X86::VECRRegBankID) {
177 if (Ty.getSizeInBits() == 32)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000178 return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000179 if (Ty.getSizeInBits() == 64)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000180 return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000181 if (Ty.getSizeInBits() == 128)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000182 return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000183 if (Ty.getSizeInBits() == 256)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000184 return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000185 if (Ty.getSizeInBits() == 512)
186 return &X86::VR512RegClass;
187 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000188
189 llvm_unreachable("Unknown RegBank!");
190}
191
Igor Breger1dcd5e82017-06-20 09:15:10 +0000192const TargetRegisterClass *
193X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg,
194 MachineRegisterInfo &MRI) const {
195 const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
196 return getRegClass(Ty, RegBank);
197}
198
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000199static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
Igor Bregerb3a860a2017-08-20 07:14:40 +0000200 unsigned SubIdx = X86::NoSubRegister;
201 if (RC == &X86::GR32RegClass) {
202 SubIdx = X86::sub_32bit;
203 } else if (RC == &X86::GR16RegClass) {
204 SubIdx = X86::sub_16bit;
205 } else if (RC == &X86::GR8RegClass) {
206 SubIdx = X86::sub_8bit;
207 }
208
209 return SubIdx;
210}
211
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000212static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) {
Igor Bregerb3a860a2017-08-20 07:14:40 +0000213 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
214 if (X86::GR64RegClass.contains(Reg))
215 return &X86::GR64RegClass;
216 if (X86::GR32RegClass.contains(Reg))
217 return &X86::GR32RegClass;
218 if (X86::GR16RegClass.contains(Reg))
219 return &X86::GR16RegClass;
220 if (X86::GR8RegClass.contains(Reg))
221 return &X86::GR8RegClass;
222
223 llvm_unreachable("Unknown RegClass for PhysReg!");
224}
225
Igor Bregerf7359d82017-02-22 12:25:09 +0000226// Set X86 Opcode and constrain DestReg.
Igor Breger1dcd5e82017-06-20 09:15:10 +0000227bool X86InstructionSelector::selectCopy(MachineInstr &I,
228 MachineRegisterInfo &MRI) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000229 unsigned DstReg = I.getOperand(0).getReg();
Igor Bregerb3a860a2017-08-20 07:14:40 +0000230 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
231 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
Igor Bregerf7359d82017-02-22 12:25:09 +0000232
Igor Bregerf7359d82017-02-22 12:25:09 +0000233 unsigned SrcReg = I.getOperand(1).getReg();
234 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Igor Bregerb3a860a2017-08-20 07:14:40 +0000235 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
236
237 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
238 assert(I.isCopy() && "Generic operators do not allow physical registers");
239
240 if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
241 DstRegBank.getID() == X86::GPRRegBankID) {
242
243 const TargetRegisterClass *SrcRC =
244 getRegClass(MRI.getType(SrcReg), SrcRegBank);
245 const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
246
247 if (SrcRC != DstRC) {
248 // This case can be generated by ABI lowering, performe anyext
249 unsigned ExtSrc = MRI.createVirtualRegister(DstRC);
250 BuildMI(*I.getParent(), I, I.getDebugLoc(),
251 TII.get(TargetOpcode::SUBREG_TO_REG))
252 .addDef(ExtSrc)
253 .addImm(0)
254 .addReg(SrcReg)
255 .addImm(getSubRegIndex(SrcRC));
256
257 I.getOperand(1).setReg(ExtSrc);
258 }
259 }
260
261 return true;
262 }
Igor Breger360d0f22017-04-27 08:02:03 +0000263
Igor Bregerf7359d82017-02-22 12:25:09 +0000264 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
265 "No phys reg on generic operators");
266 assert((DstSize == SrcSize ||
267 // Copies are a mean to setup initial types, the number of
268 // bits may not exactly match.
269 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
270 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
271 "Copy with different width?!");
272
Igor Bregerb3a860a2017-08-20 07:14:40 +0000273 const TargetRegisterClass *DstRC =
274 getRegClass(MRI.getType(DstReg), DstRegBank);
Igor Bregerf7359d82017-02-22 12:25:09 +0000275
Igor Bregerb3a860a2017-08-20 07:14:40 +0000276 if (SrcRegBank.getID() == X86::GPRRegBankID &&
277 DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
278 TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
279 // Change the physical register to performe truncate.
Igor Breger360d0f22017-04-27 08:02:03 +0000280
Igor Bregerb3a860a2017-08-20 07:14:40 +0000281 const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
Igor Breger360d0f22017-04-27 08:02:03 +0000282
Igor Bregerb3a860a2017-08-20 07:14:40 +0000283 if (DstRC != SrcRC) {
284 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
Igor Breger360d0f22017-04-27 08:02:03 +0000285 I.getOperand(1).substPhysReg(SrcReg, TRI);
286 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000287 }
288
289 // No need to constrain SrcReg. It will get constrained when
290 // we hit another of its use or its defs.
291 // Copies do not have constraints.
Igor Breger8a924be2017-03-23 12:13:29 +0000292 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
Igor Bregerb3a860a2017-08-20 07:14:40 +0000293 if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
294 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Igor Breger8a924be2017-03-23 12:13:29 +0000295 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
296 << " operand\n");
297 return false;
298 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000299 }
300 I.setDesc(TII.get(X86::COPY));
301 return true;
302}
303
Daniel Sandersf76f3152017-11-16 00:46:35 +0000304bool X86InstructionSelector::select(MachineInstr &I,
305 CodeGenCoverage &CoverageInfo) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000306 assert(I.getParent() && "Instruction should be in a basic block!");
307 assert(I.getParent()->getParent() && "Instruction should be in a function!");
308
309 MachineBasicBlock &MBB = *I.getParent();
310 MachineFunction &MF = *MBB.getParent();
311 MachineRegisterInfo &MRI = MF.getRegInfo();
312
313 unsigned Opcode = I.getOpcode();
314 if (!isPreISelGenericOpcode(Opcode)) {
315 // Certain non-generic instructions also need some special handling.
316
Igor Breger03c22082017-08-21 09:17:28 +0000317 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
318 return false;
Igor Breger03c22082017-08-21 09:17:28 +0000319
Igor Bregerf7359d82017-02-22 12:25:09 +0000320 if (I.isCopy())
Igor Breger1dcd5e82017-06-20 09:15:10 +0000321 return selectCopy(I, MRI);
Igor Bregerf7359d82017-02-22 12:25:09 +0000322
Igor Bregerf7359d82017-02-22 12:25:09 +0000323 return true;
324 }
325
Benjamin Kramer5a7e0f82017-02-22 12:59:47 +0000326 assert(I.getNumOperands() == I.getNumExplicitOperands() &&
327 "Generic instruction has unexpected implicit operands\n");
Igor Bregerf7359d82017-02-22 12:25:09 +0000328
Daniel Sandersf76f3152017-11-16 00:46:35 +0000329 if (selectImpl(I, CoverageInfo))
Igor Bregerfda31e62017-05-10 06:52:58 +0000330 return true;
Igor Breger2452ef02017-05-01 07:06:08 +0000331
332 DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
333
334 // TODO: This should be implemented by tblgen.
Igor Breger06335bb2017-09-17 14:02:19 +0000335 switch (I.getOpcode()) {
336 default:
337 return false;
338 case TargetOpcode::G_STORE:
339 case TargetOpcode::G_LOAD:
340 return selectLoadStoreOp(I, MRI, MF);
341 case TargetOpcode::G_GEP:
342 case TargetOpcode::G_FRAME_INDEX:
343 return selectFrameIndexOrGep(I, MRI, MF);
344 case TargetOpcode::G_GLOBAL_VALUE:
345 return selectGlobalValue(I, MRI, MF);
346 case TargetOpcode::G_CONSTANT:
347 return selectConstant(I, MRI, MF);
348 case TargetOpcode::G_FCONSTANT:
349 return materializeFP(I, MRI, MF);
Alexander Ivchenko46e07e32018-02-28 09:18:47 +0000350 case TargetOpcode::G_PTRTOINT:
Igor Breger06335bb2017-09-17 14:02:19 +0000351 case TargetOpcode::G_TRUNC:
Alexander Ivchenko46e07e32018-02-28 09:18:47 +0000352 return selectTruncOrPtrToInt(I, MRI, MF);
Alexander Ivchenkoc01f7502018-02-28 12:11:53 +0000353 case TargetOpcode::G_INTTOPTR:
354 return selectCopy(I, MRI);
Igor Breger06335bb2017-09-17 14:02:19 +0000355 case TargetOpcode::G_ZEXT:
356 return selectZext(I, MRI, MF);
357 case TargetOpcode::G_ANYEXT:
358 return selectAnyext(I, MRI, MF);
359 case TargetOpcode::G_ICMP:
360 return selectCmp(I, MRI, MF);
361 case TargetOpcode::G_UADDE:
362 return selectUadde(I, MRI, MF);
363 case TargetOpcode::G_UNMERGE_VALUES:
Daniel Sandersf76f3152017-11-16 00:46:35 +0000364 return selectUnmergeValues(I, MRI, MF, CoverageInfo);
Igor Breger06335bb2017-09-17 14:02:19 +0000365 case TargetOpcode::G_MERGE_VALUES:
Daniel Sandersf76f3152017-11-16 00:46:35 +0000366 return selectMergeValues(I, MRI, MF, CoverageInfo);
Igor Breger06335bb2017-09-17 14:02:19 +0000367 case TargetOpcode::G_EXTRACT:
368 return selectExtract(I, MRI, MF);
369 case TargetOpcode::G_INSERT:
370 return selectInsert(I, MRI, MF);
371 case TargetOpcode::G_BRCOND:
372 return selectCondBranch(I, MRI, MF);
373 case TargetOpcode::G_IMPLICIT_DEF:
374 case TargetOpcode::G_PHI:
375 return selectImplicitDefOrPHI(I, MRI);
376 }
Igor Breger321cf3c2017-03-03 08:06:46 +0000377
Igor Breger2452ef02017-05-01 07:06:08 +0000378 return false;
Igor Bregerf7359d82017-02-22 12:25:09 +0000379}
Igor Breger321cf3c2017-03-03 08:06:46 +0000380
Igor Breger21200ed2017-09-17 08:08:13 +0000381unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
382 const RegisterBank &RB,
Igor Bregera8ba5722017-03-23 15:25:57 +0000383 unsigned Opc,
384 uint64_t Alignment) const {
385 bool Isload = (Opc == TargetOpcode::G_LOAD);
386 bool HasAVX = STI.hasAVX();
387 bool HasAVX512 = STI.hasAVX512();
388 bool HasVLX = STI.hasVLX();
389
390 if (Ty == LLT::scalar(8)) {
391 if (X86::GPRRegBankID == RB.getID())
392 return Isload ? X86::MOV8rm : X86::MOV8mr;
393 } else if (Ty == LLT::scalar(16)) {
394 if (X86::GPRRegBankID == RB.getID())
395 return Isload ? X86::MOV16rm : X86::MOV16mr;
Igor Bregera9edb882017-05-01 06:08:32 +0000396 } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
Igor Bregera8ba5722017-03-23 15:25:57 +0000397 if (X86::GPRRegBankID == RB.getID())
398 return Isload ? X86::MOV32rm : X86::MOV32mr;
399 if (X86::VECRRegBankID == RB.getID())
400 return Isload ? (HasAVX512 ? X86::VMOVSSZrm
401 : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
402 : (HasAVX512 ? X86::VMOVSSZmr
403 : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
Igor Bregera9edb882017-05-01 06:08:32 +0000404 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Igor Bregera8ba5722017-03-23 15:25:57 +0000405 if (X86::GPRRegBankID == RB.getID())
406 return Isload ? X86::MOV64rm : X86::MOV64mr;
407 if (X86::VECRRegBankID == RB.getID())
408 return Isload ? (HasAVX512 ? X86::VMOVSDZrm
409 : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm)
410 : (HasAVX512 ? X86::VMOVSDZmr
411 : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr);
412 } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
413 if (Alignment >= 16)
414 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
415 : HasAVX512
416 ? X86::VMOVAPSZ128rm_NOVLX
417 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
418 : (HasVLX ? X86::VMOVAPSZ128mr
419 : HasAVX512
420 ? X86::VMOVAPSZ128mr_NOVLX
421 : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
422 else
423 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
424 : HasAVX512
425 ? X86::VMOVUPSZ128rm_NOVLX
426 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
427 : (HasVLX ? X86::VMOVUPSZ128mr
428 : HasAVX512
429 ? X86::VMOVUPSZ128mr_NOVLX
430 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
Igor Breger617be6e2017-05-23 08:23:51 +0000431 } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
432 if (Alignment >= 32)
433 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
434 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
435 : X86::VMOVAPSYrm)
436 : (HasVLX ? X86::VMOVAPSZ256mr
437 : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
438 : X86::VMOVAPSYmr);
439 else
440 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
441 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
442 : X86::VMOVUPSYrm)
443 : (HasVLX ? X86::VMOVUPSZ256mr
444 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
445 : X86::VMOVUPSYmr);
446 } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
447 if (Alignment >= 64)
448 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
449 else
450 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
Igor Bregera8ba5722017-03-23 15:25:57 +0000451 }
452 return Opc;
453}
454
Igor Bregerbd2deda2017-06-19 13:12:57 +0000455// Fill in an address from the given instruction.
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000456static void X86SelectAddress(const MachineInstr &I,
457 const MachineRegisterInfo &MRI,
458 X86AddressMode &AM) {
Igor Bregerbd2deda2017-06-19 13:12:57 +0000459 assert(I.getOperand(0).isReg() && "unsupported opperand.");
460 assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
461 "unsupported type.");
462
463 if (I.getOpcode() == TargetOpcode::G_GEP) {
464 if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) {
465 int64_t Imm = *COff;
466 if (isInt<32>(Imm)) { // Check for displacement overflow.
467 AM.Disp = static_cast<int32_t>(Imm);
468 AM.Base.Reg = I.getOperand(1).getReg();
469 return;
470 }
471 }
472 } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) {
473 AM.Base.FrameIndex = I.getOperand(1).getIndex();
474 AM.BaseType = X86AddressMode::FrameIndexBase;
475 return;
476 }
477
478 // Default behavior.
479 AM.Base.Reg = I.getOperand(0).getReg();
Igor Bregerbd2deda2017-06-19 13:12:57 +0000480}
481
Igor Bregera8ba5722017-03-23 15:25:57 +0000482bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
483 MachineRegisterInfo &MRI,
484 MachineFunction &MF) const {
Igor Bregera8ba5722017-03-23 15:25:57 +0000485 unsigned Opc = I.getOpcode();
486
Igor Breger06335bb2017-09-17 14:02:19 +0000487 assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
488 "unexpected instruction");
Igor Bregera8ba5722017-03-23 15:25:57 +0000489
490 const unsigned DefReg = I.getOperand(0).getReg();
491 LLT Ty = MRI.getType(DefReg);
492 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
493
494 auto &MemOp = **I.memoperands_begin();
Daniel Sanders3c1c4c02017-12-05 05:52:07 +0000495 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
496 DEBUG(dbgs() << "Atomic load/store not supported yet\n");
497 return false;
498 }
499
Igor Bregera8ba5722017-03-23 15:25:57 +0000500 unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
501 if (NewOpc == Opc)
502 return false;
503
Igor Bregerbd2deda2017-06-19 13:12:57 +0000504 X86AddressMode AM;
505 X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM);
506
Igor Bregera8ba5722017-03-23 15:25:57 +0000507 I.setDesc(TII.get(NewOpc));
508 MachineInstrBuilder MIB(MF, I);
Igor Bregerbd2deda2017-06-19 13:12:57 +0000509 if (Opc == TargetOpcode::G_LOAD) {
510 I.RemoveOperand(1);
511 addFullAddress(MIB, AM);
512 } else {
Igor Bregera8ba5722017-03-23 15:25:57 +0000513 // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
Igor Bregerbd2deda2017-06-19 13:12:57 +0000514 I.RemoveOperand(1);
Igor Bregera8ba5722017-03-23 15:25:57 +0000515 I.RemoveOperand(0);
Igor Bregerbd2deda2017-06-19 13:12:57 +0000516 addFullAddress(MIB, AM).addUse(DefReg);
Igor Bregera8ba5722017-03-23 15:25:57 +0000517 }
518 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
519}
520
Igor Breger717bd362017-07-02 08:58:29 +0000521static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
522 if (Ty == LLT::pointer(0, 64))
523 return X86::LEA64r;
524 else if (Ty == LLT::pointer(0, 32))
525 return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
526 else
527 llvm_unreachable("Can't get LEA opcode. Unsupported type.");
528}
529
Igor Breger810c6252017-05-08 09:40:43 +0000530bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
531 MachineRegisterInfo &MRI,
532 MachineFunction &MF) const {
533 unsigned Opc = I.getOpcode();
534
Igor Breger06335bb2017-09-17 14:02:19 +0000535 assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) &&
536 "unexpected instruction");
Igor Breger531a2032017-03-26 08:11:12 +0000537
538 const unsigned DefReg = I.getOperand(0).getReg();
539 LLT Ty = MRI.getType(DefReg);
540
Igor Breger810c6252017-05-08 09:40:43 +0000541 // Use LEA to calculate frame index and GEP
Igor Breger717bd362017-07-02 08:58:29 +0000542 unsigned NewOpc = getLeaOP(Ty, STI);
Igor Breger531a2032017-03-26 08:11:12 +0000543 I.setDesc(TII.get(NewOpc));
544 MachineInstrBuilder MIB(MF, I);
Igor Breger810c6252017-05-08 09:40:43 +0000545
546 if (Opc == TargetOpcode::G_FRAME_INDEX) {
547 addOffset(MIB, 0);
548 } else {
549 MachineOperand &InxOp = I.getOperand(2);
550 I.addOperand(InxOp); // set IndexReg
551 InxOp.ChangeToImmediate(1); // set Scale
552 MIB.addImm(0).addReg(0);
553 }
Igor Breger531a2032017-03-26 08:11:12 +0000554
555 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
556}
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000557
Igor Breger717bd362017-07-02 08:58:29 +0000558bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
559 MachineRegisterInfo &MRI,
560 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000561 assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
562 "unexpected instruction");
Igor Breger717bd362017-07-02 08:58:29 +0000563
564 auto GV = I.getOperand(1).getGlobal();
565 if (GV->isThreadLocal()) {
566 return false; // TODO: we don't support TLS yet.
567 }
568
569 // Can't handle alternate code models yet.
570 if (TM.getCodeModel() != CodeModel::Small)
Eugene Zelenko60433b62017-10-05 00:33:50 +0000571 return false;
Igor Breger717bd362017-07-02 08:58:29 +0000572
573 X86AddressMode AM;
574 AM.GV = GV;
575 AM.GVOpFlags = STI.classifyGlobalReference(GV);
576
577 // TODO: The ABI requires an extra load. not supported yet.
578 if (isGlobalStubReference(AM.GVOpFlags))
579 return false;
580
581 // TODO: This reference is relative to the pic base. not supported yet.
582 if (isGlobalRelativeToPICBase(AM.GVOpFlags))
583 return false;
584
585 if (STI.isPICStyleRIPRel()) {
586 // Use rip-relative addressing.
587 assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
588 AM.Base.Reg = X86::RIP;
589 }
590
591 const unsigned DefReg = I.getOperand(0).getReg();
592 LLT Ty = MRI.getType(DefReg);
593 unsigned NewOpc = getLeaOP(Ty, STI);
594
595 I.setDesc(TII.get(NewOpc));
596 MachineInstrBuilder MIB(MF, I);
597
598 I.RemoveOperand(1);
599 addFullAddress(MIB, AM);
600
601 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
602}
603
Igor Breger3b97ea32017-04-12 12:54:54 +0000604bool X86InstructionSelector::selectConstant(MachineInstr &I,
605 MachineRegisterInfo &MRI,
606 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000607 assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
608 "unexpected instruction");
Igor Breger3b97ea32017-04-12 12:54:54 +0000609
610 const unsigned DefReg = I.getOperand(0).getReg();
611 LLT Ty = MRI.getType(DefReg);
612
Igor Breger5c787ab2017-07-03 11:06:54 +0000613 if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
614 return false;
Igor Breger3b97ea32017-04-12 12:54:54 +0000615
616 uint64_t Val = 0;
617 if (I.getOperand(1).isCImm()) {
618 Val = I.getOperand(1).getCImm()->getZExtValue();
619 I.getOperand(1).ChangeToImmediate(Val);
620 } else if (I.getOperand(1).isImm()) {
621 Val = I.getOperand(1).getImm();
622 } else
623 llvm_unreachable("Unsupported operand type.");
624
625 unsigned NewOpc;
626 switch (Ty.getSizeInBits()) {
627 case 8:
628 NewOpc = X86::MOV8ri;
629 break;
630 case 16:
631 NewOpc = X86::MOV16ri;
632 break;
633 case 32:
634 NewOpc = X86::MOV32ri;
635 break;
Eugene Zelenko60433b62017-10-05 00:33:50 +0000636 case 64:
Igor Breger3b97ea32017-04-12 12:54:54 +0000637 // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
638 if (isInt<32>(Val))
639 NewOpc = X86::MOV64ri32;
640 else
641 NewOpc = X86::MOV64ri;
642 break;
Igor Breger3b97ea32017-04-12 12:54:54 +0000643 default:
644 llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
645 }
646
647 I.setDesc(TII.get(NewOpc));
648 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
649}
650
Alexander Ivchenko46e07e32018-02-28 09:18:47 +0000651// Helper function for selectTruncOrPtrToInt and selectAnyext.
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000652// Returns true if DstRC lives on a floating register class and
653// SrcRC lives on a 128-bit vector class.
654static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC,
655 const TargetRegisterClass *SrcRC) {
656 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
657 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
658 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
659}
660
661bool X86InstructionSelector::selectTurnIntoCOPY(
662 MachineInstr &I, MachineRegisterInfo &MRI, const unsigned DstReg,
663 const TargetRegisterClass *DstRC, const unsigned SrcReg,
664 const TargetRegisterClass *SrcRC) const {
665
666 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
667 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
668 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
669 << " operand\n");
670 return false;
671 }
672 I.setDesc(TII.get(X86::COPY));
673 return true;
674}
675
Alexander Ivchenko46e07e32018-02-28 09:18:47 +0000676bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
677 MachineRegisterInfo &MRI,
678 MachineFunction &MF) const {
679 assert((I.getOpcode() == TargetOpcode::G_TRUNC ||
680 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
681 "unexpected instruction");
Igor Breger4fdf1e42017-04-19 11:34:59 +0000682
683 const unsigned DstReg = I.getOperand(0).getReg();
684 const unsigned SrcReg = I.getOperand(1).getReg();
685
686 const LLT DstTy = MRI.getType(DstReg);
687 const LLT SrcTy = MRI.getType(SrcReg);
688
689 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
690 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
691
692 if (DstRB.getID() != SrcRB.getID()) {
Alexander Ivchenko46e07e32018-02-28 09:18:47 +0000693 DEBUG(dbgs() << TII.getName(I.getOpcode())
694 << " input/output on different banks\n");
Igor Breger4fdf1e42017-04-19 11:34:59 +0000695 return false;
696 }
697
Igor Breger1dcd5e82017-06-20 09:15:10 +0000698 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000699 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
700
701 if (!DstRC || !SrcRC)
Igor Breger4fdf1e42017-04-19 11:34:59 +0000702 return false;
703
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000704 // If that's truncation of the value that lives on the vector class and goes
705 // into the floating class, just replace it with copy, as we are able to
706 // select it as a regular move.
707 if (canTurnIntoCOPY(DstRC, SrcRC))
708 return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
709
710 if (DstRB.getID() != X86::GPRRegBankID)
Igor Breger4fdf1e42017-04-19 11:34:59 +0000711 return false;
712
Igor Breger014fc562017-05-21 11:13:56 +0000713 unsigned SubIdx;
714 if (DstRC == SrcRC) {
715 // Nothing to be done
716 SubIdx = X86::NoSubRegister;
717 } else if (DstRC == &X86::GR32RegClass) {
718 SubIdx = X86::sub_32bit;
719 } else if (DstRC == &X86::GR16RegClass) {
720 SubIdx = X86::sub_16bit;
721 } else if (DstRC == &X86::GR8RegClass) {
722 SubIdx = X86::sub_8bit;
723 } else {
724 return false;
725 }
726
727 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
728
Igor Breger4fdf1e42017-04-19 11:34:59 +0000729 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
730 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Alexander Ivchenko46e07e32018-02-28 09:18:47 +0000731 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
732 << "\n");
Igor Breger4fdf1e42017-04-19 11:34:59 +0000733 return false;
734 }
735
Igor Breger014fc562017-05-21 11:13:56 +0000736 I.getOperand(1).setSubReg(SubIdx);
Igor Breger4fdf1e42017-04-19 11:34:59 +0000737
738 I.setDesc(TII.get(X86::COPY));
739 return true;
740}
741
Igor Bregerfda31e62017-05-10 06:52:58 +0000742bool X86InstructionSelector::selectZext(MachineInstr &I,
743 MachineRegisterInfo &MRI,
744 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000745 assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
Igor Bregerfda31e62017-05-10 06:52:58 +0000746
747 const unsigned DstReg = I.getOperand(0).getReg();
748 const unsigned SrcReg = I.getOperand(1).getReg();
749
750 const LLT DstTy = MRI.getType(DstReg);
751 const LLT SrcTy = MRI.getType(SrcReg);
752
Igor Bregerd48c5e42017-07-10 09:07:34 +0000753 if (SrcTy != LLT::scalar(1))
754 return false;
Igor Bregerfda31e62017-05-10 06:52:58 +0000755
Igor Bregerd48c5e42017-07-10 09:07:34 +0000756 unsigned AndOpc;
757 if (DstTy == LLT::scalar(8))
Igor Breger324d3792017-07-11 08:04:51 +0000758 AndOpc = X86::AND8ri;
Igor Bregerd48c5e42017-07-10 09:07:34 +0000759 else if (DstTy == LLT::scalar(16))
760 AndOpc = X86::AND16ri8;
761 else if (DstTy == LLT::scalar(32))
762 AndOpc = X86::AND32ri8;
763 else if (DstTy == LLT::scalar(64))
764 AndOpc = X86::AND64ri8;
765 else
766 return false;
Igor Bregerfda31e62017-05-10 06:52:58 +0000767
Igor Bregerd48c5e42017-07-10 09:07:34 +0000768 unsigned DefReg = SrcReg;
769 if (DstTy != LLT::scalar(8)) {
770 DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
Igor Bregerfda31e62017-05-10 06:52:58 +0000771 BuildMI(*I.getParent(), I, I.getDebugLoc(),
772 TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
773 .addImm(0)
774 .addReg(SrcReg)
775 .addImm(X86::sub_8bit);
Igor Bregerfda31e62017-05-10 06:52:58 +0000776 }
777
Igor Bregerd48c5e42017-07-10 09:07:34 +0000778 MachineInstr &AndInst =
779 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
780 .addReg(DefReg)
781 .addImm(1);
782
783 constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
784
785 I.eraseFromParent();
786 return true;
Igor Bregerfda31e62017-05-10 06:52:58 +0000787}
788
Igor Breger1f143642017-09-11 09:41:13 +0000789bool X86InstructionSelector::selectAnyext(MachineInstr &I,
790 MachineRegisterInfo &MRI,
791 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000792 assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
Igor Breger1f143642017-09-11 09:41:13 +0000793
794 const unsigned DstReg = I.getOperand(0).getReg();
795 const unsigned SrcReg = I.getOperand(1).getReg();
796
797 const LLT DstTy = MRI.getType(DstReg);
798 const LLT SrcTy = MRI.getType(SrcReg);
799
800 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
801 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
802
Igor Breger21200ed2017-09-17 08:08:13 +0000803 assert(DstRB.getID() == SrcRB.getID() &&
804 "G_ANYEXT input/output on different banks\n");
Igor Breger1f143642017-09-11 09:41:13 +0000805
Igor Breger21200ed2017-09-17 08:08:13 +0000806 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
807 "G_ANYEXT incorrect operand size");
Igor Breger1f143642017-09-11 09:41:13 +0000808
Igor Breger1f143642017-09-11 09:41:13 +0000809 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
810 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
811
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000812 // If that's ANY_EXT of the value that lives on the floating class and goes
813 // into the vector class, just replace it with copy, as we are able to select
814 // it as a regular move.
815 if (canTurnIntoCOPY(SrcRC, DstRC))
816 return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC);
817
818 if (DstRB.getID() != X86::GPRRegBankID)
819 return false;
820
Igor Breger1f143642017-09-11 09:41:13 +0000821 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
822 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
823 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
824 << " operand\n");
825 return false;
826 }
827
828 if (SrcRC == DstRC) {
829 I.setDesc(TII.get(X86::COPY));
830 return true;
831 }
832
833 BuildMI(*I.getParent(), I, I.getDebugLoc(),
834 TII.get(TargetOpcode::SUBREG_TO_REG))
835 .addDef(DstReg)
836 .addImm(0)
837 .addReg(SrcReg)
838 .addImm(getSubRegIndex(SrcRC));
839
840 I.eraseFromParent();
841 return true;
842}
843
Igor Bregerc7b59772017-05-11 07:17:40 +0000844bool X86InstructionSelector::selectCmp(MachineInstr &I,
845 MachineRegisterInfo &MRI,
846 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000847 assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
Igor Bregerc7b59772017-05-11 07:17:40 +0000848
849 X86::CondCode CC;
850 bool SwapArgs;
851 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
852 (CmpInst::Predicate)I.getOperand(1).getPredicate());
853 unsigned OpSet = X86::getSETFromCond(CC);
854
855 unsigned LHS = I.getOperand(2).getReg();
856 unsigned RHS = I.getOperand(3).getReg();
857
858 if (SwapArgs)
859 std::swap(LHS, RHS);
860
861 unsigned OpCmp;
862 LLT Ty = MRI.getType(LHS);
863
864 switch (Ty.getSizeInBits()) {
865 default:
866 return false;
867 case 8:
868 OpCmp = X86::CMP8rr;
869 break;
870 case 16:
871 OpCmp = X86::CMP16rr;
872 break;
873 case 32:
874 OpCmp = X86::CMP32rr;
875 break;
876 case 64:
877 OpCmp = X86::CMP64rr;
878 break;
879 }
880
881 MachineInstr &CmpInst =
882 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
883 .addReg(LHS)
884 .addReg(RHS);
885
886 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
887 TII.get(OpSet), I.getOperand(0).getReg());
888
889 constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
890 constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
891
892 I.eraseFromParent();
893 return true;
894}
895
Igor Breger28f290f2017-05-17 12:48:08 +0000896bool X86InstructionSelector::selectUadde(MachineInstr &I,
897 MachineRegisterInfo &MRI,
898 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000899 assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction");
Igor Breger28f290f2017-05-17 12:48:08 +0000900
901 const unsigned DstReg = I.getOperand(0).getReg();
902 const unsigned CarryOutReg = I.getOperand(1).getReg();
903 const unsigned Op0Reg = I.getOperand(2).getReg();
904 const unsigned Op1Reg = I.getOperand(3).getReg();
905 unsigned CarryInReg = I.getOperand(4).getReg();
906
907 const LLT DstTy = MRI.getType(DstReg);
908
909 if (DstTy != LLT::scalar(32))
910 return false;
911
912 // find CarryIn def instruction.
913 MachineInstr *Def = MRI.getVRegDef(CarryInReg);
914 while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
915 CarryInReg = Def->getOperand(1).getReg();
916 Def = MRI.getVRegDef(CarryInReg);
917 }
918
919 unsigned Opcode;
920 if (Def->getOpcode() == TargetOpcode::G_UADDE) {
921 // carry set by prev ADD.
922
923 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
924 .addReg(CarryInReg);
925
926 if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
927 return false;
928
929 Opcode = X86::ADC32rr;
930 } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) {
931 // carry is constant, support only 0.
932 if (*val != 0)
933 return false;
934
935 Opcode = X86::ADD32rr;
936 } else
937 return false;
938
939 MachineInstr &AddInst =
940 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
941 .addReg(Op0Reg)
942 .addReg(Op1Reg);
943
944 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
945 .addReg(X86::EFLAGS);
946
947 if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
948 !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
949 return false;
950
951 I.eraseFromParent();
952 return true;
953}
954
Igor Bregerf5035d62017-06-25 11:42:17 +0000955bool X86InstructionSelector::selectExtract(MachineInstr &I,
956 MachineRegisterInfo &MRI,
957 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000958 assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
959 "unexpected instruction");
Igor Bregerf5035d62017-06-25 11:42:17 +0000960
961 const unsigned DstReg = I.getOperand(0).getReg();
962 const unsigned SrcReg = I.getOperand(1).getReg();
963 int64_t Index = I.getOperand(2).getImm();
964
965 const LLT DstTy = MRI.getType(DstReg);
966 const LLT SrcTy = MRI.getType(SrcReg);
967
968 // Meanwile handle vector type only.
969 if (!DstTy.isVector())
970 return false;
971
972 if (Index % DstTy.getSizeInBits() != 0)
973 return false; // Not extract subvector.
974
975 if (Index == 0) {
976 // Replace by extract subreg copy.
977 if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
978 return false;
979
980 I.eraseFromParent();
981 return true;
982 }
983
984 bool HasAVX = STI.hasAVX();
985 bool HasAVX512 = STI.hasAVX512();
986 bool HasVLX = STI.hasVLX();
987
988 if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
989 if (HasVLX)
990 I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
991 else if (HasAVX)
992 I.setDesc(TII.get(X86::VEXTRACTF128rr));
993 else
994 return false;
995 } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
996 if (DstTy.getSizeInBits() == 128)
997 I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
998 else if (DstTy.getSizeInBits() == 256)
999 I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
1000 else
1001 return false;
1002 } else
1003 return false;
1004
1005 // Convert to X86 VEXTRACT immediate.
1006 Index = Index / DstTy.getSizeInBits();
1007 I.getOperand(2).setImm(Index);
1008
1009 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1010}
1011
1012bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
1013 MachineInstr &I,
1014 MachineRegisterInfo &MRI,
1015 MachineFunction &MF) const {
Igor Bregerf5035d62017-06-25 11:42:17 +00001016 const LLT DstTy = MRI.getType(DstReg);
1017 const LLT SrcTy = MRI.getType(SrcReg);
1018 unsigned SubIdx = X86::NoSubRegister;
1019
1020 if (!DstTy.isVector() || !SrcTy.isVector())
1021 return false;
1022
1023 assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
1024 "Incorrect Src/Dst register size");
1025
1026 if (DstTy.getSizeInBits() == 128)
1027 SubIdx = X86::sub_xmm;
1028 else if (DstTy.getSizeInBits() == 256)
1029 SubIdx = X86::sub_ymm;
1030 else
1031 return false;
1032
1033 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1034 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1035
1036 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1037
1038 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1039 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1040 DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
1041 return false;
1042 }
1043
1044 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
1045 .addReg(SrcReg, 0, SubIdx);
1046
1047 return true;
1048}
1049
Igor Breger1c29be72017-06-22 09:43:35 +00001050bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
1051 MachineInstr &I,
1052 MachineRegisterInfo &MRI,
1053 MachineFunction &MF) const {
Igor Breger1c29be72017-06-22 09:43:35 +00001054 const LLT DstTy = MRI.getType(DstReg);
1055 const LLT SrcTy = MRI.getType(SrcReg);
1056 unsigned SubIdx = X86::NoSubRegister;
1057
1058 // TODO: support scalar types
1059 if (!DstTy.isVector() || !SrcTy.isVector())
1060 return false;
1061
1062 assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1063 "Incorrect Src/Dst register size");
1064
1065 if (SrcTy.getSizeInBits() == 128)
1066 SubIdx = X86::sub_xmm;
1067 else if (SrcTy.getSizeInBits() == 256)
1068 SubIdx = X86::sub_ymm;
1069 else
1070 return false;
1071
1072 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1073 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1074
1075 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1076 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1077 DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1078 return false;
1079 }
1080
1081 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1082 .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1083 .addReg(SrcReg);
1084
1085 return true;
1086}
1087
1088bool X86InstructionSelector::selectInsert(MachineInstr &I,
1089 MachineRegisterInfo &MRI,
1090 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001091 assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
Igor Breger1c29be72017-06-22 09:43:35 +00001092
1093 const unsigned DstReg = I.getOperand(0).getReg();
1094 const unsigned SrcReg = I.getOperand(1).getReg();
1095 const unsigned InsertReg = I.getOperand(2).getReg();
1096 int64_t Index = I.getOperand(3).getImm();
1097
1098 const LLT DstTy = MRI.getType(DstReg);
1099 const LLT InsertRegTy = MRI.getType(InsertReg);
1100
1101 // Meanwile handle vector type only.
1102 if (!DstTy.isVector())
1103 return false;
1104
1105 if (Index % InsertRegTy.getSizeInBits() != 0)
1106 return false; // Not insert subvector.
1107
1108 if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1109 // Replace by subreg copy.
1110 if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1111 return false;
1112
1113 I.eraseFromParent();
1114 return true;
1115 }
1116
1117 bool HasAVX = STI.hasAVX();
1118 bool HasAVX512 = STI.hasAVX512();
1119 bool HasVLX = STI.hasVLX();
1120
1121 if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
1122 if (HasVLX)
1123 I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
1124 else if (HasAVX)
1125 I.setDesc(TII.get(X86::VINSERTF128rr));
1126 else
1127 return false;
1128 } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
1129 if (InsertRegTy.getSizeInBits() == 128)
1130 I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
1131 else if (InsertRegTy.getSizeInBits() == 256)
1132 I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
1133 else
1134 return false;
1135 } else
1136 return false;
1137
1138 // Convert to X86 VINSERT immediate.
1139 Index = Index / InsertRegTy.getSizeInBits();
1140
1141 I.getOperand(3).setImm(Index);
1142
1143 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1144}
1145
Daniel Sandersf76f3152017-11-16 00:46:35 +00001146bool X86InstructionSelector::selectUnmergeValues(
1147 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF,
1148 CodeGenCoverage &CoverageInfo) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001149 assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1150 "unexpected instruction");
Igor Bregerb186a692017-07-02 08:15:49 +00001151
1152 // Split to extracts.
1153 unsigned NumDefs = I.getNumOperands() - 1;
1154 unsigned SrcReg = I.getOperand(NumDefs).getReg();
1155 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1156
1157 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
Igor Bregerb186a692017-07-02 08:15:49 +00001158 MachineInstr &ExtrInst =
1159 *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1160 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1161 .addReg(SrcReg)
1162 .addImm(Idx * DefSize);
1163
Daniel Sandersf76f3152017-11-16 00:46:35 +00001164 if (!select(ExtrInst, CoverageInfo))
Igor Bregerb186a692017-07-02 08:15:49 +00001165 return false;
1166 }
1167
1168 I.eraseFromParent();
1169 return true;
1170}
1171
Daniel Sandersf76f3152017-11-16 00:46:35 +00001172bool X86InstructionSelector::selectMergeValues(
1173 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF,
1174 CodeGenCoverage &CoverageInfo) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001175 assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES) &&
1176 "unexpected instruction");
Igor Breger0cddd342017-06-29 12:08:28 +00001177
1178 // Split to inserts.
1179 unsigned DstReg = I.getOperand(0).getReg();
1180 unsigned SrcReg0 = I.getOperand(1).getReg();
1181
1182 const LLT DstTy = MRI.getType(DstReg);
1183 const LLT SrcTy = MRI.getType(SrcReg0);
1184 unsigned SrcSize = SrcTy.getSizeInBits();
1185
1186 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1187
1188 // For the first src use insertSubReg.
1189 unsigned DefReg = MRI.createGenericVirtualRegister(DstTy);
1190 MRI.setRegBank(DefReg, RegBank);
1191 if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1192 return false;
1193
1194 for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
Igor Breger0cddd342017-06-29 12:08:28 +00001195 unsigned Tmp = MRI.createGenericVirtualRegister(DstTy);
1196 MRI.setRegBank(Tmp, RegBank);
1197
1198 MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1199 TII.get(TargetOpcode::G_INSERT), Tmp)
1200 .addReg(DefReg)
1201 .addReg(I.getOperand(Idx).getReg())
1202 .addImm((Idx - 1) * SrcSize);
1203
1204 DefReg = Tmp;
1205
Daniel Sandersf76f3152017-11-16 00:46:35 +00001206 if (!select(InsertInst, CoverageInfo))
Igor Breger0cddd342017-06-29 12:08:28 +00001207 return false;
1208 }
1209
1210 MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1211 TII.get(TargetOpcode::COPY), DstReg)
1212 .addReg(DefReg);
1213
Daniel Sandersf76f3152017-11-16 00:46:35 +00001214 if (!select(CopyInst, CoverageInfo))
Igor Breger0cddd342017-06-29 12:08:28 +00001215 return false;
1216
1217 I.eraseFromParent();
1218 return true;
1219}
Igor Breger685889c2017-08-21 10:51:54 +00001220
1221bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1222 MachineRegisterInfo &MRI,
1223 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001224 assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
Igor Breger685889c2017-08-21 10:51:54 +00001225
1226 const unsigned CondReg = I.getOperand(0).getReg();
1227 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1228
1229 MachineInstr &TestInst =
1230 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1231 .addReg(CondReg)
1232 .addImm(1);
1233 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
1234 .addMBB(DestMBB);
1235
1236 constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1237
1238 I.eraseFromParent();
1239 return true;
1240}
1241
Igor Breger21200ed2017-09-17 08:08:13 +00001242bool X86InstructionSelector::materializeFP(MachineInstr &I,
1243 MachineRegisterInfo &MRI,
1244 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001245 assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1246 "unexpected instruction");
Igor Breger21200ed2017-09-17 08:08:13 +00001247
1248 // Can't handle alternate code models yet.
1249 CodeModel::Model CM = TM.getCodeModel();
1250 if (CM != CodeModel::Small && CM != CodeModel::Large)
1251 return false;
1252
1253 const unsigned DstReg = I.getOperand(0).getReg();
1254 const LLT DstTy = MRI.getType(DstReg);
1255 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1256 unsigned Align = DstTy.getSizeInBits();
1257 const DebugLoc &DbgLoc = I.getDebugLoc();
1258
1259 unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
1260
1261 // Create the load from the constant pool.
1262 const ConstantFP *CFP = I.getOperand(1).getFPImm();
1263 unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
1264 MachineInstr *LoadInst = nullptr;
1265 unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1266
1267 if (CM == CodeModel::Large && STI.is64Bit()) {
1268 // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1269 // they cannot be folded into immediate fields.
1270
1271 unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1272 BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1273 .addConstantPoolIndex(CPI, 0, OpFlag);
1274
1275 MachineMemOperand *MMO = MF.getMachineMemOperand(
1276 MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1277 MF.getDataLayout().getPointerSize(), Align);
1278
1279 LoadInst =
1280 addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1281 AddrReg)
1282 .addMemOperand(MMO);
1283
Igor Breger06335bb2017-09-17 14:02:19 +00001284 } else if (CM == CodeModel::Small || !STI.is64Bit()) {
Igor Breger21200ed2017-09-17 08:08:13 +00001285 // Handle the case when globals fit in our immediate field.
1286 // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1287
1288 // x86-32 PIC requires a PIC base register for constant pools.
1289 unsigned PICBase = 0;
1290 if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
1291 // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1292 // In DAGISEL the code that initialize it generated by the CGBR pass.
1293 return false; // TODO support the mode.
Igor Breger06335bb2017-09-17 14:02:19 +00001294 } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
Igor Breger21200ed2017-09-17 08:08:13 +00001295 PICBase = X86::RIP;
1296
1297 LoadInst = addConstantPoolReference(
1298 BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1299 OpFlag);
1300 } else
1301 return false;
1302
1303 constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
1304 I.eraseFromParent();
1305 return true;
1306}
1307
Igor Breger2661ae42017-09-04 09:06:45 +00001308bool X86InstructionSelector::selectImplicitDefOrPHI(
1309 MachineInstr &I, MachineRegisterInfo &MRI) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001310 assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1311 I.getOpcode() == TargetOpcode::G_PHI) &&
1312 "unexpected instruction");
Igor Breger47be5fb2017-08-24 07:06:27 +00001313
1314 unsigned DstReg = I.getOperand(0).getReg();
1315
1316 if (!MRI.getRegClassOrNull(DstReg)) {
1317 const LLT DstTy = MRI.getType(DstReg);
1318 const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1319
1320 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1321 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1322 << " operand\n");
1323 return false;
1324 }
1325 }
1326
Igor Breger2661ae42017-09-04 09:06:45 +00001327 if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1328 I.setDesc(TII.get(X86::IMPLICIT_DEF));
1329 else
1330 I.setDesc(TII.get(X86::PHI));
1331
Igor Breger47be5fb2017-08-24 07:06:27 +00001332 return true;
1333}
1334
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001335InstructionSelector *
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001336llvm::createX86InstructionSelector(const X86TargetMachine &TM,
1337 X86Subtarget &Subtarget,
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001338 X86RegisterBankInfo &RBI) {
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001339 return new X86InstructionSelector(TM, Subtarget, RBI);
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001340}