LLVM 23.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,
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();
293 MachineFunction &MF = *MBB.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 if (I.getOpcode() == G_STORE) {
461 if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, SignedOffset + 3, MMO))
462 return false;
463 if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, SignedOffset, MMO))
464 return false;
465 I.eraseFromParent();
466 return true;
467 }
468
469 if (I.getOpcode() == G_LOAD) {
470 Register ImplDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
471 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
472 .addDef(ImplDef);
473 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
474 if (!buildUnalignedLoad(I, Mips::LWL, Tmp, BaseAddr, SignedOffset + 3,
475 ImplDef, MMO))
476 return false;
477 if (!buildUnalignedLoad(I, Mips::LWR, I.getOperand(0).getReg(),
478 BaseAddr, SignedOffset, Tmp, MMO))
479 return false;
480 I.eraseFromParent();
481 return true;
482 }
483
484 return false;
485 }
486
487 const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
488 if (NewOpc == I.getOpcode())
489 return false;
490
491 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
492 .add(I.getOperand(0))
493 .add(BaseAddr)
494 .addImm(SignedOffset)
495 .addMemOperand(MMO);
496 break;
497 }
498 case G_UDIV:
499 case G_UREM:
500 case G_SDIV:
501 case G_SREM: {
502 Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
503 bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV;
504 bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV;
505
506 MachineInstr *PseudoDIV, *PseudoMove;
507 PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
508 TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
509 .addDef(HILOReg)
510 .add(I.getOperand(1))
511 .add(I.getOperand(2));
512 constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI);
513
514 PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
515 TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
516 .addDef(I.getOperand(0).getReg())
517 .addUse(HILOReg);
518 constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI);
519
520 I.eraseFromParent();
521 return true;
522 }
523 case G_SELECT: {
524 // Handle operands with pointer type.
525 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
526 .add(I.getOperand(0))
527 .add(I.getOperand(2))
528 .add(I.getOperand(1))
529 .add(I.getOperand(3));
530 break;
531 }
532 case G_UNMERGE_VALUES: {
533 if (I.getNumOperands() != 3)
534 return false;
535 Register Src = I.getOperand(2).getReg();
536 Register Lo = I.getOperand(0).getReg();
537 Register Hi = I.getOperand(1).getReg();
538 if (!isRegInFprb(Src, MRI) ||
539 !(isRegInGprb(Lo, MRI) && isRegInGprb(Hi, MRI)))
540 return false;
541
542 unsigned Opcode =
543 STI.isFP64bit() ? Mips::ExtractElementF64_64 : Mips::ExtractElementF64;
544
545 MachineInstr *ExtractLo = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
546 .addDef(Lo)
547 .addUse(Src)
548 .addImm(0);
549 constrainSelectedInstRegOperands(*ExtractLo, TII, TRI, RBI);
550
551 MachineInstr *ExtractHi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
552 .addDef(Hi)
553 .addUse(Src)
554 .addImm(1);
555 constrainSelectedInstRegOperands(*ExtractHi, TII, TRI, RBI);
556
557 I.eraseFromParent();
558 return true;
559 }
560 case G_IMPLICIT_DEF: {
561 Register Dst = I.getOperand(0).getReg();
562 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
563 .addDef(Dst);
564
565 // Set class based on register bank, there can be fpr and gpr implicit def.
566 MRI.setRegClass(Dst, getRegClassForTypeOnBank(Dst, MRI));
567 break;
568 }
569 case G_CONSTANT: {
570 MachineIRBuilder B(I);
571 if (!materialize32BitImm(I.getOperand(0).getReg(),
572 I.getOperand(1).getCImm()->getValue(), B))
573 return false;
574
575 I.eraseFromParent();
576 return true;
577 }
578 case G_FCONSTANT: {
579 const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
580 APInt APImm = FPimm.bitcastToAPInt();
581 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
582
583 if (Size == 32) {
584 Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
585 MachineIRBuilder B(I);
586 if (!materialize32BitImm(GPRReg, APImm, B))
587 return false;
588
589 MachineInstrBuilder MTC1 =
590 B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
591 MTC1.constrainAllUses(TII, TRI, RBI);
592 }
593 if (Size == 64) {
594 Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
595 Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
596 MachineIRBuilder B(I);
597 if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
598 return false;
599 if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
600 return false;
601
602 MachineInstrBuilder PairF64 = B.buildInstr(
603 STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64,
604 {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
605 PairF64.constrainAllUses(TII, TRI, RBI);
606 }
607
608 I.eraseFromParent();
609 return true;
610 }
611 case G_FABS: {
612 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
613 unsigned FABSOpcode =
614 Size == 32 ? Mips::FABS_S
615 : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
616 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
617 .add(I.getOperand(0))
618 .add(I.getOperand(1));
619 break;
620 }
621 case G_FPTOSI: {
622 unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits();
623 unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
624 (void)ToSize;
625 assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI");
626 assert((FromSize == 32 || FromSize == 64) &&
627 "Unsupported floating point size for G_FPTOSI");
628
629 unsigned Opcode;
630 if (FromSize == 32)
631 Opcode = Mips::TRUNC_W_S;
632 else
633 Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32;
634 Register ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass);
635 MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
636 .addDef(ResultInFPR)
637 .addUse(I.getOperand(1).getReg());
639
640 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1))
641 .addDef(I.getOperand(0).getReg())
642 .addUse(ResultInFPR);
644
645 I.eraseFromParent();
646 return true;
647 }
648 case G_GLOBAL_VALUE: {
649 const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
650 if (MF.getTarget().isPositionIndependent()) {
651 MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
652 .addDef(I.getOperand(0).getReg())
653 .addReg(MF.getInfo<MipsFunctionInfo>()
654 ->getGlobalBaseRegForGlobalISel(MF))
655 .addGlobalAddress(GVal);
656 // Global Values that don't have local linkage are handled differently
657 // when they are part of call sequence. MipsCallLowering::lowerCall
658 // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
659 // MO_GOT_CALL flag when Callee doesn't have local linkage.
660 if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
662 else
664 LWGOT->addMemOperand(
668
669 if (GVal->hasLocalLinkage()) {
670 Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
671 LWGOT->getOperand(0).setReg(LWGOTDef);
672
673 MachineInstr *ADDiu =
674 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
675 .addDef(I.getOperand(0).getReg())
676 .addReg(LWGOTDef)
677 .addGlobalAddress(GVal);
680 }
681 } else {
682 Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
683
684 MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
685 .addDef(LUiReg)
686 .addGlobalAddress(GVal);
689
690 MachineInstr *ADDiu =
691 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
692 .addDef(I.getOperand(0).getReg())
693 .addUse(LUiReg)
694 .addGlobalAddress(GVal);
697 }
698 I.eraseFromParent();
699 return true;
700 }
701 case G_JUMP_TABLE: {
702 if (MF.getTarget().isPositionIndependent()) {
703 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
704 .addDef(I.getOperand(0).getReg())
705 .addReg(MF.getInfo<MipsFunctionInfo>()
706 ->getGlobalBaseRegForGlobalISel(MF))
707 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT)
710 Align(4)));
711 } else {
712 MI =
713 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
714 .addDef(I.getOperand(0).getReg())
715 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI);
716 }
717 break;
718 }
719 case G_ICMP: {
720 struct Instr {
721 unsigned Opcode;
723 Instr(unsigned Opcode, Register Def, Register LHS, Register RHS)
724 : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
725
726 bool hasImm() const {
727 if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
728 return true;
729 return false;
730 }
731 };
732
734 Register ICMPReg = I.getOperand(0).getReg();
735 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
736 Register LHS = I.getOperand(2).getReg();
737 Register RHS = I.getOperand(3).getReg();
739 static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
740
741 switch (Cond) {
742 case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
743 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
744 Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
745 break;
746 case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
747 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
748 Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
749 break;
750 case CmpInst::ICMP_UGT: // LHS > RHS -> RHS < LHS
751 Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
752 break;
753 case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
754 Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
755 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
756 break;
757 case CmpInst::ICMP_ULT: // LHS < RHS -> LHS < RHS
758 Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
759 break;
760 case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
761 Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
762 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
763 break;
764 case CmpInst::ICMP_SGT: // LHS > RHS -> RHS < LHS
765 Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
766 break;
767 case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
768 Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
769 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
770 break;
771 case CmpInst::ICMP_SLT: // LHS < RHS -> LHS < RHS
772 Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
773 break;
774 case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
775 Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
776 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
777 break;
778 default:
779 return false;
780 }
781
782 MachineIRBuilder B(I);
783 for (const struct Instr &Instruction : Instructions) {
784 MachineInstrBuilder MIB = B.buildInstr(
785 Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
786
787 if (Instruction.hasImm())
788 MIB.addImm(Instruction.RHS);
789 else
790 MIB.addUse(Instruction.RHS);
791
792 MIB.constrainAllUses(TII, TRI, RBI);
793 }
794
795 I.eraseFromParent();
796 return true;
797 }
798 case G_FCMP: {
799 unsigned MipsFCMPCondCode;
800 bool isLogicallyNegated;
801 switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
802 I.getOperand(1).getPredicate())) {
803 case CmpInst::FCMP_UNO: // Unordered
804 case CmpInst::FCMP_ORD: // Ordered (OR)
805 MipsFCMPCondCode = Mips::FCOND_UN;
806 isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
807 break;
808 case CmpInst::FCMP_OEQ: // Equal
809 case CmpInst::FCMP_UNE: // Not Equal (NEQ)
810 MipsFCMPCondCode = Mips::FCOND_OEQ;
811 isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
812 break;
813 case CmpInst::FCMP_UEQ: // Unordered or Equal
814 case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
815 MipsFCMPCondCode = Mips::FCOND_UEQ;
816 isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
817 break;
818 case CmpInst::FCMP_OLT: // Ordered or Less Than
819 case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
820 MipsFCMPCondCode = Mips::FCOND_OLT;
821 isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
822 break;
823 case CmpInst::FCMP_ULT: // Unordered or Less Than
824 case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
825 MipsFCMPCondCode = Mips::FCOND_ULT;
826 isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
827 break;
828 case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
829 case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
830 MipsFCMPCondCode = Mips::FCOND_OLE;
831 isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
832 break;
833 case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
834 case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
835 MipsFCMPCondCode = Mips::FCOND_ULE;
836 isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
837 break;
838 default:
839 return false;
840 }
841
842 // Default compare result in gpr register will be `true`.
843 // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
844 // using MOVF_I. When orignal predicate (Cond) is logically negated
845 // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
846 unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
847
848 Register TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
849 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
850 .addDef(TrueInReg)
851 .addUse(Mips::ZERO)
852 .addImm(1);
853
854 unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
855 unsigned FCMPOpcode =
856 Size == 32 ? Mips::FCMP_S32
857 : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
858 MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
859 .addUse(I.getOperand(2).getReg())
860 .addUse(I.getOperand(3).getReg())
861 .addImm(MipsFCMPCondCode);
863
864 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
865 .addDef(I.getOperand(0).getReg())
866 .addUse(Mips::ZERO)
867 .addUse(Mips::FCC0)
868 .addUse(TrueInReg);
870
871 I.eraseFromParent();
872 return true;
873 }
874 case G_FENCE: {
875 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
876 break;
877 }
878 case G_VASTART: {
879 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
880 int FI = FuncInfo->getVarArgsFrameIndex();
881
882 Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
883 MachineInstr *LEA_ADDiu =
884 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
885 .addDef(LeaReg)
886 .addFrameIndex(FI)
887 .addImm(0);
888 constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI);
889
890 MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
891 .addUse(LeaReg)
892 .addUse(I.getOperand(0).getReg())
893 .addImm(0);
895
896 I.eraseFromParent();
897 return true;
898 }
899 default:
900 return false;
901 }
902
903 I.eraseFromParent();
905 return true;
906}
907
908namespace llvm {
909InstructionSelector *
911 const MipsSubtarget &Subtarget,
912 const MipsRegisterBankInfo &RBI) {
913 return new MipsInstructionSelector(TM, Subtarget, RBI);
914}
915} // end namespace llvm
unsigned const MachineRegisterInfo * MRI
#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!")
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:114
Value * RHS
Value * LHS
BinaryOperator * Mul
APInt bitcastToAPInt() const
Definition APFloat.h:1404
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:644
LLVM_ABI APInt getHiBits(unsigned numBits) const
Compute an APInt containing numBits highbits from this APInt.
Definition APInt.cpp:639
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:936
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
Definition APInt.h:436
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1577
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:679
@ ICMP_SLT
signed less than
Definition InstrTypes.h:705
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:706
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:682
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
Definition InstrTypes.h:691
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:680
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:681
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:700
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:699
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:703
@ FCMP_ULT
1 1 0 0 True if unordered or less than
Definition InstrTypes.h:690
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:684
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:687
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:701
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
Definition InstrTypes.h:688
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:683
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
Definition InstrTypes.h:685
@ ICMP_NE
not equal
Definition InstrTypes.h:698
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:704
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Definition InstrTypes.h:692
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:702
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Definition InstrTypes.h:689
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:686
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
constexpr 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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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...
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,...
This class provides the information for the target register banks.
bool isFP64bit() 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.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
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:155
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:331
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.