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_BRINDIRECT: {
411 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch))
412 .add(I.getOperand(0));
413 break;
414 }
415 case G_PHI: {
416 const Register DestReg = I.getOperand(0).getReg();
417
418 const TargetRegisterClass *DefRC = nullptr;
419 if (DestReg.isPhysical())
420 DefRC = TRI.getRegClass(DestReg);
421 else
422 DefRC = getRegClassForTypeOnBank(DestReg, MRI);
423
424 I.setDesc(TII.get(TargetOpcode::PHI));
425 return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
426 }
427 case G_STORE:
428 case G_LOAD:
429 case G_ZEXTLOAD:
430 case G_SEXTLOAD: {
431 auto MMO = *I.memoperands_begin();
432 MachineOperand BaseAddr = I.getOperand(1);
433 int64_t SignedOffset = 0;
434 // Try to fold load/store + G_PTR_ADD + G_CONSTANT
435 // %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate
436 // %Addr:(p0) = G_PTR_ADD %BaseAddr, %SignedOffset
437 // %LoadResult/%StoreSrc = load/store %Addr(p0)
438 // into:
439 // %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate
440
441 MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg());
442 if (Addr->getOpcode() == G_PTR_ADD) {
443 MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg());
444 if (Offset->getOpcode() == G_CONSTANT) {
445 APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue();
446 if (OffsetValue.isSignedIntN(16)) {
447 BaseAddr = Addr->getOperand(1);
448 SignedOffset = OffsetValue.getSExtValue();
449 }
450 }
451 }
452
453 // Unaligned memory access
454 if ((!MMO->getSize().hasValue() ||
455 MMO->getAlign() < MMO->getSize().getValue()) &&
457 if (MMO->getSize() != 4 || !isRegInGprb(I.getOperand(0).getReg(), MRI))
458 return false;
459
460 unsigned LeftOffset = SignedOffset + (STI.isLittle() ? 3 : 0);
461 unsigned RightOffset = SignedOffset + (STI.isLittle() ? 0 : 3);
462 if (I.getOpcode() == G_STORE) {
463 if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, LeftOffset, MMO))
464 return false;
465 if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, RightOffset, MMO))
466 return false;
467 I.eraseFromParent();
468 return true;
469 }
470
471 if (I.getOpcode() == G_LOAD) {
472 Register ImplDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
473 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
474 .addDef(ImplDef);
475 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
476 if (!buildUnalignedLoad(I, Mips::LWL, Tmp, BaseAddr, LeftOffset,
477 ImplDef, MMO))
478 return false;
479 if (!buildUnalignedLoad(I, Mips::LWR, I.getOperand(0).getReg(),
480 BaseAddr, RightOffset, Tmp, MMO))
481 return false;
482 I.eraseFromParent();
483 return true;
484 }
485
486 return false;
487 }
488
489 const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
490 if (NewOpc == I.getOpcode())
491 return false;
492
493 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
494 .add(I.getOperand(0))
495 .add(BaseAddr)
496 .addImm(SignedOffset)
497 .addMemOperand(MMO);
498 break;
499 }
500 case G_UDIV:
501 case G_UREM:
502 case G_SDIV:
503 case G_SREM: {
504 Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
505 bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV;
506 bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV;
507
508 MachineInstr *PseudoDIV, *PseudoMove;
509 PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
510 TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
511 .addDef(HILOReg)
512 .add(I.getOperand(1))
513 .add(I.getOperand(2));
514 constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI);
515
516 PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
517 TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
518 .addDef(I.getOperand(0).getReg())
519 .addUse(HILOReg);
520 constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI);
521
522 I.eraseFromParent();
523 return true;
524 }
525 case G_SELECT: {
526 // Handle operands with pointer type.
527 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
528 .add(I.getOperand(0))
529 .add(I.getOperand(2))
530 .add(I.getOperand(1))
531 .add(I.getOperand(3));
532 break;
533 }
534 case G_UNMERGE_VALUES: {
535 if (I.getNumOperands() != 3)
536 return false;
537 Register Src = I.getOperand(2).getReg();
538 Register Lo = I.getOperand(0).getReg();
539 Register Hi = I.getOperand(1).getReg();
540 if (!isRegInFprb(Src, MRI) ||
541 !(isRegInGprb(Lo, MRI) && isRegInGprb(Hi, MRI)))
542 return false;
543
544 unsigned Opcode =
545 STI.isFP64bit() ? Mips::ExtractElementF64_64 : Mips::ExtractElementF64;
546
547 MachineInstr *ExtractLo = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
548 .addDef(Lo)
549 .addUse(Src)
550 .addImm(0);
551 constrainSelectedInstRegOperands(*ExtractLo, TII, TRI, RBI);
552
553 MachineInstr *ExtractHi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
554 .addDef(Hi)
555 .addUse(Src)
556 .addImm(1);
557 constrainSelectedInstRegOperands(*ExtractHi, TII, TRI, RBI);
558
559 I.eraseFromParent();
560 return true;
561 }
562 case G_IMPLICIT_DEF: {
563 Register Dst = I.getOperand(0).getReg();
564 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
565 .addDef(Dst);
566
567 // Set class based on register bank, there can be fpr and gpr implicit def.
568 MRI.setRegClass(Dst, getRegClassForTypeOnBank(Dst, MRI));
569 break;
570 }
571 case G_CONSTANT: {
572 MachineIRBuilder B(I);
573 if (!materialize32BitImm(I.getOperand(0).getReg(),
574 I.getOperand(1).getCImm()->getValue(), B))
575 return false;
576
577 I.eraseFromParent();
578 return true;
579 }
580 case G_FCONSTANT: {
581 const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
582 APInt APImm = FPimm.bitcastToAPInt();
583 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
584
585 if (Size == 32) {
586 Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
587 MachineIRBuilder B(I);
588 if (!materialize32BitImm(GPRReg, APImm, B))
589 return false;
590
591 MachineInstrBuilder MTC1 =
592 B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
593 MTC1.constrainAllUses(TII, TRI, RBI);
594 }
595 if (Size == 64) {
596 Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
597 Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
598 MachineIRBuilder B(I);
599 if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
600 return false;
601 if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
602 return false;
603
604 MachineInstrBuilder PairF64 = B.buildInstr(
605 STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64,
606 {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
607 PairF64.constrainAllUses(TII, TRI, RBI);
608 }
609
610 I.eraseFromParent();
611 return true;
612 }
613 case G_FABS: {
614 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
615 unsigned FABSOpcode =
616 Size == 32 ? Mips::FABS_S
617 : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
618 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
619 .add(I.getOperand(0))
620 .add(I.getOperand(1));
621 break;
622 }
623 case G_FPTOSI: {
624 unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits();
625 unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
626 (void)ToSize;
627 assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI");
628 assert((FromSize == 32 || FromSize == 64) &&
629 "Unsupported floating point size for G_FPTOSI");
630
631 unsigned Opcode;
632 if (FromSize == 32)
633 Opcode = Mips::TRUNC_W_S;
634 else
635 Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32;
636 Register ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass);
637 MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
638 .addDef(ResultInFPR)
639 .addUse(I.getOperand(1).getReg());
641
642 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1))
643 .addDef(I.getOperand(0).getReg())
644 .addUse(ResultInFPR);
646
647 I.eraseFromParent();
648 return true;
649 }
650 case G_GLOBAL_VALUE: {
651 const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
652 if (MF.getTarget().isPositionIndependent()) {
653 MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
654 .addDef(I.getOperand(0).getReg())
655 .addReg(MF.getInfo<MipsFunctionInfo>()
656 ->getGlobalBaseRegForGlobalISel(MF))
657 .addGlobalAddress(GVal);
658 // Global Values that don't have local linkage are handled differently
659 // when they are part of call sequence. MipsCallLowering::lowerCall
660 // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
661 // MO_GOT_CALL flag when Callee doesn't have local linkage.
662 if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
664 else
666 LWGOT->addMemOperand(
670
671 if (GVal->hasLocalLinkage()) {
672 Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
673 LWGOT->getOperand(0).setReg(LWGOTDef);
674
675 MachineInstr *ADDiu =
676 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
677 .addDef(I.getOperand(0).getReg())
678 .addReg(LWGOTDef)
679 .addGlobalAddress(GVal);
682 }
683 } else {
684 Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
685
686 MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
687 .addDef(LUiReg)
688 .addGlobalAddress(GVal);
691
692 MachineInstr *ADDiu =
693 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
694 .addDef(I.getOperand(0).getReg())
695 .addUse(LUiReg)
696 .addGlobalAddress(GVal);
699 }
700 I.eraseFromParent();
701 return true;
702 }
703 case G_JUMP_TABLE: {
704 if (MF.getTarget().isPositionIndependent()) {
705 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
706 .addDef(I.getOperand(0).getReg())
707 .addReg(MF.getInfo<MipsFunctionInfo>()
708 ->getGlobalBaseRegForGlobalISel(MF))
709 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT)
712 Align(4)));
713 } else {
714 MI =
715 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
716 .addDef(I.getOperand(0).getReg())
717 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI);
718 }
719 break;
720 }
721 case G_ICMP: {
722 struct Instr {
723 unsigned Opcode;
725 Instr(unsigned Opcode, Register Def, Register LHS, Register RHS)
726 : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
727
728 bool hasImm() const {
729 if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
730 return true;
731 return false;
732 }
733 };
734
736 Register ICMPReg = I.getOperand(0).getReg();
737 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
738 Register LHS = I.getOperand(2).getReg();
739 Register RHS = I.getOperand(3).getReg();
741 static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
742
743 switch (Cond) {
744 case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
745 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
746 Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
747 break;
748 case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
749 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
750 Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
751 break;
752 case CmpInst::ICMP_UGT: // LHS > RHS -> RHS < LHS
753 Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
754 break;
755 case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
756 Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
757 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
758 break;
759 case CmpInst::ICMP_ULT: // LHS < RHS -> LHS < RHS
760 Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
761 break;
762 case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
763 Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
764 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
765 break;
766 case CmpInst::ICMP_SGT: // LHS > RHS -> RHS < LHS
767 Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
768 break;
769 case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
770 Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
771 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
772 break;
773 case CmpInst::ICMP_SLT: // LHS < RHS -> LHS < RHS
774 Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
775 break;
776 case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
777 Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
778 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
779 break;
780 default:
781 return false;
782 }
783
784 MachineIRBuilder B(I);
785 for (const struct Instr &Instruction : Instructions) {
786 MachineInstrBuilder MIB = B.buildInstr(
787 Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
788
789 if (Instruction.hasImm())
790 MIB.addImm(Instruction.RHS);
791 else
792 MIB.addUse(Instruction.RHS);
793
794 MIB.constrainAllUses(TII, TRI, RBI);
795 }
796
797 I.eraseFromParent();
798 return true;
799 }
800 case G_FCMP: {
801 unsigned MipsFCMPCondCode;
802 bool isLogicallyNegated;
803 switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
804 I.getOperand(1).getPredicate())) {
805 case CmpInst::FCMP_UNO: // Unordered
806 case CmpInst::FCMP_ORD: // Ordered (OR)
807 MipsFCMPCondCode = Mips::FCOND_UN;
808 isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
809 break;
810 case CmpInst::FCMP_OEQ: // Equal
811 case CmpInst::FCMP_UNE: // Not Equal (NEQ)
812 MipsFCMPCondCode = Mips::FCOND_OEQ;
813 isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
814 break;
815 case CmpInst::FCMP_UEQ: // Unordered or Equal
816 case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
817 MipsFCMPCondCode = Mips::FCOND_UEQ;
818 isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
819 break;
820 case CmpInst::FCMP_OLT: // Ordered or Less Than
821 case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
822 MipsFCMPCondCode = Mips::FCOND_OLT;
823 isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
824 break;
825 case CmpInst::FCMP_ULT: // Unordered or Less Than
826 case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
827 MipsFCMPCondCode = Mips::FCOND_ULT;
828 isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
829 break;
830 case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
831 case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
832 MipsFCMPCondCode = Mips::FCOND_OLE;
833 isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
834 break;
835 case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
836 case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
837 MipsFCMPCondCode = Mips::FCOND_ULE;
838 isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
839 break;
840 default:
841 return false;
842 }
843
844 // Default compare result in gpr register will be `true`.
845 // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
846 // using MOVF_I. When orignal predicate (Cond) is logically negated
847 // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
848 unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
849
850 Register TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
851 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
852 .addDef(TrueInReg)
853 .addUse(Mips::ZERO)
854 .addImm(1);
855
856 unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
857 unsigned FCMPOpcode =
858 Size == 32 ? Mips::FCMP_S32
859 : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
860 MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
861 .addUse(I.getOperand(2).getReg())
862 .addUse(I.getOperand(3).getReg())
863 .addImm(MipsFCMPCondCode);
865
866 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
867 .addDef(I.getOperand(0).getReg())
868 .addUse(Mips::ZERO)
869 .addUse(Mips::FCC0)
870 .addUse(TrueInReg);
872
873 I.eraseFromParent();
874 return true;
875 }
876 case G_FENCE: {
877 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
878 break;
879 }
880 case G_VASTART: {
881 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
882 int FI = FuncInfo->getVarArgsFrameIndex();
883
884 Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
885 MachineInstr *LEA_ADDiu =
886 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
887 .addDef(LeaReg)
888 .addFrameIndex(FI)
889 .addImm(0);
890 constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI);
891
892 MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
893 .addUse(LeaReg)
894 .addUse(I.getOperand(0).getReg())
895 .addImm(0);
897
898 I.eraseFromParent();
899 return true;
900 }
901 default:
902 return false;
903 }
904
905 I.eraseFromParent();
907 return true;
908}
909
910namespace llvm {
911InstructionSelector *
913 const MipsSubtarget &Subtarget,
914 const MipsRegisterBankInfo &RBI) {
915 return new MipsInstructionSelector(TM, Subtarget, RBI);
916}
917} // 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.