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