/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86InstructionSelector.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- X86InstructionSelector.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 | | /// X86. |
12 | | /// \todo This should be generated by TableGen. |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "X86InstrBuilder.h" |
16 | | #include "X86InstrInfo.h" |
17 | | #include "X86RegisterBankInfo.h" |
18 | | #include "X86RegisterInfo.h" |
19 | | #include "X86Subtarget.h" |
20 | | #include "X86TargetMachine.h" |
21 | | #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" |
22 | | #include "llvm/CodeGen/GlobalISel/Utils.h" |
23 | | #include "llvm/CodeGen/MachineBasicBlock.h" |
24 | | #include "llvm/CodeGen/MachineConstantPool.h" |
25 | | #include "llvm/CodeGen/MachineFunction.h" |
26 | | #include "llvm/CodeGen/MachineInstr.h" |
27 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
28 | | #include "llvm/CodeGen/MachineOperand.h" |
29 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
30 | | #include "llvm/IR/Type.h" |
31 | | #include "llvm/Support/Debug.h" |
32 | | #include "llvm/Support/raw_ostream.h" |
33 | | |
34 | | #define DEBUG_TYPE "X86-isel" |
35 | | |
36 | | #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" |
37 | | |
38 | | using namespace llvm; |
39 | | |
40 | | namespace { |
41 | | |
42 | | #define GET_GLOBALISEL_PREDICATE_BITSET |
43 | | #include "X86GenGlobalISel.inc" |
44 | | #undef GET_GLOBALISEL_PREDICATE_BITSET |
45 | | |
46 | | class X86InstructionSelector : public InstructionSelector { |
47 | | public: |
48 | | X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI, |
49 | | const X86RegisterBankInfo &RBI); |
50 | | |
51 | | bool select(MachineInstr &I) const override; |
52 | | |
53 | | private: |
54 | | /// tblgen-erated 'select' implementation, used as the initial selector for |
55 | | /// the patterns that don't require complex C++. |
56 | | bool selectImpl(MachineInstr &I) const; |
57 | | |
58 | | // TODO: remove after supported by Tablegen-erated instruction selection. |
59 | | unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc, |
60 | | uint64_t Alignment) const; |
61 | | |
62 | | bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI, |
63 | | MachineFunction &MF) const; |
64 | | bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI, |
65 | | MachineFunction &MF) const; |
66 | | bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI, |
67 | | MachineFunction &MF) const; |
68 | | bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI, |
69 | | MachineFunction &MF) const; |
70 | | bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI, |
71 | | MachineFunction &MF) const; |
72 | | bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI, |
73 | | MachineFunction &MF) const; |
74 | | bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI, |
75 | | MachineFunction &MF) const; |
76 | | bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI, |
77 | | MachineFunction &MF) const; |
78 | | bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI, |
79 | | MachineFunction &MF) const; |
80 | | bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const; |
81 | | bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI, |
82 | | MachineFunction &MF) const; |
83 | | bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI, |
84 | | MachineFunction &MF) const; |
85 | | bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI, |
86 | | MachineFunction &MF) const; |
87 | | bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI, |
88 | | MachineFunction &MF) const; |
89 | | bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI, |
90 | | MachineFunction &MF) const; |
91 | | bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI, |
92 | | MachineFunction &MF) const; |
93 | | bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const; |
94 | | |
95 | | // emit insert subreg instruction and insert it before MachineInstr &I |
96 | | bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I, |
97 | | MachineRegisterInfo &MRI, MachineFunction &MF) const; |
98 | | // emit extract subreg instruction and insert it before MachineInstr &I |
99 | | bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I, |
100 | | MachineRegisterInfo &MRI, MachineFunction &MF) const; |
101 | | |
102 | | const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const; |
103 | | const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg, |
104 | | MachineRegisterInfo &MRI) const; |
105 | | |
106 | | const X86TargetMachine &TM; |
107 | | const X86Subtarget &STI; |
108 | | const X86InstrInfo &TII; |
109 | | const X86RegisterInfo &TRI; |
110 | | const X86RegisterBankInfo &RBI; |
111 | | |
112 | | #define GET_GLOBALISEL_PREDICATES_DECL |
113 | | #include "X86GenGlobalISel.inc" |
114 | | #undef GET_GLOBALISEL_PREDICATES_DECL |
115 | | |
116 | | #define GET_GLOBALISEL_TEMPORARIES_DECL |
117 | | #include "X86GenGlobalISel.inc" |
118 | | #undef GET_GLOBALISEL_TEMPORARIES_DECL |
119 | | }; |
120 | | |
121 | | } // end anonymous namespace |
122 | | |
123 | | #define GET_GLOBALISEL_IMPL |
124 | | #include "X86GenGlobalISel.inc" |
125 | | #undef GET_GLOBALISEL_IMPL |
126 | | |
127 | | X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM, |
128 | | const X86Subtarget &STI, |
129 | | const X86RegisterBankInfo &RBI) |
130 | | : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), |
131 | | TRI(*STI.getRegisterInfo()), RBI(RBI), |
132 | | #define GET_GLOBALISEL_PREDICATES_INIT |
133 | | #include "X86GenGlobalISel.inc" |
134 | | #undef GET_GLOBALISEL_PREDICATES_INIT |
135 | | #define GET_GLOBALISEL_TEMPORARIES_INIT |
136 | | #include "X86GenGlobalISel.inc" |
137 | | #undef GET_GLOBALISEL_TEMPORARIES_INIT |
138 | 9.64k | { |
139 | 9.64k | } |
140 | | |
141 | | // FIXME: This should be target-independent, inferred from the types declared |
142 | | // for each class in the bank. |
143 | | const TargetRegisterClass * |
144 | 1.50k | X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const { |
145 | 1.50k | if (RB.getID() == X86::GPRRegBankID1.50k ) { |
146 | 791 | if (Ty.getSizeInBits() <= 8) |
147 | 159 | return &X86::GR8RegClass; |
148 | 632 | if (632 Ty.getSizeInBits() == 16632 ) |
149 | 68 | return &X86::GR16RegClass; |
150 | 564 | if (564 Ty.getSizeInBits() == 32564 ) |
151 | 268 | return &X86::GR32RegClass; |
152 | 296 | if (296 Ty.getSizeInBits() == 64296 ) |
153 | 296 | return &X86::GR64RegClass; |
154 | 713 | } |
155 | 713 | if (713 RB.getID() == X86::VECRRegBankID713 ) { |
156 | 713 | if (Ty.getSizeInBits() == 32) |
157 | 85 | return STI.hasAVX512() ? 85 &X86::FR32XRegClass30 : &X86::FR32RegClass55 ; |
158 | 628 | if (628 Ty.getSizeInBits() == 64628 ) |
159 | 72 | return STI.hasAVX512() ? 72 &X86::FR64XRegClass28 : &X86::FR64RegClass44 ; |
160 | 556 | if (556 Ty.getSizeInBits() == 128556 ) |
161 | 269 | return STI.hasAVX512() ? 269 &X86::VR128XRegClass117 : &X86::VR128RegClass152 ; |
162 | 287 | if (287 Ty.getSizeInBits() == 256287 ) |
163 | 213 | return STI.hasAVX512() ? 213 &X86::VR256XRegClass86 : &X86::VR256RegClass127 ; |
164 | 74 | if (74 Ty.getSizeInBits() == 51274 ) |
165 | 74 | return &X86::VR512RegClass; |
166 | 0 | } |
167 | 0 |
|
168 | 0 | llvm_unreachable0 ("Unknown RegBank!"); |
169 | 0 | } |
170 | | |
171 | | const TargetRegisterClass * |
172 | | X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg, |
173 | 168 | MachineRegisterInfo &MRI) const { |
174 | 168 | const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI); |
175 | 168 | return getRegClass(Ty, RegBank); |
176 | 168 | } |
177 | | |
178 | 78 | static unsigned getSubRegIndex(const TargetRegisterClass *RC) { |
179 | 78 | unsigned SubIdx = X86::NoSubRegister; |
180 | 78 | if (RC == &X86::GR32RegClass78 ) { |
181 | 2 | SubIdx = X86::sub_32bit; |
182 | 78 | } else if (76 RC == &X86::GR16RegClass76 ) { |
183 | 31 | SubIdx = X86::sub_16bit; |
184 | 76 | } else if (45 RC == &X86::GR8RegClass45 ) { |
185 | 45 | SubIdx = X86::sub_8bit; |
186 | 45 | } |
187 | 78 | |
188 | 78 | return SubIdx; |
189 | 78 | } |
190 | | |
191 | 74 | static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) { |
192 | 74 | assert(TargetRegisterInfo::isPhysicalRegister(Reg)); |
193 | 74 | if (X86::GR64RegClass.contains(Reg)) |
194 | 1 | return &X86::GR64RegClass; |
195 | 73 | if (73 X86::GR32RegClass.contains(Reg)73 ) |
196 | 63 | return &X86::GR32RegClass; |
197 | 10 | if (10 X86::GR16RegClass.contains(Reg)10 ) |
198 | 2 | return &X86::GR16RegClass; |
199 | 8 | if (8 X86::GR8RegClass.contains(Reg)8 ) |
200 | 8 | return &X86::GR8RegClass; |
201 | 0 |
|
202 | 0 | llvm_unreachable0 ("Unknown RegClass for PhysReg!"); |
203 | 0 | } |
204 | | |
205 | | // Set X86 Opcode and constrain DestReg. |
206 | | bool X86InstructionSelector::selectCopy(MachineInstr &I, |
207 | 1.95k | MachineRegisterInfo &MRI) const { |
208 | 1.95k | |
209 | 1.95k | unsigned DstReg = I.getOperand(0).getReg(); |
210 | 1.95k | const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI); |
211 | 1.95k | const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI); |
212 | 1.95k | |
213 | 1.95k | unsigned SrcReg = I.getOperand(1).getReg(); |
214 | 1.95k | const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); |
215 | 1.95k | const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI); |
216 | 1.95k | |
217 | 1.95k | if (TargetRegisterInfo::isPhysicalRegister(DstReg)1.95k ) { |
218 | 758 | assert(I.isCopy() && "Generic operators do not allow physical registers"); |
219 | 758 | |
220 | 758 | if (DstSize > SrcSize && 758 SrcRegBank.getID() == X86::GPRRegBankID111 && |
221 | 758 | DstRegBank.getID() == X86::GPRRegBankID30 ) { |
222 | 12 | |
223 | 12 | const TargetRegisterClass *SrcRC = |
224 | 12 | getRegClass(MRI.getType(SrcReg), SrcRegBank); |
225 | 12 | const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg); |
226 | 12 | |
227 | 12 | if (SrcRC != DstRC12 ) { |
228 | 6 | // This case can be generated by ABI lowering, performe anyext |
229 | 6 | unsigned ExtSrc = MRI.createVirtualRegister(DstRC); |
230 | 6 | BuildMI(*I.getParent(), I, I.getDebugLoc(), |
231 | 6 | TII.get(TargetOpcode::SUBREG_TO_REG)) |
232 | 6 | .addDef(ExtSrc) |
233 | 6 | .addImm(0) |
234 | 6 | .addReg(SrcReg) |
235 | 6 | .addImm(getSubRegIndex(SrcRC)); |
236 | 6 | |
237 | 6 | I.getOperand(1).setReg(ExtSrc); |
238 | 6 | } |
239 | 12 | } |
240 | 758 | |
241 | 758 | return true; |
242 | 758 | } |
243 | 1.19k | |
244 | 1.95k | assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && |
245 | 1.19k | "No phys reg on generic operators"); |
246 | 1.19k | assert((DstSize == SrcSize || |
247 | 1.19k | // Copies are a mean to setup initial types, the number of |
248 | 1.19k | // bits may not exactly match. |
249 | 1.19k | (TargetRegisterInfo::isPhysicalRegister(SrcReg) && |
250 | 1.19k | DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) && |
251 | 1.19k | "Copy with different width?!"); |
252 | 1.19k | |
253 | 1.19k | const TargetRegisterClass *DstRC = |
254 | 1.19k | getRegClass(MRI.getType(DstReg), DstRegBank); |
255 | 1.19k | |
256 | 1.19k | if (SrcRegBank.getID() == X86::GPRRegBankID && |
257 | 1.19k | DstRegBank.getID() == X86::GPRRegBankID579 && SrcSize > DstSize576 && |
258 | 1.19k | TargetRegisterInfo::isPhysicalRegister(SrcReg)62 ) { |
259 | 62 | // Change the physical register to performe truncate. |
260 | 62 | |
261 | 62 | const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg); |
262 | 62 | |
263 | 62 | if (DstRC != SrcRC62 ) { |
264 | 60 | I.getOperand(1).setSubReg(getSubRegIndex(DstRC)); |
265 | 60 | I.getOperand(1).substPhysReg(SrcReg, TRI); |
266 | 60 | } |
267 | 62 | } |
268 | 1.19k | |
269 | 1.19k | // No need to constrain SrcReg. It will get constrained when |
270 | 1.19k | // we hit another of its use or its defs. |
271 | 1.19k | // Copies do not have constraints. |
272 | 1.19k | const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg); |
273 | 1.19k | if (!OldRC || 1.19k !DstRC->hasSubClassEq(OldRC)1.10k ) { |
274 | 86 | if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)86 ) { |
275 | 0 | DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) |
276 | 0 | << " operand\n"); |
277 | 0 | return false; |
278 | 0 | } |
279 | 1.19k | } |
280 | 1.19k | I.setDesc(TII.get(X86::COPY)); |
281 | 1.19k | return true; |
282 | 1.19k | } |
283 | | |
284 | 4.13k | bool X86InstructionSelector::select(MachineInstr &I) const { |
285 | 4.13k | assert(I.getParent() && "Instruction should be in a basic block!"); |
286 | 4.13k | assert(I.getParent()->getParent() && "Instruction should be in a function!"); |
287 | 4.13k | |
288 | 4.13k | MachineBasicBlock &MBB = *I.getParent(); |
289 | 4.13k | MachineFunction &MF = *MBB.getParent(); |
290 | 4.13k | MachineRegisterInfo &MRI = MF.getRegInfo(); |
291 | 4.13k | |
292 | 4.13k | unsigned Opcode = I.getOpcode(); |
293 | 4.13k | if (!isPreISelGenericOpcode(Opcode)4.13k ) { |
294 | 2.79k | // Certain non-generic instructions also need some special handling. |
295 | 2.79k | |
296 | 2.79k | if (Opcode == TargetOpcode::LOAD_STACK_GUARD) |
297 | 0 | return false; |
298 | 2.79k | |
299 | 2.79k | if (2.79k I.isCopy()2.79k ) |
300 | 1.95k | return selectCopy(I, MRI); |
301 | 845 | |
302 | 845 | return true; |
303 | 845 | } |
304 | 1.34k | |
305 | 4.13k | assert(I.getNumOperands() == I.getNumExplicitOperands() && |
306 | 1.34k | "Generic instruction has unexpected implicit operands\n"); |
307 | 1.34k | |
308 | 1.34k | if (selectImpl(I)) |
309 | 495 | return true; |
310 | 845 | |
311 | 845 | DEBUG845 (dbgs() << " C++ instruction selection: "; I.print(dbgs())); |
312 | 845 | |
313 | 845 | // TODO: This should be implemented by tblgen. |
314 | 845 | switch (I.getOpcode()) { |
315 | 0 | default: |
316 | 0 | return false; |
317 | 399 | case TargetOpcode::G_STORE: |
318 | 399 | case TargetOpcode::G_LOAD: |
319 | 399 | return selectLoadStoreOp(I, MRI, MF); |
320 | 31 | case TargetOpcode::G_GEP: |
321 | 31 | case TargetOpcode::G_FRAME_INDEX: |
322 | 31 | return selectFrameIndexOrGep(I, MRI, MF); |
323 | 25 | case TargetOpcode::G_GLOBAL_VALUE: |
324 | 25 | return selectGlobalValue(I, MRI, MF); |
325 | 26 | case TargetOpcode::G_CONSTANT: |
326 | 26 | return selectConstant(I, MRI, MF); |
327 | 15 | case TargetOpcode::G_FCONSTANT: |
328 | 15 | return materializeFP(I, MRI, MF); |
329 | 42 | case TargetOpcode::G_TRUNC: |
330 | 42 | return selectTrunc(I, MRI, MF); |
331 | 50 | case TargetOpcode::G_ZEXT: |
332 | 50 | return selectZext(I, MRI, MF); |
333 | 24 | case TargetOpcode::G_ANYEXT: |
334 | 24 | return selectAnyext(I, MRI, MF); |
335 | 45 | case TargetOpcode::G_ICMP: |
336 | 45 | return selectCmp(I, MRI, MF); |
337 | 4 | case TargetOpcode::G_UADDE: |
338 | 4 | return selectUadde(I, MRI, MF); |
339 | 28 | case TargetOpcode::G_UNMERGE_VALUES: |
340 | 28 | return selectUnmergeValues(I, MRI, MF); |
341 | 16 | case TargetOpcode::G_MERGE_VALUES: |
342 | 16 | return selectMergeValues(I, MRI, MF); |
343 | 70 | case TargetOpcode::G_EXTRACT: |
344 | 70 | return selectExtract(I, MRI, MF); |
345 | 34 | case TargetOpcode::G_INSERT: |
346 | 34 | return selectInsert(I, MRI, MF); |
347 | 18 | case TargetOpcode::G_BRCOND: |
348 | 18 | return selectCondBranch(I, MRI, MF); |
349 | 18 | case TargetOpcode::G_IMPLICIT_DEF: |
350 | 18 | case TargetOpcode::G_PHI: |
351 | 18 | return selectImplicitDefOrPHI(I, MRI); |
352 | 0 | } |
353 | 0 |
|
354 | 0 | return false; |
355 | 0 | } |
356 | | |
357 | | unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty, |
358 | | const RegisterBank &RB, |
359 | | unsigned Opc, |
360 | 414 | uint64_t Alignment) const { |
361 | 414 | bool Isload = (Opc == TargetOpcode::G_LOAD); |
362 | 414 | bool HasAVX = STI.hasAVX(); |
363 | 414 | bool HasAVX512 = STI.hasAVX512(); |
364 | 414 | bool HasVLX = STI.hasVLX(); |
365 | 414 | |
366 | 414 | if (Ty == LLT::scalar(8)414 ) { |
367 | 42 | if (X86::GPRRegBankID == RB.getID()) |
368 | 42 | return Isload ? 42 X86::MOV8rm34 : X86::MOV8mr8 ; |
369 | 372 | } else if (372 Ty == LLT::scalar(16)372 ) { |
370 | 20 | if (X86::GPRRegBankID == RB.getID()) |
371 | 20 | return Isload ? 20 X86::MOV16rm17 : X86::MOV16mr3 ; |
372 | 352 | } else if (352 Ty == LLT::scalar(32) || 352 Ty == LLT::pointer(0, 32)175 ) { |
373 | 228 | if (X86::GPRRegBankID == RB.getID()) |
374 | 209 | return Isload ? 209 X86::MOV32rm134 : X86::MOV32mr75 ; |
375 | 19 | if (19 X86::VECRRegBankID == RB.getID()19 ) |
376 | 19 | return Isload ? 19 (HasAVX512 ? 14 X86::VMOVSSZrm2 |
377 | 14 | : HasAVX ? 12 X86::VMOVSSrm1 : X86::MOVSSrm11 ) |
378 | 5 | : (HasAVX512 ? 5 X86::VMOVSSZmr2 |
379 | 19 | : HasAVX ? 3 X86::VMOVSSmr1 : X86::MOVSSmr2 ); |
380 | 124 | } else if (124 Ty == LLT::scalar(64) || 124 Ty == LLT::pointer(0, 64)85 ) { |
381 | 66 | if (X86::GPRRegBankID == RB.getID()) |
382 | 52 | return Isload ? 52 X86::MOV64rm29 : X86::MOV64mr23 ; |
383 | 14 | if (14 X86::VECRRegBankID == RB.getID()14 ) |
384 | 14 | return Isload ? 14 (HasAVX512 ? 9 X86::VMOVSDZrm2 |
385 | 9 | : HasAVX ? 7 X86::VMOVSDrm1 : X86::MOVSDrm6 ) |
386 | 5 | : (HasAVX512 ? 5 X86::VMOVSDZmr2 |
387 | 14 | : HasAVX ? 3 X86::VMOVSDmr1 : X86::MOVSDmr2 ); |
388 | 58 | } else if (58 Ty.isVector() && 58 Ty.getSizeInBits() == 12858 ) { |
389 | 26 | if (Alignment >= 16) |
390 | 12 | return Isload ? 12 (HasVLX ? 6 X86::VMOVAPSZ128rm3 |
391 | 3 | : HasAVX512 |
392 | 1 | ? X86::VMOVAPSZ128rm_NOVLX |
393 | 6 | : HasAVX ? 2 X86::VMOVAPSrm1 : X86::MOVAPSrm1 ) |
394 | 6 | : (HasVLX ? 6 X86::VMOVAPSZ128mr3 |
395 | 3 | : HasAVX512 |
396 | 1 | ? X86::VMOVAPSZ128mr_NOVLX |
397 | 12 | : HasAVX ? 2 X86::VMOVAPSmr1 : X86::MOVAPSmr1 ); |
398 | 26 | else |
399 | 14 | return Isload ? 14 (HasVLX ? 8 X86::VMOVUPSZ128rm3 |
400 | 5 | : HasAVX512 |
401 | 1 | ? X86::VMOVUPSZ128rm_NOVLX |
402 | 8 | : HasAVX ? 4 X86::VMOVUPSrm1 : X86::MOVUPSrm3 ) |
403 | 6 | : (HasVLX ? 6 X86::VMOVUPSZ128mr3 |
404 | 3 | : HasAVX512 |
405 | 1 | ? X86::VMOVUPSZ128mr_NOVLX |
406 | 14 | : HasAVX ? 2 X86::VMOVUPSmr1 : X86::MOVUPSmr1 ); |
407 | 32 | } else if (32 Ty.isVector() && 32 Ty.getSizeInBits() == 25632 ) { |
408 | 20 | if (Alignment >= 32) |
409 | 10 | return Isload ? 10 (HasVLX ? 5 X86::VMOVAPSZ256rm3 |
410 | 2 | : HasAVX512 ? 2 X86::VMOVAPSZ256rm_NOVLX1 |
411 | 5 | : X86::VMOVAPSYrm) |
412 | 5 | : (HasVLX ? 5 X86::VMOVAPSZ256mr3 |
413 | 2 | : HasAVX512 ? 2 X86::VMOVAPSZ256mr_NOVLX1 |
414 | 10 | : X86::VMOVAPSYmr); |
415 | 20 | else |
416 | 10 | return Isload ? 10 (HasVLX ? 5 X86::VMOVUPSZ256rm3 |
417 | 2 | : HasAVX512 ? 2 X86::VMOVUPSZ256rm_NOVLX1 |
418 | 5 | : X86::VMOVUPSYrm) |
419 | 5 | : (HasVLX ? 5 X86::VMOVUPSZ256mr3 |
420 | 2 | : HasAVX512 ? 2 X86::VMOVUPSZ256mr_NOVLX1 |
421 | 10 | : X86::VMOVUPSYmr); |
422 | 12 | } else if (12 Ty.isVector() && 12 Ty.getSizeInBits() == 51212 ) { |
423 | 12 | if (Alignment >= 64) |
424 | 2 | return Isload ? 2 X86::VMOVAPSZrm0 : X86::VMOVAPSZmr2 ; |
425 | 12 | else |
426 | 10 | return Isload ? 10 X86::VMOVUPSZrm6 : X86::VMOVUPSZmr4 ; |
427 | 0 | } |
428 | 0 | return Opc; |
429 | 0 | } |
430 | | |
431 | | // Fill in an address from the given instruction. |
432 | | static void X86SelectAddress(const MachineInstr &I, |
433 | | const MachineRegisterInfo &MRI, |
434 | 399 | X86AddressMode &AM) { |
435 | 399 | |
436 | 399 | assert(I.getOperand(0).isReg() && "unsupported opperand."); |
437 | 399 | assert(MRI.getType(I.getOperand(0).getReg()).isPointer() && |
438 | 399 | "unsupported type."); |
439 | 399 | |
440 | 399 | if (I.getOpcode() == TargetOpcode::G_GEP399 ) { |
441 | 46 | if (auto COff46 = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) { |
442 | 46 | int64_t Imm = *COff; |
443 | 46 | if (isInt<32>(Imm)46 ) { // Check for displacement overflow. |
444 | 34 | AM.Disp = static_cast<int32_t>(Imm); |
445 | 34 | AM.Base.Reg = I.getOperand(1).getReg(); |
446 | 34 | return; |
447 | 34 | } |
448 | 399 | } |
449 | 353 | } else if (353 I.getOpcode() == TargetOpcode::G_FRAME_INDEX353 ) { |
450 | 132 | AM.Base.FrameIndex = I.getOperand(1).getIndex(); |
451 | 132 | AM.BaseType = X86AddressMode::FrameIndexBase; |
452 | 132 | return; |
453 | 132 | } |
454 | 233 | |
455 | 233 | // Default behavior. |
456 | 233 | AM.Base.Reg = I.getOperand(0).getReg(); |
457 | 233 | return; |
458 | 233 | } |
459 | | |
460 | | bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I, |
461 | | MachineRegisterInfo &MRI, |
462 | 399 | MachineFunction &MF) const { |
463 | 399 | |
464 | 399 | unsigned Opc = I.getOpcode(); |
465 | 399 | |
466 | 399 | assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) && |
467 | 399 | "unexpected instruction"); |
468 | 399 | |
469 | 399 | const unsigned DefReg = I.getOperand(0).getReg(); |
470 | 399 | LLT Ty = MRI.getType(DefReg); |
471 | 399 | const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); |
472 | 399 | |
473 | 399 | auto &MemOp = **I.memoperands_begin(); |
474 | 399 | if (MemOp.getOrdering() != AtomicOrdering::NotAtomic399 ) { |
475 | 0 | DEBUG(dbgs() << "Atomic load/store not supported yet\n"); |
476 | 0 | return false; |
477 | 0 | } |
478 | 399 | |
479 | 399 | unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment()); |
480 | 399 | if (NewOpc == Opc) |
481 | 0 | return false; |
482 | 399 | |
483 | 399 | X86AddressMode AM; |
484 | 399 | X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM); |
485 | 399 | |
486 | 399 | I.setDesc(TII.get(NewOpc)); |
487 | 399 | MachineInstrBuilder MIB(MF, I); |
488 | 399 | if (Opc == TargetOpcode::G_LOAD399 ) { |
489 | 252 | I.RemoveOperand(1); |
490 | 252 | addFullAddress(MIB, AM); |
491 | 399 | } else { |
492 | 147 | // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL) |
493 | 147 | I.RemoveOperand(1); |
494 | 147 | I.RemoveOperand(0); |
495 | 147 | addFullAddress(MIB, AM).addUse(DefReg); |
496 | 147 | } |
497 | 399 | return constrainSelectedInstRegOperands(I, TII, TRI, RBI); |
498 | 399 | } |
499 | | |
500 | 56 | static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) { |
501 | 56 | if (Ty == LLT::pointer(0, 64)) |
502 | 43 | return X86::LEA64r; |
503 | 13 | else if (13 Ty == LLT::pointer(0, 32)13 ) |
504 | 13 | return STI.isTarget64BitILP32() ? 13 X86::LEA64_32r6 : X86::LEA32r7 ; |
505 | 13 | else |
506 | 13 | llvm_unreachable("Can't get LEA opcode. Unsupported type."); |
507 | 56 | } |
508 | | |
509 | | bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I, |
510 | | MachineRegisterInfo &MRI, |
511 | 31 | MachineFunction &MF) const { |
512 | 31 | unsigned Opc = I.getOpcode(); |
513 | 31 | |
514 | 31 | assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) && |
515 | 31 | "unexpected instruction"); |
516 | 31 | |
517 | 31 | const unsigned DefReg = I.getOperand(0).getReg(); |
518 | 31 | LLT Ty = MRI.getType(DefReg); |
519 | 31 | |
520 | 31 | // Use LEA to calculate frame index and GEP |
521 | 31 | unsigned NewOpc = getLeaOP(Ty, STI); |
522 | 31 | I.setDesc(TII.get(NewOpc)); |
523 | 31 | MachineInstrBuilder MIB(MF, I); |
524 | 31 | |
525 | 31 | if (Opc == TargetOpcode::G_FRAME_INDEX31 ) { |
526 | 6 | addOffset(MIB, 0); |
527 | 31 | } else { |
528 | 25 | MachineOperand &InxOp = I.getOperand(2); |
529 | 25 | I.addOperand(InxOp); // set IndexReg |
530 | 25 | InxOp.ChangeToImmediate(1); // set Scale |
531 | 25 | MIB.addImm(0).addReg(0); |
532 | 25 | } |
533 | 31 | |
534 | 31 | return constrainSelectedInstRegOperands(I, TII, TRI, RBI); |
535 | 31 | } |
536 | | |
537 | | bool X86InstructionSelector::selectGlobalValue(MachineInstr &I, |
538 | | MachineRegisterInfo &MRI, |
539 | 25 | MachineFunction &MF) const { |
540 | 25 | |
541 | 25 | assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) && |
542 | 25 | "unexpected instruction"); |
543 | 25 | |
544 | 25 | auto GV = I.getOperand(1).getGlobal(); |
545 | 25 | if (GV->isThreadLocal()25 ) { |
546 | 0 | return false; // TODO: we don't support TLS yet. |
547 | 0 | } |
548 | 25 | |
549 | 25 | // Can't handle alternate code models yet. |
550 | 25 | if (25 TM.getCodeModel() != CodeModel::Small25 ) |
551 | 0 | return 0; |
552 | 25 | |
553 | 25 | X86AddressMode AM; |
554 | 25 | AM.GV = GV; |
555 | 25 | AM.GVOpFlags = STI.classifyGlobalReference(GV); |
556 | 25 | |
557 | 25 | // TODO: The ABI requires an extra load. not supported yet. |
558 | 25 | if (isGlobalStubReference(AM.GVOpFlags)) |
559 | 0 | return false; |
560 | 25 | |
561 | 25 | // TODO: This reference is relative to the pic base. not supported yet. |
562 | 25 | if (25 isGlobalRelativeToPICBase(AM.GVOpFlags)25 ) |
563 | 0 | return false; |
564 | 25 | |
565 | 25 | if (25 STI.isPICStyleRIPRel()25 ) { |
566 | 13 | // Use rip-relative addressing. |
567 | 13 | assert(AM.Base.Reg == 0 && AM.IndexReg == 0); |
568 | 13 | AM.Base.Reg = X86::RIP; |
569 | 13 | } |
570 | 25 | |
571 | 25 | const unsigned DefReg = I.getOperand(0).getReg(); |
572 | 25 | LLT Ty = MRI.getType(DefReg); |
573 | 25 | unsigned NewOpc = getLeaOP(Ty, STI); |
574 | 25 | |
575 | 25 | I.setDesc(TII.get(NewOpc)); |
576 | 25 | MachineInstrBuilder MIB(MF, I); |
577 | 25 | |
578 | 25 | I.RemoveOperand(1); |
579 | 25 | addFullAddress(MIB, AM); |
580 | 25 | |
581 | 25 | return constrainSelectedInstRegOperands(I, TII, TRI, RBI); |
582 | 25 | } |
583 | | |
584 | | bool X86InstructionSelector::selectConstant(MachineInstr &I, |
585 | | MachineRegisterInfo &MRI, |
586 | 26 | MachineFunction &MF) const { |
587 | 26 | |
588 | 26 | assert((I.getOpcode() == TargetOpcode::G_CONSTANT) && |
589 | 26 | "unexpected instruction"); |
590 | 26 | |
591 | 26 | const unsigned DefReg = I.getOperand(0).getReg(); |
592 | 26 | LLT Ty = MRI.getType(DefReg); |
593 | 26 | |
594 | 26 | if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID) |
595 | 0 | return false; |
596 | 26 | |
597 | 26 | uint64_t Val = 0; |
598 | 26 | if (I.getOperand(1).isCImm()26 ) { |
599 | 26 | Val = I.getOperand(1).getCImm()->getZExtValue(); |
600 | 26 | I.getOperand(1).ChangeToImmediate(Val); |
601 | 26 | } else if (0 I.getOperand(1).isImm()0 ) { |
602 | 0 | Val = I.getOperand(1).getImm(); |
603 | 0 | } else |
604 | 0 | llvm_unreachable("Unsupported operand type."); |
605 | 26 | |
606 | 26 | unsigned NewOpc; |
607 | 26 | switch (Ty.getSizeInBits()) { |
608 | 0 | case 8: |
609 | 0 | NewOpc = X86::MOV8ri; |
610 | 0 | break; |
611 | 0 | case 16: |
612 | 0 | NewOpc = X86::MOV16ri; |
613 | 0 | break; |
614 | 15 | case 32: |
615 | 15 | NewOpc = X86::MOV32ri; |
616 | 15 | break; |
617 | 11 | case 64: { |
618 | 11 | // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used |
619 | 11 | if (isInt<32>(Val)) |
620 | 2 | NewOpc = X86::MOV64ri32; |
621 | 11 | else |
622 | 9 | NewOpc = X86::MOV64ri; |
623 | 11 | break; |
624 | 26 | } |
625 | 0 | default: |
626 | 0 | llvm_unreachable("Can't select G_CONSTANT, unsupported type."); |
627 | 26 | } |
628 | 26 | |
629 | 26 | I.setDesc(TII.get(NewOpc)); |
630 | 26 | return constrainSelectedInstRegOperands(I, TII, TRI, RBI); |
631 | 26 | } |
632 | | |
633 | | bool X86InstructionSelector::selectTrunc(MachineInstr &I, |
634 | | MachineRegisterInfo &MRI, |
635 | 42 | MachineFunction &MF) const { |
636 | 42 | |
637 | 42 | assert((I.getOpcode() == TargetOpcode::G_TRUNC) && "unexpected instruction"); |
638 | 42 | |
639 | 42 | const unsigned DstReg = I.getOperand(0).getReg(); |
640 | 42 | const unsigned SrcReg = I.getOperand(1).getReg(); |
641 | 42 | |
642 | 42 | const LLT DstTy = MRI.getType(DstReg); |
643 | 42 | const LLT SrcTy = MRI.getType(SrcReg); |
644 | 42 | |
645 | 42 | const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); |
646 | 42 | const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); |
647 | 42 | |
648 | 42 | if (DstRB.getID() != SrcRB.getID()42 ) { |
649 | 0 | DEBUG(dbgs() << "G_TRUNC input/output on different banks\n"); |
650 | 0 | return false; |
651 | 0 | } |
652 | 42 | |
653 | 42 | if (42 DstRB.getID() != X86::GPRRegBankID42 ) |
654 | 0 | return false; |
655 | 42 | |
656 | 42 | const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB); |
657 | 42 | if (!DstRC) |
658 | 0 | return false; |
659 | 42 | |
660 | 42 | const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB); |
661 | 42 | if (!SrcRC) |
662 | 0 | return false; |
663 | 42 | |
664 | 42 | unsigned SubIdx; |
665 | 42 | if (DstRC == SrcRC42 ) { |
666 | 12 | // Nothing to be done |
667 | 12 | SubIdx = X86::NoSubRegister; |
668 | 42 | } else if (30 DstRC == &X86::GR32RegClass30 ) { |
669 | 3 | SubIdx = X86::sub_32bit; |
670 | 30 | } else if (27 DstRC == &X86::GR16RegClass27 ) { |
671 | 3 | SubIdx = X86::sub_16bit; |
672 | 27 | } else if (24 DstRC == &X86::GR8RegClass24 ) { |
673 | 24 | SubIdx = X86::sub_8bit; |
674 | 24 | } else { |
675 | 0 | return false; |
676 | 0 | } |
677 | 42 | |
678 | 42 | SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx); |
679 | 42 | |
680 | 42 | if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || |
681 | 42 | !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)42 ) { |
682 | 0 | DEBUG(dbgs() << "Failed to constrain G_TRUNC\n"); |
683 | 0 | return false; |
684 | 0 | } |
685 | 42 | |
686 | 42 | I.getOperand(1).setSubReg(SubIdx); |
687 | 42 | |
688 | 42 | I.setDesc(TII.get(X86::COPY)); |
689 | 42 | return true; |
690 | 42 | } |
691 | | |
692 | | bool X86InstructionSelector::selectZext(MachineInstr &I, |
693 | | MachineRegisterInfo &MRI, |
694 | 50 | MachineFunction &MF) const { |
695 | 50 | |
696 | 50 | assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction"); |
697 | 50 | |
698 | 50 | const unsigned DstReg = I.getOperand(0).getReg(); |
699 | 50 | const unsigned SrcReg = I.getOperand(1).getReg(); |
700 | 50 | |
701 | 50 | const LLT DstTy = MRI.getType(DstReg); |
702 | 50 | const LLT SrcTy = MRI.getType(SrcReg); |
703 | 50 | |
704 | 50 | if (SrcTy != LLT::scalar(1)) |
705 | 0 | return false; |
706 | 50 | |
707 | 50 | unsigned AndOpc; |
708 | 50 | if (DstTy == LLT::scalar(8)) |
709 | 6 | AndOpc = X86::AND8ri; |
710 | 44 | else if (44 DstTy == LLT::scalar(16)44 ) |
711 | 4 | AndOpc = X86::AND16ri8; |
712 | 40 | else if (40 DstTy == LLT::scalar(32)40 ) |
713 | 38 | AndOpc = X86::AND32ri8; |
714 | 2 | else if (2 DstTy == LLT::scalar(64)2 ) |
715 | 2 | AndOpc = X86::AND64ri8; |
716 | 2 | else |
717 | 0 | return false; |
718 | 50 | |
719 | 50 | unsigned DefReg = SrcReg; |
720 | 50 | if (DstTy != LLT::scalar(8)50 ) { |
721 | 44 | DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI)); |
722 | 44 | BuildMI(*I.getParent(), I, I.getDebugLoc(), |
723 | 44 | TII.get(TargetOpcode::SUBREG_TO_REG), DefReg) |
724 | 44 | .addImm(0) |
725 | 44 | .addReg(SrcReg) |
726 | 44 | .addImm(X86::sub_8bit); |
727 | 44 | } |
728 | 50 | |
729 | 50 | MachineInstr &AndInst = |
730 | 50 | *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg) |
731 | 50 | .addReg(DefReg) |
732 | 50 | .addImm(1); |
733 | 50 | |
734 | 50 | constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI); |
735 | 50 | |
736 | 50 | I.eraseFromParent(); |
737 | 50 | return true; |
738 | 50 | } |
739 | | |
740 | | bool X86InstructionSelector::selectAnyext(MachineInstr &I, |
741 | | MachineRegisterInfo &MRI, |
742 | 24 | MachineFunction &MF) const { |
743 | 24 | |
744 | 24 | assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction"); |
745 | 24 | |
746 | 24 | const unsigned DstReg = I.getOperand(0).getReg(); |
747 | 24 | const unsigned SrcReg = I.getOperand(1).getReg(); |
748 | 24 | |
749 | 24 | const LLT DstTy = MRI.getType(DstReg); |
750 | 24 | const LLT SrcTy = MRI.getType(SrcReg); |
751 | 24 | |
752 | 24 | const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); |
753 | 24 | const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); |
754 | 24 | |
755 | 24 | assert(DstRB.getID() == SrcRB.getID() && |
756 | 24 | "G_ANYEXT input/output on different banks\n"); |
757 | 24 | |
758 | 24 | assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() && |
759 | 24 | "G_ANYEXT incorrect operand size"); |
760 | 24 | |
761 | 24 | if (DstRB.getID() != X86::GPRRegBankID) |
762 | 0 | return false; |
763 | 24 | |
764 | 24 | const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB); |
765 | 24 | const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB); |
766 | 24 | |
767 | 24 | if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || |
768 | 24 | !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)24 ) { |
769 | 0 | DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) |
770 | 0 | << " operand\n"); |
771 | 0 | return false; |
772 | 0 | } |
773 | 24 | |
774 | 24 | if (24 SrcRC == DstRC24 ) { |
775 | 12 | I.setDesc(TII.get(X86::COPY)); |
776 | 12 | return true; |
777 | 12 | } |
778 | 12 | |
779 | 12 | BuildMI(*I.getParent(), I, I.getDebugLoc(), |
780 | 12 | TII.get(TargetOpcode::SUBREG_TO_REG)) |
781 | 12 | .addDef(DstReg) |
782 | 12 | .addImm(0) |
783 | 12 | .addReg(SrcReg) |
784 | 12 | .addImm(getSubRegIndex(SrcRC)); |
785 | 12 | |
786 | 12 | I.eraseFromParent(); |
787 | 12 | return true; |
788 | 12 | } |
789 | | |
790 | | bool X86InstructionSelector::selectCmp(MachineInstr &I, |
791 | | MachineRegisterInfo &MRI, |
792 | 45 | MachineFunction &MF) const { |
793 | 45 | |
794 | 45 | assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction"); |
795 | 45 | |
796 | 45 | X86::CondCode CC; |
797 | 45 | bool SwapArgs; |
798 | 45 | std::tie(CC, SwapArgs) = X86::getX86ConditionCode( |
799 | 45 | (CmpInst::Predicate)I.getOperand(1).getPredicate()); |
800 | 45 | unsigned OpSet = X86::getSETFromCond(CC); |
801 | 45 | |
802 | 45 | unsigned LHS = I.getOperand(2).getReg(); |
803 | 45 | unsigned RHS = I.getOperand(3).getReg(); |
804 | 45 | |
805 | 45 | if (SwapArgs) |
806 | 0 | std::swap(LHS, RHS); |
807 | 45 | |
808 | 45 | unsigned OpCmp; |
809 | 45 | LLT Ty = MRI.getType(LHS); |
810 | 45 | |
811 | 45 | switch (Ty.getSizeInBits()) { |
812 | 0 | default: |
813 | 0 | return false; |
814 | 2 | case 8: |
815 | 2 | OpCmp = X86::CMP8rr; |
816 | 2 | break; |
817 | 2 | case 16: |
818 | 2 | OpCmp = X86::CMP16rr; |
819 | 2 | break; |
820 | 39 | case 32: |
821 | 39 | OpCmp = X86::CMP32rr; |
822 | 39 | break; |
823 | 2 | case 64: |
824 | 2 | OpCmp = X86::CMP64rr; |
825 | 2 | break; |
826 | 45 | } |
827 | 45 | |
828 | 45 | MachineInstr &CmpInst = |
829 | 45 | *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp)) |
830 | 45 | .addReg(LHS) |
831 | 45 | .addReg(RHS); |
832 | 45 | |
833 | 45 | MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), |
834 | 45 | TII.get(OpSet), I.getOperand(0).getReg()); |
835 | 45 | |
836 | 45 | constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI); |
837 | 45 | constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI); |
838 | 45 | |
839 | 45 | I.eraseFromParent(); |
840 | 45 | return true; |
841 | 45 | } |
842 | | |
843 | | bool X86InstructionSelector::selectUadde(MachineInstr &I, |
844 | | MachineRegisterInfo &MRI, |
845 | 4 | MachineFunction &MF) const { |
846 | 4 | |
847 | 4 | assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction"); |
848 | 4 | |
849 | 4 | const unsigned DstReg = I.getOperand(0).getReg(); |
850 | 4 | const unsigned CarryOutReg = I.getOperand(1).getReg(); |
851 | 4 | const unsigned Op0Reg = I.getOperand(2).getReg(); |
852 | 4 | const unsigned Op1Reg = I.getOperand(3).getReg(); |
853 | 4 | unsigned CarryInReg = I.getOperand(4).getReg(); |
854 | 4 | |
855 | 4 | const LLT DstTy = MRI.getType(DstReg); |
856 | 4 | |
857 | 4 | if (DstTy != LLT::scalar(32)) |
858 | 0 | return false; |
859 | 4 | |
860 | 4 | // find CarryIn def instruction. |
861 | 4 | MachineInstr *Def = MRI.getVRegDef(CarryInReg); |
862 | 6 | while (Def->getOpcode() == TargetOpcode::G_TRUNC6 ) { |
863 | 2 | CarryInReg = Def->getOperand(1).getReg(); |
864 | 2 | Def = MRI.getVRegDef(CarryInReg); |
865 | 2 | } |
866 | 4 | |
867 | 4 | unsigned Opcode; |
868 | 4 | if (Def->getOpcode() == TargetOpcode::G_UADDE4 ) { |
869 | 2 | // carry set by prev ADD. |
870 | 2 | |
871 | 2 | BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS) |
872 | 2 | .addReg(CarryInReg); |
873 | 2 | |
874 | 2 | if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI)) |
875 | 0 | return false; |
876 | 2 | |
877 | 2 | Opcode = X86::ADC32rr; |
878 | 4 | } else if (auto 2 val2 = getConstantVRegVal(CarryInReg, MRI)) { |
879 | 2 | // carry is constant, support only 0. |
880 | 2 | if (*val != 0) |
881 | 0 | return false; |
882 | 2 | |
883 | 2 | Opcode = X86::ADD32rr; |
884 | 2 | } else |
885 | 0 | return false; |
886 | 4 | |
887 | 4 | MachineInstr &AddInst = |
888 | 4 | *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg) |
889 | 4 | .addReg(Op0Reg) |
890 | 4 | .addReg(Op1Reg); |
891 | 4 | |
892 | 4 | BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg) |
893 | 4 | .addReg(X86::EFLAGS); |
894 | 4 | |
895 | 4 | if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) || |
896 | 4 | !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI)) |
897 | 0 | return false; |
898 | 4 | |
899 | 4 | I.eraseFromParent(); |
900 | 4 | return true; |
901 | 4 | } |
902 | | |
903 | | bool X86InstructionSelector::selectExtract(MachineInstr &I, |
904 | | MachineRegisterInfo &MRI, |
905 | 70 | MachineFunction &MF) const { |
906 | 70 | |
907 | 70 | assert((I.getOpcode() == TargetOpcode::G_EXTRACT) && |
908 | 70 | "unexpected instruction"); |
909 | 70 | |
910 | 70 | const unsigned DstReg = I.getOperand(0).getReg(); |
911 | 70 | const unsigned SrcReg = I.getOperand(1).getReg(); |
912 | 70 | int64_t Index = I.getOperand(2).getImm(); |
913 | 70 | |
914 | 70 | const LLT DstTy = MRI.getType(DstReg); |
915 | 70 | const LLT SrcTy = MRI.getType(SrcReg); |
916 | 70 | |
917 | 70 | // Meanwile handle vector type only. |
918 | 70 | if (!DstTy.isVector()) |
919 | 0 | return false; |
920 | 70 | |
921 | 70 | if (70 Index % DstTy.getSizeInBits() != 070 ) |
922 | 0 | return false; // Not extract subvector. |
923 | 70 | |
924 | 70 | if (70 Index == 070 ) { |
925 | 34 | // Replace by extract subreg copy. |
926 | 34 | if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF)) |
927 | 0 | return false; |
928 | 34 | |
929 | 34 | I.eraseFromParent(); |
930 | 34 | return true; |
931 | 34 | } |
932 | 36 | |
933 | 36 | bool HasAVX = STI.hasAVX(); |
934 | 36 | bool HasAVX512 = STI.hasAVX512(); |
935 | 36 | bool HasVLX = STI.hasVLX(); |
936 | 36 | |
937 | 36 | if (SrcTy.getSizeInBits() == 256 && 36 DstTy.getSizeInBits() == 12828 ) { |
938 | 28 | if (HasVLX) |
939 | 2 | I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr)); |
940 | 26 | else if (26 HasAVX26 ) |
941 | 26 | I.setDesc(TII.get(X86::VEXTRACTF128rr)); |
942 | 26 | else |
943 | 0 | return false; |
944 | 8 | } else if (8 SrcTy.getSizeInBits() == 512 && 8 HasAVX5128 ) { |
945 | 8 | if (DstTy.getSizeInBits() == 128) |
946 | 5 | I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr)); |
947 | 3 | else if (3 DstTy.getSizeInBits() == 2563 ) |
948 | 3 | I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr)); |
949 | 3 | else |
950 | 0 | return false; |
951 | 8 | } else |
952 | 0 | return false; |
953 | 36 | |
954 | 36 | // Convert to X86 VEXTRACT immediate. |
955 | 36 | Index = Index / DstTy.getSizeInBits(); |
956 | 36 | I.getOperand(2).setImm(Index); |
957 | 36 | |
958 | 36 | return constrainSelectedInstRegOperands(I, TII, TRI, RBI); |
959 | 36 | } |
960 | | |
961 | | bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg, |
962 | | MachineInstr &I, |
963 | | MachineRegisterInfo &MRI, |
964 | 34 | MachineFunction &MF) const { |
965 | 34 | |
966 | 34 | const LLT DstTy = MRI.getType(DstReg); |
967 | 34 | const LLT SrcTy = MRI.getType(SrcReg); |
968 | 34 | unsigned SubIdx = X86::NoSubRegister; |
969 | 34 | |
970 | 34 | if (!DstTy.isVector() || 34 !SrcTy.isVector()34 ) |
971 | 0 | return false; |
972 | 34 | |
973 | 34 | assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() && |
974 | 34 | "Incorrect Src/Dst register size"); |
975 | 34 | |
976 | 34 | if (DstTy.getSizeInBits() == 128) |
977 | 31 | SubIdx = X86::sub_xmm; |
978 | 3 | else if (3 DstTy.getSizeInBits() == 2563 ) |
979 | 3 | SubIdx = X86::sub_ymm; |
980 | 3 | else |
981 | 0 | return false; |
982 | 34 | |
983 | 34 | const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI); |
984 | 34 | const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI); |
985 | 34 | |
986 | 34 | SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx); |
987 | 34 | |
988 | 34 | if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || |
989 | 34 | !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)34 ) { |
990 | 0 | DEBUG(dbgs() << "Failed to constrain G_TRUNC\n"); |
991 | 0 | return false; |
992 | 0 | } |
993 | 34 | |
994 | 34 | BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg) |
995 | 34 | .addReg(SrcReg, 0, SubIdx); |
996 | 34 | |
997 | 34 | return true; |
998 | 34 | } |
999 | | |
1000 | | bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg, |
1001 | | MachineInstr &I, |
1002 | | MachineRegisterInfo &MRI, |
1003 | 20 | MachineFunction &MF) const { |
1004 | 20 | |
1005 | 20 | const LLT DstTy = MRI.getType(DstReg); |
1006 | 20 | const LLT SrcTy = MRI.getType(SrcReg); |
1007 | 20 | unsigned SubIdx = X86::NoSubRegister; |
1008 | 20 | |
1009 | 20 | // TODO: support scalar types |
1010 | 20 | if (!DstTy.isVector() || 20 !SrcTy.isVector()20 ) |
1011 | 0 | return false; |
1012 | 20 | |
1013 | 20 | assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() && |
1014 | 20 | "Incorrect Src/Dst register size"); |
1015 | 20 | |
1016 | 20 | if (SrcTy.getSizeInBits() == 128) |
1017 | 18 | SubIdx = X86::sub_xmm; |
1018 | 2 | else if (2 SrcTy.getSizeInBits() == 2562 ) |
1019 | 2 | SubIdx = X86::sub_ymm; |
1020 | 2 | else |
1021 | 0 | return false; |
1022 | 20 | |
1023 | 20 | const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI); |
1024 | 20 | const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI); |
1025 | 20 | |
1026 | 20 | if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || |
1027 | 20 | !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)20 ) { |
1028 | 0 | DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n"); |
1029 | 0 | return false; |
1030 | 0 | } |
1031 | 20 | |
1032 | 20 | BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY)) |
1033 | 20 | .addReg(DstReg, RegState::DefineNoRead, SubIdx) |
1034 | 20 | .addReg(SrcReg); |
1035 | 20 | |
1036 | 20 | return true; |
1037 | 20 | } |
1038 | | |
1039 | | bool X86InstructionSelector::selectInsert(MachineInstr &I, |
1040 | | MachineRegisterInfo &MRI, |
1041 | 34 | MachineFunction &MF) const { |
1042 | 34 | |
1043 | 34 | assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction"); |
1044 | 34 | |
1045 | 34 | const unsigned DstReg = I.getOperand(0).getReg(); |
1046 | 34 | const unsigned SrcReg = I.getOperand(1).getReg(); |
1047 | 34 | const unsigned InsertReg = I.getOperand(2).getReg(); |
1048 | 34 | int64_t Index = I.getOperand(3).getImm(); |
1049 | 34 | |
1050 | 34 | const LLT DstTy = MRI.getType(DstReg); |
1051 | 34 | const LLT InsertRegTy = MRI.getType(InsertReg); |
1052 | 34 | |
1053 | 34 | // Meanwile handle vector type only. |
1054 | 34 | if (!DstTy.isVector()) |
1055 | 0 | return false; |
1056 | 34 | |
1057 | 34 | if (34 Index % InsertRegTy.getSizeInBits() != 034 ) |
1058 | 0 | return false; // Not insert subvector. |
1059 | 34 | |
1060 | 34 | if (34 Index == 0 && 34 MRI.getVRegDef(SrcReg)->isImplicitDef()8 ) { |
1061 | 4 | // Replace by subreg copy. |
1062 | 4 | if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF)) |
1063 | 0 | return false; |
1064 | 4 | |
1065 | 4 | I.eraseFromParent(); |
1066 | 4 | return true; |
1067 | 4 | } |
1068 | 30 | |
1069 | 30 | bool HasAVX = STI.hasAVX(); |
1070 | 30 | bool HasAVX512 = STI.hasAVX512(); |
1071 | 30 | bool HasVLX = STI.hasVLX(); |
1072 | 30 | |
1073 | 30 | if (DstTy.getSizeInBits() == 256 && 30 InsertRegTy.getSizeInBits() == 12820 ) { |
1074 | 20 | if (HasVLX) |
1075 | 4 | I.setDesc(TII.get(X86::VINSERTF32x4Z256rr)); |
1076 | 16 | else if (16 HasAVX16 ) |
1077 | 16 | I.setDesc(TII.get(X86::VINSERTF128rr)); |
1078 | 16 | else |
1079 | 0 | return false; |
1080 | 10 | } else if (10 DstTy.getSizeInBits() == 512 && 10 HasAVX51210 ) { |
1081 | 10 | if (InsertRegTy.getSizeInBits() == 128) |
1082 | 6 | I.setDesc(TII.get(X86::VINSERTF32x4Zrr)); |
1083 | 4 | else if (4 InsertRegTy.getSizeInBits() == 2564 ) |
1084 | 4 | I.setDesc(TII.get(X86::VINSERTF64x4Zrr)); |
1085 | 4 | else |
1086 | 0 | return false; |
1087 | 10 | } else |
1088 | 0 | return false; |
1089 | 30 | |
1090 | 30 | // Convert to X86 VINSERT immediate. |
1091 | 30 | Index = Index / InsertRegTy.getSizeInBits(); |
1092 | 30 | |
1093 | 30 | I.getOperand(3).setImm(Index); |
1094 | 30 | |
1095 | 30 | return constrainSelectedInstRegOperands(I, TII, TRI, RBI); |
1096 | 30 | } |
1097 | | |
1098 | | bool X86InstructionSelector::selectUnmergeValues(MachineInstr &I, |
1099 | | MachineRegisterInfo &MRI, |
1100 | 28 | MachineFunction &MF) const { |
1101 | 28 | |
1102 | 28 | assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) && |
1103 | 28 | "unexpected instruction"); |
1104 | 28 | |
1105 | 28 | // Split to extracts. |
1106 | 28 | unsigned NumDefs = I.getNumOperands() - 1; |
1107 | 28 | unsigned SrcReg = I.getOperand(NumDefs).getReg(); |
1108 | 28 | unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits(); |
1109 | 28 | |
1110 | 86 | for (unsigned Idx = 0; Idx < NumDefs86 ; ++Idx58 ) { |
1111 | 58 | |
1112 | 58 | MachineInstr &ExtrInst = |
1113 | 58 | *BuildMI(*I.getParent(), I, I.getDebugLoc(), |
1114 | 58 | TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg()) |
1115 | 58 | .addReg(SrcReg) |
1116 | 58 | .addImm(Idx * DefSize); |
1117 | 58 | |
1118 | 58 | if (!select(ExtrInst)) |
1119 | 0 | return false; |
1120 | 58 | } |
1121 | 28 | |
1122 | 28 | I.eraseFromParent(); |
1123 | 28 | return true; |
1124 | 28 | } |
1125 | | |
1126 | | bool X86InstructionSelector::selectMergeValues(MachineInstr &I, |
1127 | | MachineRegisterInfo &MRI, |
1128 | 16 | MachineFunction &MF) const { |
1129 | 16 | |
1130 | 16 | assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES) && |
1131 | 16 | "unexpected instruction"); |
1132 | 16 | |
1133 | 16 | // Split to inserts. |
1134 | 16 | unsigned DstReg = I.getOperand(0).getReg(); |
1135 | 16 | unsigned SrcReg0 = I.getOperand(1).getReg(); |
1136 | 16 | |
1137 | 16 | const LLT DstTy = MRI.getType(DstReg); |
1138 | 16 | const LLT SrcTy = MRI.getType(SrcReg0); |
1139 | 16 | unsigned SrcSize = SrcTy.getSizeInBits(); |
1140 | 16 | |
1141 | 16 | const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); |
1142 | 16 | |
1143 | 16 | // For the first src use insertSubReg. |
1144 | 16 | unsigned DefReg = MRI.createGenericVirtualRegister(DstTy); |
1145 | 16 | MRI.setRegBank(DefReg, RegBank); |
1146 | 16 | if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF)) |
1147 | 0 | return false; |
1148 | 16 | |
1149 | 34 | for (unsigned Idx = 2; 16 Idx < I.getNumOperands()34 ; ++Idx18 ) { |
1150 | 18 | |
1151 | 18 | unsigned Tmp = MRI.createGenericVirtualRegister(DstTy); |
1152 | 18 | MRI.setRegBank(Tmp, RegBank); |
1153 | 18 | |
1154 | 18 | MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), |
1155 | 18 | TII.get(TargetOpcode::G_INSERT), Tmp) |
1156 | 18 | .addReg(DefReg) |
1157 | 18 | .addReg(I.getOperand(Idx).getReg()) |
1158 | 18 | .addImm((Idx - 1) * SrcSize); |
1159 | 18 | |
1160 | 18 | DefReg = Tmp; |
1161 | 18 | |
1162 | 18 | if (!select(InsertInst)) |
1163 | 0 | return false; |
1164 | 18 | } |
1165 | 16 | |
1166 | 16 | MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), |
1167 | 16 | TII.get(TargetOpcode::COPY), DstReg) |
1168 | 16 | .addReg(DefReg); |
1169 | 16 | |
1170 | 16 | if (!select(CopyInst)) |
1171 | 0 | return false; |
1172 | 16 | |
1173 | 16 | I.eraseFromParent(); |
1174 | 16 | return true; |
1175 | 16 | } |
1176 | | |
1177 | | bool X86InstructionSelector::selectCondBranch(MachineInstr &I, |
1178 | | MachineRegisterInfo &MRI, |
1179 | 18 | MachineFunction &MF) const { |
1180 | 18 | |
1181 | 18 | assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction"); |
1182 | 18 | |
1183 | 18 | const unsigned CondReg = I.getOperand(0).getReg(); |
1184 | 18 | MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); |
1185 | 18 | |
1186 | 18 | MachineInstr &TestInst = |
1187 | 18 | *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri)) |
1188 | 18 | .addReg(CondReg) |
1189 | 18 | .addImm(1); |
1190 | 18 | BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1)) |
1191 | 18 | .addMBB(DestMBB); |
1192 | 18 | |
1193 | 18 | constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI); |
1194 | 18 | |
1195 | 18 | I.eraseFromParent(); |
1196 | 18 | return true; |
1197 | 18 | } |
1198 | | |
1199 | | bool X86InstructionSelector::materializeFP(MachineInstr &I, |
1200 | | MachineRegisterInfo &MRI, |
1201 | 15 | MachineFunction &MF) const { |
1202 | 15 | |
1203 | 15 | assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) && |
1204 | 15 | "unexpected instruction"); |
1205 | 15 | |
1206 | 15 | // Can't handle alternate code models yet. |
1207 | 15 | CodeModel::Model CM = TM.getCodeModel(); |
1208 | 15 | if (CM != CodeModel::Small && 15 CM != CodeModel::Large6 ) |
1209 | 0 | return false; |
1210 | 15 | |
1211 | 15 | const unsigned DstReg = I.getOperand(0).getReg(); |
1212 | 15 | const LLT DstTy = MRI.getType(DstReg); |
1213 | 15 | const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); |
1214 | 15 | unsigned Align = DstTy.getSizeInBits(); |
1215 | 15 | const DebugLoc &DbgLoc = I.getDebugLoc(); |
1216 | 15 | |
1217 | 15 | unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align); |
1218 | 15 | |
1219 | 15 | // Create the load from the constant pool. |
1220 | 15 | const ConstantFP *CFP = I.getOperand(1).getFPImm(); |
1221 | 15 | unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align); |
1222 | 15 | MachineInstr *LoadInst = nullptr; |
1223 | 15 | unsigned char OpFlag = STI.classifyLocalReference(nullptr); |
1224 | 15 | |
1225 | 15 | if (CM == CodeModel::Large && 15 STI.is64Bit()6 ) { |
1226 | 3 | // Under X86-64 non-small code model, GV (and friends) are 64-bits, so |
1227 | 3 | // they cannot be folded into immediate fields. |
1228 | 3 | |
1229 | 3 | unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass); |
1230 | 3 | BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg) |
1231 | 3 | .addConstantPoolIndex(CPI, 0, OpFlag); |
1232 | 3 | |
1233 | 3 | MachineMemOperand *MMO = MF.getMachineMemOperand( |
1234 | 3 | MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad, |
1235 | 3 | MF.getDataLayout().getPointerSize(), Align); |
1236 | 3 | |
1237 | 3 | LoadInst = |
1238 | 3 | addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), |
1239 | 3 | AddrReg) |
1240 | 3 | .addMemOperand(MMO); |
1241 | 3 | |
1242 | 15 | } else if (12 CM == CodeModel::Small || 12 !STI.is64Bit()3 ) { |
1243 | 12 | // Handle the case when globals fit in our immediate field. |
1244 | 12 | // This is true for X86-32 always and X86-64 when in -mcmodel=small mode. |
1245 | 12 | |
1246 | 12 | // x86-32 PIC requires a PIC base register for constant pools. |
1247 | 12 | unsigned PICBase = 0; |
1248 | 12 | if (OpFlag == X86II::MO_PIC_BASE_OFFSET || 12 OpFlag == X86II::MO_GOTOFF12 ) { |
1249 | 0 | // PICBase can be allocated by TII.getGlobalBaseReg(&MF). |
1250 | 0 | // In DAGISEL the code that initialize it generated by the CGBR pass. |
1251 | 0 | return false; // TODO support the mode. |
1252 | 12 | } else if (12 STI.is64Bit() && 12 TM.getCodeModel() == CodeModel::Small6 ) |
1253 | 6 | PICBase = X86::RIP; |
1254 | 12 | |
1255 | 12 | LoadInst = addConstantPoolReference( |
1256 | 12 | BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase, |
1257 | 12 | OpFlag); |
1258 | 12 | } else |
1259 | 0 | return false; |
1260 | 15 | |
1261 | 15 | constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI); |
1262 | 15 | I.eraseFromParent(); |
1263 | 15 | return true; |
1264 | 15 | } |
1265 | | |
1266 | | bool X86InstructionSelector::selectImplicitDefOrPHI( |
1267 | 18 | MachineInstr &I, MachineRegisterInfo &MRI) const { |
1268 | 18 | |
1269 | 18 | assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF || |
1270 | 18 | I.getOpcode() == TargetOpcode::G_PHI) && |
1271 | 18 | "unexpected instruction"); |
1272 | 18 | |
1273 | 18 | unsigned DstReg = I.getOperand(0).getReg(); |
1274 | 18 | |
1275 | 18 | if (!MRI.getRegClassOrNull(DstReg)18 ) { |
1276 | 16 | const LLT DstTy = MRI.getType(DstReg); |
1277 | 16 | const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI); |
1278 | 16 | |
1279 | 16 | if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)16 ) { |
1280 | 0 | DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) |
1281 | 0 | << " operand\n"); |
1282 | 0 | return false; |
1283 | 0 | } |
1284 | 18 | } |
1285 | 18 | |
1286 | 18 | if (18 I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF18 ) |
1287 | 6 | I.setDesc(TII.get(X86::IMPLICIT_DEF)); |
1288 | 18 | else |
1289 | 12 | I.setDesc(TII.get(X86::PHI)); |
1290 | 18 | |
1291 | 18 | return true; |
1292 | 18 | } |
1293 | | |
1294 | | InstructionSelector * |
1295 | | llvm::createX86InstructionSelector(const X86TargetMachine &TM, |
1296 | | X86Subtarget &Subtarget, |
1297 | 9.64k | X86RegisterBankInfo &RBI) { |
1298 | 9.64k | return new X86InstructionSelector(TM, Subtarget, RBI); |
1299 | 9.64k | } |