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 
14 #include "MCTargetDesc/MipsInstPrinter.h"
15 #include "MipsMachineFunction.h"
16 #include "MipsRegisterBankInfo.h"
17 #include "MipsTargetMachine.h"
18 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
19 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
20 #include "llvm/CodeGen/MachineJumpTableInfo.h"
21 
22 #define DEBUG_TYPE "mips-isel"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 #define GET_GLOBALISEL_PREDICATE_BITSET
29 #include "MipsGenGlobalISel.inc"
30 #undef GET_GLOBALISEL_PREDICATE_BITSET
31 
32 class MipsInstructionSelector : public InstructionSelector {
33 public:
34   MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI,
35                           const MipsRegisterBankInfo &RBI);
36 
37   bool select(MachineInstr &I) override;
38   static const char *getName() { return DEBUG_TYPE; }
39 
40 private:
41   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
42   bool materialize32BitImm(Register DestReg, APInt Imm,
43                            MachineIRBuilder &B) const;
44   bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
45   const TargetRegisterClass *
46   getRegClassForTypeOnBank(unsigned OpSize, const RegisterBank &RB,
47                            const RegisterBankInfo &RBI) const;
48   unsigned selectLoadStoreOpCode(MachineInstr &I,
49                                  MachineRegisterInfo &MRI) const;
50 
51   const MipsTargetMachine &TM;
52   const MipsSubtarget &STI;
53   const MipsInstrInfo &TII;
54   const MipsRegisterInfo &TRI;
55   const MipsRegisterBankInfo &RBI;
56 
57 #define GET_GLOBALISEL_PREDICATES_DECL
58 #include "MipsGenGlobalISel.inc"
59 #undef GET_GLOBALISEL_PREDICATES_DECL
60 
61 #define GET_GLOBALISEL_TEMPORARIES_DECL
62 #include "MipsGenGlobalISel.inc"
63 #undef GET_GLOBALISEL_TEMPORARIES_DECL
64 };
65 
66 } // end anonymous namespace
67 
68 #define GET_GLOBALISEL_IMPL
69 #include "MipsGenGlobalISel.inc"
70 #undef GET_GLOBALISEL_IMPL
71 
72 MipsInstructionSelector::MipsInstructionSelector(
73     const MipsTargetMachine &TM, const MipsSubtarget &STI,
74     const MipsRegisterBankInfo &RBI)
75     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
76       TRI(*STI.getRegisterInfo()), RBI(RBI),
77 
78 #define GET_GLOBALISEL_PREDICATES_INIT
79 #include "MipsGenGlobalISel.inc"
80 #undef GET_GLOBALISEL_PREDICATES_INIT
81 #define GET_GLOBALISEL_TEMPORARIES_INIT
82 #include "MipsGenGlobalISel.inc"
83 #undef GET_GLOBALISEL_TEMPORARIES_INIT
84 {
85 }
86 
87 bool MipsInstructionSelector::selectCopy(MachineInstr &I,
88                                          MachineRegisterInfo &MRI) const {
89   Register DstReg = I.getOperand(0).getReg();
90   if (Register::isPhysicalRegister(DstReg))
91     return true;
92 
93   const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
94   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
95 
96   const TargetRegisterClass *RC = &Mips::GPR32RegClass;
97   if (RegBank->getID() == Mips::FPRBRegBankID) {
98     if (DstSize == 32)
99       RC = &Mips::FGR32RegClass;
100     else if (DstSize == 64)
101       RC = STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
102     else
103       llvm_unreachable("Unsupported destination size");
104   }
105   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
106     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
107                       << " operand\n");
108     return false;
109   }
110   return true;
111 }
112 
113 const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
114     unsigned OpSize, const RegisterBank &RB,
115     const RegisterBankInfo &RBI) const {
116   if (RB.getID() == Mips::GPRBRegBankID)
117     return &Mips::GPR32RegClass;
118 
119   if (RB.getID() == Mips::FPRBRegBankID)
120     return OpSize == 32
121                ? &Mips::FGR32RegClass
122                : STI.hasMips32r6() || STI.isFP64bit() ? &Mips::FGR64RegClass
123                                                       : &Mips::AFGR64RegClass;
124 
125   llvm_unreachable("getRegClassForTypeOnBank can't find register class.");
126   return nullptr;
127 }
128 
129 bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
130                                                   MachineIRBuilder &B) const {
131   assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
132   // Ori zero extends immediate. Used for values with zeros in high 16 bits.
133   if (Imm.getHiBits(16).isNullValue()) {
134     MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
135                              .addImm(Imm.getLoBits(16).getLimitedValue());
136     return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
137   }
138   // Lui places immediate in high 16 bits and sets low 16 bits to zero.
139   if (Imm.getLoBits(16).isNullValue()) {
140     MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {})
141                              .addImm(Imm.getHiBits(16).getLimitedValue());
142     return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
143   }
144   // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
145   if (Imm.isSignedIntN(16)) {
146     MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
147                              .addImm(Imm.getLoBits(16).getLimitedValue());
148     return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
149   }
150   // Values that cannot be materialized with single immediate instruction.
151   Register LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
152   MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {})
153                           .addImm(Imm.getHiBits(16).getLimitedValue());
154   MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
155                           .addImm(Imm.getLoBits(16).getLimitedValue());
156   if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
157     return false;
158   if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
159     return false;
160   return true;
161 }
162 
163 /// Returning Opc indicates that we failed to select MIPS instruction opcode.
164 unsigned
165 MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
166                                                MachineRegisterInfo &MRI) const {
167   STI.getRegisterInfo();
168   const Register DestReg = I.getOperand(0).getReg();
169   const unsigned RegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
170   const unsigned MemSizeInBytes = (*I.memoperands_begin())->getSize();
171   unsigned Opc = I.getOpcode();
172   const bool isStore = Opc == TargetOpcode::G_STORE;
173   if (RegBank == Mips::GPRBRegBankID) {
174     if (isStore)
175       switch (MemSizeInBytes) {
176       case 4:
177         return Mips::SW;
178       case 2:
179         return Mips::SH;
180       case 1:
181         return Mips::SB;
182       default:
183         return Opc;
184       }
185     else
186       // Unspecified extending load is selected into zeroExtending load.
187       switch (MemSizeInBytes) {
188       case 4:
189         return Mips::LW;
190       case 2:
191         return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
192       case 1:
193         return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
194       default:
195         return Opc;
196       }
197   }
198 
199   if (RegBank == Mips::FPRBRegBankID) {
200     switch (MemSizeInBytes) {
201     case 4:
202       return isStore ? Mips::SWC1 : Mips::LWC1;
203     case 8:
204       if (STI.isFP64bit())
205         return isStore ? Mips::SDC164 : Mips::LDC164;
206       else
207         return isStore ? Mips::SDC1 : Mips::LDC1;
208     case 16: {
209       assert(STI.hasMSA() && "Vector instructions require target with MSA.");
210       const unsigned VectorElementSizeInBytes =
211           MRI.getType(DestReg).getElementType().getSizeInBytes();
212       if (VectorElementSizeInBytes == 1)
213         return isStore ? Mips::ST_B : Mips::LD_B;
214       if (VectorElementSizeInBytes == 2)
215         return isStore ? Mips::ST_H : Mips::LD_H;
216       if (VectorElementSizeInBytes == 4)
217         return isStore ? Mips::ST_W : Mips::LD_W;
218       if (VectorElementSizeInBytes == 8)
219         return isStore ? Mips::ST_D : Mips::LD_D;
220       return Opc;
221     }
222     default:
223       return Opc;
224     }
225   }
226   return Opc;
227 }
228 
229 bool MipsInstructionSelector::select(MachineInstr &I) {
230 
231   MachineBasicBlock &MBB = *I.getParent();
232   MachineFunction &MF = *MBB.getParent();
233   MachineRegisterInfo &MRI = MF.getRegInfo();
234 
235   if (!isPreISelGenericOpcode(I.getOpcode())) {
236     if (I.isCopy())
237       return selectCopy(I, MRI);
238 
239     return true;
240   }
241 
242   if (I.getOpcode() == Mips::G_MUL &&
243       (RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI)->getID() ==
244        Mips::GPRBRegBankID)) {
245     MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
246                             .add(I.getOperand(0))
247                             .add(I.getOperand(1))
248                             .add(I.getOperand(2));
249     if (!constrainSelectedInstRegOperands(*Mul, TII, TRI, RBI))
250       return false;
251     Mul->getOperand(3).setIsDead(true);
252     Mul->getOperand(4).setIsDead(true);
253 
254     I.eraseFromParent();
255     return true;
256   }
257 
258   if (selectImpl(I, *CoverageInfo))
259     return true;
260 
261   MachineInstr *MI = nullptr;
262   using namespace TargetOpcode;
263 
264   switch (I.getOpcode()) {
265   case G_UMULH: {
266     Register PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
267     MachineInstr *PseudoMULTu, *PseudoMove;
268 
269     PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu))
270                       .addDef(PseudoMULTuReg)
271                       .add(I.getOperand(1))
272                       .add(I.getOperand(2));
273     if (!constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI))
274       return false;
275 
276     PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI))
277                      .addDef(I.getOperand(0).getReg())
278                      .addUse(PseudoMULTuReg);
279     if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
280       return false;
281 
282     I.eraseFromParent();
283     return true;
284   }
285   case G_GEP: {
286     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
287              .add(I.getOperand(0))
288              .add(I.getOperand(1))
289              .add(I.getOperand(2));
290     break;
291   }
292   case G_INTTOPTR:
293   case G_PTRTOINT: {
294     I.setDesc(TII.get(COPY));
295     return selectCopy(I, MRI);
296   }
297   case G_FRAME_INDEX: {
298     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
299              .add(I.getOperand(0))
300              .add(I.getOperand(1))
301              .addImm(0);
302     break;
303   }
304   case G_BRCOND: {
305     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::BNE))
306              .add(I.getOperand(0))
307              .addUse(Mips::ZERO)
308              .add(I.getOperand(1));
309     break;
310   }
311   case G_BRJT: {
312     unsigned EntrySize =
313         MF.getJumpTableInfo()->getEntrySize(MF.getDataLayout());
314     assert(isPowerOf2_32(EntrySize) &&
315            "Non-power-of-two jump-table entry size not supported.");
316 
317     Register JTIndex = MRI.createVirtualRegister(&Mips::GPR32RegClass);
318     MachineInstr *SLL = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SLL))
319                             .addDef(JTIndex)
320                             .addUse(I.getOperand(2).getReg())
321                             .addImm(Log2_32(EntrySize));
322     if (!constrainSelectedInstRegOperands(*SLL, TII, TRI, RBI))
323       return false;
324 
325     Register DestAddress = MRI.createVirtualRegister(&Mips::GPR32RegClass);
326     MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
327                              .addDef(DestAddress)
328                              .addUse(I.getOperand(0).getReg())
329                              .addUse(JTIndex);
330     if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI))
331       return false;
332 
333     Register Dest = MRI.createVirtualRegister(&Mips::GPR32RegClass);
334     MachineInstr *LW =
335         BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
336             .addDef(Dest)
337             .addUse(DestAddress)
338             .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_LO)
339             .addMemOperand(MF.getMachineMemOperand(
340                 MachinePointerInfo(), MachineMemOperand::MOLoad, 4, 4));
341     if (!constrainSelectedInstRegOperands(*LW, TII, TRI, RBI))
342       return false;
343 
344     if (MF.getTarget().isPositionIndependent()) {
345       Register DestTmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
346       LW->getOperand(0).setReg(DestTmp);
347       MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
348                                .addDef(Dest)
349                                .addUse(DestTmp)
350                                .addUse(MF.getInfo<MipsFunctionInfo>()
351                                            ->getGlobalBaseRegForGlobalISel());
352       if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI))
353         return false;
354     }
355 
356     MachineInstr *Branch =
357         BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch))
358             .addUse(Dest);
359     if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
360       return false;
361 
362     I.eraseFromParent();
363     return true;
364   }
365   case G_BRINDIRECT: {
366     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch))
367              .add(I.getOperand(0));
368     break;
369   }
370   case G_PHI: {
371     const Register DestReg = I.getOperand(0).getReg();
372     const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
373 
374     const TargetRegisterClass *DefRC = nullptr;
375     if (Register::isPhysicalRegister(DestReg))
376       DefRC = TRI.getRegClass(DestReg);
377     else
378       DefRC = getRegClassForTypeOnBank(OpSize,
379                                        *RBI.getRegBank(DestReg, MRI, TRI), RBI);
380 
381     I.setDesc(TII.get(TargetOpcode::PHI));
382     return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
383   }
384   case G_STORE:
385   case G_LOAD:
386   case G_ZEXTLOAD:
387   case G_SEXTLOAD: {
388     const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
389     if (NewOpc == I.getOpcode())
390       return false;
391 
392     MachineOperand BaseAddr = I.getOperand(1);
393     int64_t SignedOffset = 0;
394     // Try to fold load/store + G_GEP + G_CONSTANT
395     // %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate
396     // %Addr:(p0) = G_GEP %BaseAddr, %SignedOffset
397     // %LoadResult/%StoreSrc = load/store %Addr(p0)
398     // into:
399     // %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate
400 
401     MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg());
402     if (Addr->getOpcode() == G_GEP) {
403       MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg());
404       if (Offset->getOpcode() == G_CONSTANT) {
405         APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue();
406         if (OffsetValue.isSignedIntN(16)) {
407           BaseAddr = Addr->getOperand(1);
408           SignedOffset = OffsetValue.getSExtValue();
409         }
410       }
411     }
412 
413     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
414              .add(I.getOperand(0))
415              .add(BaseAddr)
416              .addImm(SignedOffset)
417              .addMemOperand(*I.memoperands_begin());
418     break;
419   }
420   case G_UDIV:
421   case G_UREM:
422   case G_SDIV:
423   case G_SREM: {
424     Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
425     bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV;
426     bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV;
427 
428     MachineInstr *PseudoDIV, *PseudoMove;
429     PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
430                         TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
431                     .addDef(HILOReg)
432                     .add(I.getOperand(1))
433                     .add(I.getOperand(2));
434     if (!constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI))
435       return false;
436 
437     PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
438                          TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
439                      .addDef(I.getOperand(0).getReg())
440                      .addUse(HILOReg);
441     if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
442       return false;
443 
444     I.eraseFromParent();
445     return true;
446   }
447   case G_SELECT: {
448     // Handle operands with pointer type.
449     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
450              .add(I.getOperand(0))
451              .add(I.getOperand(2))
452              .add(I.getOperand(1))
453              .add(I.getOperand(3));
454     break;
455   }
456   case G_IMPLICIT_DEF: {
457     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
458              .add(I.getOperand(0));
459 
460     // Set class based on register bank, there can be fpr and gpr implicit def.
461     MRI.setRegClass(MI->getOperand(0).getReg(),
462                     getRegClassForTypeOnBank(
463                         MRI.getType(I.getOperand(0).getReg()).getSizeInBits(),
464                         *RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI),
465                         RBI));
466     break;
467   }
468   case G_CONSTANT: {
469     MachineIRBuilder B(I);
470     if (!materialize32BitImm(I.getOperand(0).getReg(),
471                              I.getOperand(1).getCImm()->getValue(), B))
472       return false;
473 
474     I.eraseFromParent();
475     return true;
476   }
477   case G_FCONSTANT: {
478     const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
479     APInt APImm = FPimm.bitcastToAPInt();
480     unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
481 
482     if (Size == 32) {
483       Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
484       MachineIRBuilder B(I);
485       if (!materialize32BitImm(GPRReg, APImm, B))
486         return false;
487 
488       MachineInstrBuilder MTC1 =
489           B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
490       if (!MTC1.constrainAllUses(TII, TRI, RBI))
491         return false;
492     }
493     if (Size == 64) {
494       Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
495       Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
496       MachineIRBuilder B(I);
497       if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
498         return false;
499       if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
500         return false;
501 
502       MachineInstrBuilder PairF64 = B.buildInstr(
503           STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64,
504           {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
505       if (!PairF64.constrainAllUses(TII, TRI, RBI))
506         return false;
507     }
508 
509     I.eraseFromParent();
510     return true;
511   }
512   case G_FABS: {
513     unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
514     unsigned FABSOpcode =
515         Size == 32 ? Mips::FABS_S
516                    : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
517     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
518              .add(I.getOperand(0))
519              .add(I.getOperand(1));
520     break;
521   }
522   case G_FPTOSI: {
523     unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits();
524     unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
525     (void)ToSize;
526     assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI");
527     assert((FromSize == 32 || FromSize == 64) &&
528            "Unsupported floating point size for G_FPTOSI");
529 
530     unsigned Opcode;
531     if (FromSize == 32)
532       Opcode = Mips::TRUNC_W_S;
533     else
534       Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32;
535     Register ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass);
536     MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
537                 .addDef(ResultInFPR)
538                 .addUse(I.getOperand(1).getReg());
539     if (!constrainSelectedInstRegOperands(*Trunc, TII, TRI, RBI))
540       return false;
541 
542     MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1))
543                              .addDef(I.getOperand(0).getReg())
544                              .addUse(ResultInFPR);
545     if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
546       return false;
547 
548     I.eraseFromParent();
549     return true;
550   }
551   case G_GLOBAL_VALUE: {
552     const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
553     if (MF.getTarget().isPositionIndependent()) {
554       MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
555                                 .addDef(I.getOperand(0).getReg())
556                                 .addReg(MF.getInfo<MipsFunctionInfo>()
557                                             ->getGlobalBaseRegForGlobalISel())
558                                 .addGlobalAddress(GVal);
559       // Global Values that don't have local linkage are handled differently
560       // when they are part of call sequence. MipsCallLowering::lowerCall
561       // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
562       // MO_GOT_CALL flag when Callee doesn't have local linkage.
563       if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
564         LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL);
565       else
566         LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT);
567       LWGOT->addMemOperand(
568           MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF),
569                                       MachineMemOperand::MOLoad, 4, 4));
570       if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI))
571         return false;
572 
573       if (GVal->hasLocalLinkage()) {
574         Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
575         LWGOT->getOperand(0).setReg(LWGOTDef);
576 
577         MachineInstr *ADDiu =
578             BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
579                 .addDef(I.getOperand(0).getReg())
580                 .addReg(LWGOTDef)
581                 .addGlobalAddress(GVal);
582         ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
583         if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
584           return false;
585       }
586     } else {
587       Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
588 
589       MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
590                               .addDef(LUiReg)
591                               .addGlobalAddress(GVal);
592       LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI);
593       if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
594         return false;
595 
596       MachineInstr *ADDiu =
597           BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
598               .addDef(I.getOperand(0).getReg())
599               .addUse(LUiReg)
600               .addGlobalAddress(GVal);
601       ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
602       if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
603         return false;
604     }
605     I.eraseFromParent();
606     return true;
607   }
608   case G_JUMP_TABLE: {
609     if (MF.getTarget().isPositionIndependent()) {
610       MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
611                .addDef(I.getOperand(0).getReg())
612                .addReg(MF.getInfo<MipsFunctionInfo>()
613                            ->getGlobalBaseRegForGlobalISel())
614                .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT)
615                .addMemOperand(
616                    MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF),
617                                            MachineMemOperand::MOLoad, 4, 4));
618     } else {
619       MI =
620           BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
621               .addDef(I.getOperand(0).getReg())
622               .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI);
623     }
624     break;
625   }
626   case G_ICMP: {
627     struct Instr {
628       unsigned Opcode;
629       Register Def, LHS, RHS;
630       Instr(unsigned Opcode, Register Def, Register LHS, Register RHS)
631           : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
632 
633       bool hasImm() const {
634         if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
635           return true;
636         return false;
637       }
638     };
639 
640     SmallVector<struct Instr, 2> Instructions;
641     Register ICMPReg = I.getOperand(0).getReg();
642     Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
643     Register LHS = I.getOperand(2).getReg();
644     Register RHS = I.getOperand(3).getReg();
645     CmpInst::Predicate Cond =
646         static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
647 
648     switch (Cond) {
649     case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
650       Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
651       Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
652       break;
653     case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
654       Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
655       Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
656       break;
657     case CmpInst::ICMP_UGT: // LHS >  RHS -> RHS < LHS
658       Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
659       break;
660     case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
661       Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
662       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
663       break;
664     case CmpInst::ICMP_ULT: // LHS <  RHS -> LHS < RHS
665       Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
666       break;
667     case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
668       Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
669       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
670       break;
671     case CmpInst::ICMP_SGT: // LHS >  RHS -> RHS < LHS
672       Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
673       break;
674     case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
675       Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
676       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
677       break;
678     case CmpInst::ICMP_SLT: // LHS <  RHS -> LHS < RHS
679       Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
680       break;
681     case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
682       Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
683       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
684       break;
685     default:
686       return false;
687     }
688 
689     MachineIRBuilder B(I);
690     for (const struct Instr &Instruction : Instructions) {
691       MachineInstrBuilder MIB = B.buildInstr(
692           Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
693 
694       if (Instruction.hasImm())
695         MIB.addImm(Instruction.RHS);
696       else
697         MIB.addUse(Instruction.RHS);
698 
699       if (!MIB.constrainAllUses(TII, TRI, RBI))
700         return false;
701     }
702 
703     I.eraseFromParent();
704     return true;
705   }
706   case G_FCMP: {
707     unsigned MipsFCMPCondCode;
708     bool isLogicallyNegated;
709     switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
710                 I.getOperand(1).getPredicate())) {
711     case CmpInst::FCMP_UNO: // Unordered
712     case CmpInst::FCMP_ORD: // Ordered (OR)
713       MipsFCMPCondCode = Mips::FCOND_UN;
714       isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
715       break;
716     case CmpInst::FCMP_OEQ: // Equal
717     case CmpInst::FCMP_UNE: // Not Equal (NEQ)
718       MipsFCMPCondCode = Mips::FCOND_OEQ;
719       isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
720       break;
721     case CmpInst::FCMP_UEQ: // Unordered or Equal
722     case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
723       MipsFCMPCondCode = Mips::FCOND_UEQ;
724       isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
725       break;
726     case CmpInst::FCMP_OLT: // Ordered or Less Than
727     case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
728       MipsFCMPCondCode = Mips::FCOND_OLT;
729       isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
730       break;
731     case CmpInst::FCMP_ULT: // Unordered or Less Than
732     case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
733       MipsFCMPCondCode = Mips::FCOND_ULT;
734       isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
735       break;
736     case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
737     case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
738       MipsFCMPCondCode = Mips::FCOND_OLE;
739       isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
740       break;
741     case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
742     case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
743       MipsFCMPCondCode = Mips::FCOND_ULE;
744       isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
745       break;
746     default:
747       return false;
748     }
749 
750     // Default compare result in gpr register will be `true`.
751     // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
752     // using MOVF_I. When orignal predicate (Cond) is logically negated
753     // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
754     unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
755 
756     Register TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
757     BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
758         .addDef(TrueInReg)
759         .addUse(Mips::ZERO)
760         .addImm(1);
761 
762     unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
763     unsigned FCMPOpcode =
764         Size == 32 ? Mips::FCMP_S32
765                    : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
766     MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
767                              .addUse(I.getOperand(2).getReg())
768                              .addUse(I.getOperand(3).getReg())
769                              .addImm(MipsFCMPCondCode);
770     if (!constrainSelectedInstRegOperands(*FCMP, TII, TRI, RBI))
771       return false;
772 
773     MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
774                              .addDef(I.getOperand(0).getReg())
775                              .addUse(Mips::ZERO)
776                              .addUse(Mips::FCC0)
777                              .addUse(TrueInReg);
778     if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
779       return false;
780 
781     I.eraseFromParent();
782     return true;
783   }
784   case G_FENCE: {
785     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
786     break;
787   }
788   case G_VASTART: {
789     MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
790     int FI = FuncInfo->getVarArgsFrameIndex();
791 
792     Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
793     MachineInstr *LEA_ADDiu =
794         BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
795             .addDef(LeaReg)
796             .addFrameIndex(FI)
797             .addImm(0);
798     if (!constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI))
799       return false;
800 
801     MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
802                               .addUse(LeaReg)
803                               .addUse(I.getOperand(0).getReg())
804                               .addImm(0);
805     if (!constrainSelectedInstRegOperands(*Store, TII, TRI, RBI))
806       return false;
807 
808     I.eraseFromParent();
809     return true;
810   }
811   default:
812     return false;
813   }
814 
815   I.eraseFromParent();
816   return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
817 }
818 
819 namespace llvm {
820 InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM,
821                                                    MipsSubtarget &Subtarget,
822                                                    MipsRegisterBankInfo &RBI) {
823   return new MipsInstructionSelector(TM, Subtarget, RBI);
824 }
825 } // end namespace llvm
826