LLVM 24.0.0git
MipsInstructionSelector.cpp
Go to the documentation of this file.
1//===- MipsInstructionSelector.cpp ------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for
10/// Mips.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
15#include "MipsMachineFunction.h"
17#include "MipsTargetMachine.h"
21#include "llvm/IR/IntrinsicsMips.h"
22
23#define DEBUG_TYPE "mips-isel"
24
25using namespace llvm;
26
27namespace {
28
29#define GET_GLOBALISEL_PREDICATE_BITSET
30#include "MipsGenGlobalISel.inc"
31#undef GET_GLOBALISEL_PREDICATE_BITSET
32
33class MipsInstructionSelector : public InstructionSelector {
34public:
35 MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI,
36 const MipsRegisterBankInfo &RBI);
37
38 bool select(MachineInstr &I) override;
39 static const char *getName() { return DEBUG_TYPE; }
40
41private:
42 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
43 bool isRegInGprb(Register Reg, MachineRegisterInfo &MRI) const;
44 bool isRegInFprb(Register Reg, MachineRegisterInfo &MRI) const;
45 bool materialize32BitImm(Register DestReg, APInt Imm,
46 MachineIRBuilder &B) const;
49 getRegClassForTypeOnBank(Register Reg, MachineRegisterInfo &MRI) const;
50 unsigned selectLoadStoreOpCode(MachineInstr &I,
51 MachineRegisterInfo &MRI) const;
52 bool buildUnalignedStore(MachineInstr &I, unsigned Opc,
53 MachineOperand &BaseAddr, unsigned Offset,
54 MachineMemOperand *MMO) const;
55 bool buildUnalignedLoad(MachineInstr &I, unsigned Opc, Register Dest,
56 MachineOperand &BaseAddr, unsigned Offset,
57 Register TiedDest, MachineMemOperand *MMO) const;
58
59 const MipsTargetMachine &TM;
60 const MipsSubtarget &STI;
61 const MipsInstrInfo &TII;
62 const MipsRegisterInfo &TRI;
63 const MipsRegisterBankInfo &RBI;
64
65#define GET_GLOBALISEL_PREDICATES_DECL
66#include "MipsGenGlobalISel.inc"
67#undef GET_GLOBALISEL_PREDICATES_DECL
68
69#define GET_GLOBALISEL_TEMPORARIES_DECL
70#include "MipsGenGlobalISel.inc"
71#undef GET_GLOBALISEL_TEMPORARIES_DECL
72};
73
74} // end anonymous namespace
75
76#define GET_GLOBALISEL_IMPL
77#include "MipsGenGlobalISel.inc"
78#undef GET_GLOBALISEL_IMPL
79
80MipsInstructionSelector::MipsInstructionSelector(
81 const MipsTargetMachine &TM, const MipsSubtarget &STI,
82 const MipsRegisterBankInfo &RBI)
83 : TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()),
84 RBI(RBI),
85
87#include "MipsGenGlobalISel.inc"
90#include "MipsGenGlobalISel.inc"
92{
93}
94
95bool MipsInstructionSelector::isRegInGprb(Register Reg,
96 MachineRegisterInfo &MRI) const {
97 return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::GPRBRegBankID;
98}
99
100bool MipsInstructionSelector::isRegInFprb(Register Reg,
101 MachineRegisterInfo &MRI) const {
102 return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::FPRBRegBankID;
103}
104
105bool MipsInstructionSelector::selectCopy(MachineInstr &I,
106 MachineRegisterInfo &MRI) const {
107 Register DstReg = I.getOperand(0).getReg();
108 if (DstReg.isPhysical())
109 return true;
110
111 const TargetRegisterClass *RC = getRegClassForTypeOnBank(DstReg, MRI);
112 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
113 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
114 << " operand\n");
115 return false;
116 }
117 return true;
118}
119
120const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
121 Register Reg, MachineRegisterInfo &MRI) const {
122 const LLT Ty = MRI.getType(Reg);
123 const unsigned TySize = Ty.getSizeInBits();
124
125 if (isRegInGprb(Reg, MRI)) {
126 assert((Ty.isScalar() || Ty.isPointer()) &&
127 (TySize == 32 || TySize == 64) &&
128 "Register class not available for LLT, register bank combination");
129 if (TySize == 32)
130 return &Mips::GPR32RegClass;
131 if (TySize == 64)
132 return &Mips::GPR64RegClass;
133 }
134
135 if (isRegInFprb(Reg, MRI)) {
136 if (Ty.isScalar()) {
137 assert((TySize == 32 || TySize == 64) &&
138 "Register class not available for LLT, register bank combination");
139 if (TySize == 32)
140 return &Mips::FGR32RegClass;
141 return STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
142 }
143 }
144
145 llvm_unreachable("Unsupported register bank.");
146}
147
148bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
149 MachineIRBuilder &B) const {
150 assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
151 // Ori zero extends immediate. Used for values with zeros in high 16 bits.
152 if (Imm.getHiBits(16).isZero()) {
153 MachineInstr *Inst =
154 B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
155 .addImm(Imm.getLoBits(16).getLimitedValue());
157 return true;
158 }
159 // Lui places immediate in high 16 bits and sets low 16 bits to zero.
160 if (Imm.getLoBits(16).isZero()) {
161 MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {})
162 .addImm(Imm.getHiBits(16).getLimitedValue());
164 return true;
165 }
166 // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
167 if (Imm.isSignedIntN(16)) {
168 MachineInstr *Inst =
169 B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
170 .addImm(Imm.getLoBits(16).getLimitedValue());
172 return true;
173 }
174 // Values that cannot be materialized with single immediate instruction.
175 Register LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
176 MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {})
177 .addImm(Imm.getHiBits(16).getLimitedValue());
178 MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
179 .addImm(Imm.getLoBits(16).getLimitedValue());
182 return true;
183}
184
185/// When I.getOpcode() is returned, we failed to select MIPS instruction opcode.
186unsigned
187MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
188 MachineRegisterInfo &MRI) const {
189 const Register ValueReg = I.getOperand(0).getReg();
190 const LLT Ty = MRI.getType(ValueReg);
191 const unsigned TySize = Ty.getSizeInBits();
192 const unsigned MemSizeInBytes =
193 (*I.memoperands_begin())->getSize().getValue();
194 unsigned Opc = I.getOpcode();
195 const bool isStore = Opc == TargetOpcode::G_STORE;
196
197 if (isRegInGprb(ValueReg, MRI)) {
198 assert(((Ty.isScalar() && TySize == 32) ||
199 (Ty.isPointer() && TySize == 32 && MemSizeInBytes == 4)) &&
200 "Unsupported register bank, LLT, MemSizeInBytes combination");
201 (void)TySize;
202 if (isStore)
203 switch (MemSizeInBytes) {
204 case 4:
205 return Mips::SW;
206 case 2:
207 return Mips::SH;
208 case 1:
209 return Mips::SB;
210 default:
211 return Opc;
212 }
213 else
214 // Unspecified extending load is selected into zeroExtending load.
215 switch (MemSizeInBytes) {
216 case 4:
217 return Mips::LW;
218 case 2:
219 return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
220 case 1:
221 return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
222 default:
223 return Opc;
224 }
225 }
226
227 if (isRegInFprb(ValueReg, MRI)) {
228 if (Ty.isScalar()) {
229 assert(((TySize == 32 && MemSizeInBytes == 4) ||
230 (TySize == 64 && MemSizeInBytes == 8)) &&
231 "Unsupported register bank, LLT, MemSizeInBytes combination");
232
233 if (MemSizeInBytes == 4)
234 return isStore ? Mips::SWC1 : Mips::LWC1;
235
236 if (STI.isFP64bit())
237 return isStore ? Mips::SDC164 : Mips::LDC164;
238 return isStore ? Mips::SDC1 : Mips::LDC1;
239 }
240
241 if (Ty.isVector()) {
242 assert(STI.hasMSA() && "Vector instructions require target with MSA.");
243 assert((TySize == 128 && MemSizeInBytes == 16) &&
244 "Unsupported register bank, LLT, MemSizeInBytes combination");
245 switch (Ty.getElementType().getSizeInBits()) {
246 case 8:
247 return isStore ? Mips::ST_B : Mips::LD_B;
248 case 16:
249 return isStore ? Mips::ST_H : Mips::LD_H;
250 case 32:
251 return isStore ? Mips::ST_W : Mips::LD_W;
252 case 64:
253 return isStore ? Mips::ST_D : Mips::LD_D;
254 default:
255 return Opc;
256 }
257 }
258 }
259
260 return Opc;
261}
262
263bool MipsInstructionSelector::buildUnalignedStore(
264 MachineInstr &I, unsigned Opc, MachineOperand &BaseAddr, unsigned Offset,
265 MachineMemOperand *MMO) const {
266 MachineInstr *NewInst =
267 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
268 .add(I.getOperand(0))
269 .add(BaseAddr)
270 .addImm(Offset)
271 .addMemOperand(MMO);
273 return true;
274}
275
276bool MipsInstructionSelector::buildUnalignedLoad(
277 MachineInstr &I, unsigned Opc, Register Dest, MachineOperand &BaseAddr,
278 unsigned Offset, Register TiedDest, MachineMemOperand *MMO) const {
279 MachineInstr *NewInst =
280 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
281 .addDef(Dest)
282 .add(BaseAddr)
283 .addImm(Offset)
284 .addUse(TiedDest)
285 .addMemOperand(*I.memoperands_begin());
287 return true;
288}
289
290bool MipsInstructionSelector::select(MachineInstr &I) {
291
292 MachineBasicBlock &MBB = *I.getParent();
294 MachineRegisterInfo &MRI = MF.getRegInfo();
295
296 if (!isPreISelGenericOpcode(I.getOpcode())) {
297 if (I.isCopy())
298 return selectCopy(I, MRI);
299
300 return true;
301 }
302
303 if (I.getOpcode() == Mips::G_MUL &&
304 isRegInGprb(I.getOperand(0).getReg(), MRI)) {
305 MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
306 .add(I.getOperand(0))
307 .add(I.getOperand(1))
308 .add(I.getOperand(2));
310 Mul->getOperand(3).setIsDead(true);
311 Mul->getOperand(4).setIsDead(true);
312
313 I.eraseFromParent();
314 return true;
315 }
316
317 if (selectImpl(I, *CoverageInfo))
318 return true;
319
320 MachineInstr *MI = nullptr;
321 using namespace TargetOpcode;
322
323 switch (I.getOpcode()) {
324 case G_UMULH: {
325 Register PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
326 MachineInstr *PseudoMULTu, *PseudoMove;
327
328 PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu))
329 .addDef(PseudoMULTuReg)
330 .add(I.getOperand(1))
331 .add(I.getOperand(2));
332 constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI);
333
334 PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI))
335 .addDef(I.getOperand(0).getReg())
336 .addUse(PseudoMULTuReg);
337 constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI);
338
339 I.eraseFromParent();
340 return true;
341 }
342 case G_PTR_ADD: {
343 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
344 .add(I.getOperand(0))
345 .add(I.getOperand(1))
346 .add(I.getOperand(2));
347 break;
348 }
349 case G_INTTOPTR:
350 case G_PTRTOINT: {
351 I.setDesc(TII.get(COPY));
352 return selectCopy(I, MRI);
353 }
354 case G_FRAME_INDEX: {
355 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
356 .add(I.getOperand(0))
357 .add(I.getOperand(1))
358 .addImm(0);
359 break;
360 }
361 case G_BRJT: {
362 unsigned EntrySize =
364 assert(isPowerOf2_32(EntrySize) &&
365 "Non-power-of-two jump-table entry size not supported.");
366
367 Register JTIndex = MRI.createVirtualRegister(&Mips::GPR32RegClass);
368 MachineInstr *SLL = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SLL))
369 .addDef(JTIndex)
370 .addUse(I.getOperand(2).getReg())
371 .addImm(Log2_32(EntrySize));
373
374 Register DestAddress = MRI.createVirtualRegister(&Mips::GPR32RegClass);
375 MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
376 .addDef(DestAddress)
377 .addUse(I.getOperand(0).getReg())
378 .addUse(JTIndex);
380
381 Register Dest = MRI.createVirtualRegister(&Mips::GPR32RegClass);
382 MachineInstr *LW =
383 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
384 .addDef(Dest)
385 .addUse(DestAddress)
386 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_LO)
388 MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4)));
390
391 if (MF.getTarget().isPositionIndependent()) {
392 Register DestTmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
393 LW->getOperand(0).setReg(DestTmp);
394 MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
395 .addDef(Dest)
396 .addUse(DestTmp)
397 .addUse(MF.getInfo<MipsFunctionInfo>()
398 ->getGlobalBaseRegForGlobalISel(MF));
400 }
401
402 MachineInstr *Branch =
403 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch))
404 .addUse(Dest);
406
407 I.eraseFromParent();
408 return true;
409 }
410 case G_PHI: {
411 const Register DestReg = I.getOperand(0).getReg();
412
413 const TargetRegisterClass *DefRC = nullptr;
414 if (DestReg.isPhysical())
415 DefRC = TRI.getRegClass(DestReg);
416 else
417 DefRC = getRegClassForTypeOnBank(DestReg, MRI);
418
419 I.setDesc(TII.get(TargetOpcode::PHI));
420 return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
421 }
422 case G_STORE:
423 case G_LOAD:
424 case G_ZEXTLOAD:
425 case G_SEXTLOAD: {
426 auto MMO = *I.memoperands_begin();
427 MachineOperand BaseAddr = I.getOperand(1);
428 int64_t SignedOffset = 0;
429 // Try to fold load/store + G_PTR_ADD + G_CONSTANT
430 // %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate
431 // %Addr:(p0) = G_PTR_ADD %BaseAddr, %SignedOffset
432 // %LoadResult/%StoreSrc = load/store %Addr(p0)
433 // into:
434 // %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate
435
436 MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg());
437 if (Addr->getOpcode() == G_PTR_ADD) {
438 MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg());
439 if (Offset->getOpcode() == G_CONSTANT) {
440 APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue();
441 if (OffsetValue.isSignedIntN(16)) {
442 BaseAddr = Addr->getOperand(1);
443 SignedOffset = OffsetValue.getSExtValue();
444 }
445 }
446 }
447
448 // Unaligned memory access
449 if ((!MMO->getSize().hasValue() ||
450 MMO->getAlign() < MMO->getSize().getValue()) &&
452 if (MMO->getSize() != 4 || !isRegInGprb(I.getOperand(0).getReg(), MRI))
453 return false;
454
455 unsigned LeftOffset = SignedOffset + (STI.isLittle() ? 3 : 0);
456 unsigned RightOffset = SignedOffset + (STI.isLittle() ? 0 : 3);
457 if (I.getOpcode() == G_STORE) {
458 if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, LeftOffset, MMO))
459 return false;
460 if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, RightOffset, MMO))
461 return false;
462 I.eraseFromParent();
463 return true;
464 }
465
466 if (I.getOpcode() == G_LOAD) {
467 Register ImplDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
468 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
469 .addDef(ImplDef);
470 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
471 if (!buildUnalignedLoad(I, Mips::LWL, Tmp, BaseAddr, LeftOffset,
472 ImplDef, MMO))
473 return false;
474 if (!buildUnalignedLoad(I, Mips::LWR, I.getOperand(0).getReg(),
475 BaseAddr, RightOffset, Tmp, MMO))
476 return false;
477 I.eraseFromParent();
478 return true;
479 }
480
481 return false;
482 }
483
484 const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
485 if (NewOpc == I.getOpcode())
486 return false;
487
488 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
489 .add(I.getOperand(0))
490 .add(BaseAddr)
491 .addImm(SignedOffset)
492 .addMemOperand(MMO);
493 break;
494 }
495 case G_UDIV:
496 case G_UREM:
497 case G_SDIV:
498 case G_SREM: {
499 Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
500 bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV;
501 bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV;
502
503 MachineInstr *PseudoDIV, *PseudoMove;
504 PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
505 TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
506 .addDef(HILOReg)
507 .add(I.getOperand(1))
508 .add(I.getOperand(2));
509 constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI);
510
511 PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
512 TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
513 .addDef(I.getOperand(0).getReg())
514 .addUse(HILOReg);
515 constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI);
516
517 I.eraseFromParent();
518 return true;
519 }
520 case G_SELECT: {
521 // Handle operands with pointer type.
522 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
523 .add(I.getOperand(0))
524 .add(I.getOperand(2))
525 .add(I.getOperand(1))
526 .add(I.getOperand(3));
527 break;
528 }
529 case G_UNMERGE_VALUES: {
530 if (I.getNumOperands() != 3)
531 return false;
532 Register Src = I.getOperand(2).getReg();
533 Register Lo = I.getOperand(0).getReg();
534 Register Hi = I.getOperand(1).getReg();
535 if (!isRegInFprb(Src, MRI) ||
536 !(isRegInGprb(Lo, MRI) && isRegInGprb(Hi, MRI)))
537 return false;
538
539 unsigned Opcode =
540 STI.isFP64bit() ? Mips::ExtractElementF64_64 : Mips::ExtractElementF64;
541
542 MachineInstr *ExtractLo = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
543 .addDef(Lo)
544 .addUse(Src)
545 .addImm(0);
546 constrainSelectedInstRegOperands(*ExtractLo, TII, TRI, RBI);
547
548 MachineInstr *ExtractHi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
549 .addDef(Hi)
550 .addUse(Src)
551 .addImm(1);
552 constrainSelectedInstRegOperands(*ExtractHi, TII, TRI, RBI);
553
554 I.eraseFromParent();
555 return true;
556 }
557 case G_IMPLICIT_DEF: {
558 Register Dst = I.getOperand(0).getReg();
559 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
560 .addDef(Dst);
561
562 // Set class based on register bank, there can be fpr and gpr implicit def.
563 MRI.setRegClass(Dst, getRegClassForTypeOnBank(Dst, MRI));
564 break;
565 }
566 case G_CONSTANT: {
567 MachineIRBuilder B(I);
568 if (!materialize32BitImm(I.getOperand(0).getReg(),
569 I.getOperand(1).getCImm()->getValue(), B))
570 return false;
571
572 I.eraseFromParent();
573 return true;
574 }
575 case G_FCONSTANT: {
576 const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
577 APInt APImm = FPimm.bitcastToAPInt();
578 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
579
580 if (Size == 32) {
581 Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
582 MachineIRBuilder B(I);
583 if (!materialize32BitImm(GPRReg, APImm, B))
584 return false;
585
586 MachineInstrBuilder MTC1 =
587 B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
588 MTC1.constrainAllUses(TII, TRI, RBI);
589 }
590 if (Size == 64) {
591 Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
592 Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
593 MachineIRBuilder B(I);
594 if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
595 return false;
596 if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
597 return false;
598
599 MachineInstrBuilder PairF64 = B.buildInstr(
600 STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64,
601 {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
602 PairF64.constrainAllUses(TII, TRI, RBI);
603 }
604
605 I.eraseFromParent();
606 return true;
607 }
608 case G_FABS: {
609 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
610 unsigned FABSOpcode =
611 Size == 32 ? Mips::FABS_S
612 : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
613 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
614 .add(I.getOperand(0))
615 .add(I.getOperand(1));
616 break;
617 }
618 case G_FPTOSI: {
619 unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits();
620 unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
621 (void)ToSize;
622 assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI");
623 assert((FromSize == 32 || FromSize == 64) &&
624 "Unsupported floating point size for G_FPTOSI");
625
626 unsigned Opcode;
627 if (FromSize == 32)
628 Opcode = Mips::TRUNC_W_S;
629 else
630 Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32;
631 Register ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass);
632 MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
633 .addDef(ResultInFPR)
634 .addUse(I.getOperand(1).getReg());
636
637 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1))
638 .addDef(I.getOperand(0).getReg())
639 .addUse(ResultInFPR);
641
642 I.eraseFromParent();
643 return true;
644 }
645 case G_GLOBAL_VALUE: {
646 const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
647 if (MF.getTarget().isPositionIndependent()) {
648 MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
649 .addDef(I.getOperand(0).getReg())
650 .addReg(MF.getInfo<MipsFunctionInfo>()
651 ->getGlobalBaseRegForGlobalISel(MF))
652 .addGlobalAddress(GVal);
653 // Global Values that don't have local linkage are handled differently
654 // when they are part of call sequence. MipsCallLowering::lowerCall
655 // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
656 // MO_GOT_CALL flag when Callee doesn't have local linkage.
657 if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
659 else
661 LWGOT->addMemOperand(
665
666 if (GVal->hasLocalLinkage()) {
667 Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
668 LWGOT->getOperand(0).setReg(LWGOTDef);
669
670 MachineInstr *ADDiu =
671 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
672 .addDef(I.getOperand(0).getReg())
673 .addReg(LWGOTDef)
674 .addGlobalAddress(GVal);
677 }
678 } else {
679 Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
680
681 MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
682 .addDef(LUiReg)
683 .addGlobalAddress(GVal);
686
687 MachineInstr *ADDiu =
688 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
689 .addDef(I.getOperand(0).getReg())
690 .addUse(LUiReg)
691 .addGlobalAddress(GVal);
694 }
695 I.eraseFromParent();
696 return true;
697 }
698 case G_JUMP_TABLE: {
699 if (MF.getTarget().isPositionIndependent()) {
700 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
701 .addDef(I.getOperand(0).getReg())
702 .addReg(MF.getInfo<MipsFunctionInfo>()
703 ->getGlobalBaseRegForGlobalISel(MF))
704 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT)
707 Align(4)));
708 } else {
709 MI =
710 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
711 .addDef(I.getOperand(0).getReg())
712 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI);
713 }
714 break;
715 }
716 case G_ICMP: {
717 struct Instr {
718 unsigned Opcode;
720 Instr(unsigned Opcode, Register Def, Register LHS, Register RHS)
721 : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
722
723 bool hasImm() const {
724 if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
725 return true;
726 return false;
727 }
728 };
729
731 Register ICMPReg = I.getOperand(0).getReg();
732 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
733 Register LHS = I.getOperand(2).getReg();
734 Register RHS = I.getOperand(3).getReg();
736 static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
737
738 switch (Cond) {
739 case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
740 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
741 Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
742 break;
743 case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
744 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
745 Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
746 break;
747 case CmpInst::ICMP_UGT: // LHS > RHS -> RHS < LHS
748 Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
749 break;
750 case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
751 Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
752 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
753 break;
754 case CmpInst::ICMP_ULT: // LHS < RHS -> LHS < RHS
755 Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
756 break;
757 case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
758 Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
759 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
760 break;
761 case CmpInst::ICMP_SGT: // LHS > RHS -> RHS < LHS
762 Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
763 break;
764 case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
765 Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
766 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
767 break;
768 case CmpInst::ICMP_SLT: // LHS < RHS -> LHS < RHS
769 Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
770 break;
771 case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
772 Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
773 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
774 break;
775 default:
776 return false;
777 }
778
779 MachineIRBuilder B(I);
780 for (const struct Instr &Instruction : Instructions) {
781 MachineInstrBuilder MIB = B.buildInstr(
782 Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
783
784 if (Instruction.hasImm())
785 MIB.addImm(Instruction.RHS);
786 else
787 MIB.addUse(Instruction.RHS);
788
789 MIB.constrainAllUses(TII, TRI, RBI);
790 }
791
792 I.eraseFromParent();
793 return true;
794 }
795 case G_FCMP: {
796 unsigned MipsFCMPCondCode;
797 bool isLogicallyNegated;
798 switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
799 I.getOperand(1).getPredicate())) {
800 case CmpInst::FCMP_UNO: // Unordered
801 case CmpInst::FCMP_ORD: // Ordered (OR)
802 MipsFCMPCondCode = Mips::FCOND_UN;
803 isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
804 break;
805 case CmpInst::FCMP_OEQ: // Equal
806 case CmpInst::FCMP_UNE: // Not Equal (NEQ)
807 MipsFCMPCondCode = Mips::FCOND_OEQ;
808 isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
809 break;
810 case CmpInst::FCMP_UEQ: // Unordered or Equal
811 case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
812 MipsFCMPCondCode = Mips::FCOND_UEQ;
813 isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
814 break;
815 case CmpInst::FCMP_OLT: // Ordered or Less Than
816 case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
817 MipsFCMPCondCode = Mips::FCOND_OLT;
818 isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
819 break;
820 case CmpInst::FCMP_ULT: // Unordered or Less Than
821 case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
822 MipsFCMPCondCode = Mips::FCOND_ULT;
823 isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
824 break;
825 case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
826 case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
827 MipsFCMPCondCode = Mips::FCOND_OLE;
828 isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
829 break;
830 case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
831 case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
832 MipsFCMPCondCode = Mips::FCOND_ULE;
833 isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
834 break;
835 default:
836 return false;
837 }
838
839 // Default compare result in gpr register will be `true`.
840 // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
841 // using MOVF_I. When orignal predicate (Cond) is logically negated
842 // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
843 unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
844
845 Register TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
846 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
847 .addDef(TrueInReg)
848 .addUse(Mips::ZERO)
849 .addImm(1);
850
851 unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
852 unsigned FCMPOpcode =
853 Size == 32 ? Mips::FCMP_S32
854 : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
855 MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
856 .addUse(I.getOperand(2).getReg())
857 .addUse(I.getOperand(3).getReg())
858 .addImm(MipsFCMPCondCode);
860
861 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
862 .addDef(I.getOperand(0).getReg())
863 .addUse(Mips::ZERO)
864 .addUse(Mips::FCC0)
865 .addUse(TrueInReg);
867
868 I.eraseFromParent();
869 return true;
870 }
871 case G_FENCE: {
872 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
873 break;
874 }
875 case G_VASTART: {
876 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
877 int FI = FuncInfo->getVarArgsFrameIndex();
878
879 Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
880 MachineInstr *LEA_ADDiu =
881 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
882 .addDef(LeaReg)
883 .addFrameIndex(FI)
884 .addImm(0);
885 constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI);
886
887 MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
888 .addUse(LeaReg)
889 .addUse(I.getOperand(0).getReg())
890 .addImm(0);
892
893 I.eraseFromParent();
894 return true;
895 }
896 default:
897 return false;
898 }
899
900 I.eraseFromParent();
902 return true;
903}
904
905namespace llvm {
906InstructionSelector *
908 const MipsSubtarget &Subtarget,
909 const MipsRegisterBankInfo &RBI) {
910 return new MipsInstructionSelector(TM, Subtarget, RBI);
911}
912} // end namespace llvm
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
static bool isStore(int Opcode)
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineIRBuilder class.
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
This file declares the targeting of the RegisterBankInfo class for Mips.
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
BinaryOperator * Mul
APInt bitcastToAPInt() const
Definition APFloat.h:1475
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
Definition APInt.cpp:641
LLVM_ABI APInt getHiBits(unsigned numBits) const
Compute an APInt containing numBits highbits from this APInt.
Definition APInt.cpp:636
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:970
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
Definition APInt.h:431
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:746
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
Definition InstrTypes.h:755
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:745
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ FCMP_ULT
1 1 0 0 True if unordered or less than
Definition InstrTypes.h:754
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
Definition InstrTypes.h:752
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
Definition InstrTypes.h:749
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Definition InstrTypes.h:756
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Definition InstrTypes.h:753
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
bool hasLocalLinkage() const
constexpr bool isScalar() const
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
bool hasValue() const
TypeSize getValue() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
void constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
LLVM_ABI unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
@ MOLoad
The memory access reads data.
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
void setTargetFlags(unsigned F)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
This class provides the information for the target register banks.
bool isFP64bit() const
bool isLittle() const
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
bool isPositionIndependent() const
Value * getOperand(unsigned i) const
Definition User.h:207
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
bool hasImm(uint64_t TSFlags)
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition Utils.cpp:159
@ Store
The extracted value is stored (ExtractElement only).
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
InstructionSelector * createMipsInstructionSelector(const MipsTargetMachine &, const MipsSubtarget &, const MipsRegisterBankInfo &)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.