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 
21 #define DEBUG_TYPE "mips-isel"
22 
23 using namespace llvm;
24 
25 namespace {
26 
27 #define GET_GLOBALISEL_PREDICATE_BITSET
28 #include "MipsGenGlobalISel.inc"
29 #undef GET_GLOBALISEL_PREDICATE_BITSET
30 
31 class MipsInstructionSelector : public InstructionSelector {
32 public:
33   MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI,
34                           const MipsRegisterBankInfo &RBI);
35 
36   bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
37   static const char *getName() { return DEBUG_TYPE; }
38 
39 private:
40   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
41   bool materialize32BitImm(unsigned DestReg, APInt Imm,
42                            MachineIRBuilder &B) const;
43   bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
44 
45   const MipsTargetMachine &TM;
46   const MipsSubtarget &STI;
47   const MipsInstrInfo &TII;
48   const MipsRegisterInfo &TRI;
49   const MipsRegisterBankInfo &RBI;
50 
51 #define GET_GLOBALISEL_PREDICATES_DECL
52 #include "MipsGenGlobalISel.inc"
53 #undef GET_GLOBALISEL_PREDICATES_DECL
54 
55 #define GET_GLOBALISEL_TEMPORARIES_DECL
56 #include "MipsGenGlobalISel.inc"
57 #undef GET_GLOBALISEL_TEMPORARIES_DECL
58 };
59 
60 } // end anonymous namespace
61 
62 #define GET_GLOBALISEL_IMPL
63 #include "MipsGenGlobalISel.inc"
64 #undef GET_GLOBALISEL_IMPL
65 
66 MipsInstructionSelector::MipsInstructionSelector(
67     const MipsTargetMachine &TM, const MipsSubtarget &STI,
68     const MipsRegisterBankInfo &RBI)
69     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
70       TRI(*STI.getRegisterInfo()), RBI(RBI),
71 
72 #define GET_GLOBALISEL_PREDICATES_INIT
73 #include "MipsGenGlobalISel.inc"
74 #undef GET_GLOBALISEL_PREDICATES_INIT
75 #define GET_GLOBALISEL_TEMPORARIES_INIT
76 #include "MipsGenGlobalISel.inc"
77 #undef GET_GLOBALISEL_TEMPORARIES_INIT
78 {
79 }
80 
81 bool MipsInstructionSelector::selectCopy(MachineInstr &I,
82                                          MachineRegisterInfo &MRI) const {
83   unsigned DstReg = I.getOperand(0).getReg();
84   if (TargetRegisterInfo::isPhysicalRegister(DstReg))
85     return true;
86 
87   const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
88   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
89 
90   const TargetRegisterClass *RC = &Mips::GPR32RegClass;
91   if (RegBank->getID() == Mips::FPRBRegBankID) {
92     if (DstSize == 32)
93       RC = &Mips::FGR32RegClass;
94     else if (DstSize == 64)
95       RC = STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
96     else
97       llvm_unreachable("Unsupported destination size");
98   }
99   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
100     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
101                       << " operand\n");
102     return false;
103   }
104   return true;
105 }
106 
107 bool MipsInstructionSelector::materialize32BitImm(unsigned DestReg, APInt Imm,
108                                                   MachineIRBuilder &B) const {
109   assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
110   // Ori zero extends immediate. Used for values with zeros in high 16 bits.
111   if (Imm.getHiBits(16).isNullValue()) {
112     MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Mips::ZERO})
113                              .addImm(Imm.getLoBits(16).getLimitedValue());
114     return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
115   }
116   // Lui places immediate in high 16 bits and sets low 16 bits to zero.
117   if (Imm.getLoBits(16).isNullValue()) {
118     MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {})
119                              .addImm(Imm.getHiBits(16).getLimitedValue());
120     return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
121   }
122   // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
123   if (Imm.isSignedIntN(16)) {
124     MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Mips::ZERO})
125                              .addImm(Imm.getLoBits(16).getLimitedValue());
126     return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
127   }
128   // Values that cannot be materialized with single immediate instruction.
129   unsigned LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
130   MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {})
131                           .addImm(Imm.getHiBits(16).getLimitedValue());
132   MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
133                           .addImm(Imm.getLoBits(16).getLimitedValue());
134   if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
135     return false;
136   if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
137     return false;
138   return true;
139 }
140 
141 /// Returning Opc indicates that we failed to select MIPS instruction opcode.
142 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes) {
143   if (Opc == TargetOpcode::G_STORE)
144     switch (MemSizeInBytes) {
145     case 4:
146       return Mips::SW;
147     case 2:
148       return Mips::SH;
149     case 1:
150       return Mips::SB;
151     default:
152       return Opc;
153     }
154   else
155     // Unspecified extending load is selected into zeroExtending load.
156     switch (MemSizeInBytes) {
157     case 4:
158       return Mips::LW;
159     case 2:
160       return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
161     case 1:
162       return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
163     default:
164       return Opc;
165     }
166 }
167 
168 bool MipsInstructionSelector::select(MachineInstr &I,
169                                      CodeGenCoverage &CoverageInfo) const {
170 
171   MachineBasicBlock &MBB = *I.getParent();
172   MachineFunction &MF = *MBB.getParent();
173   MachineRegisterInfo &MRI = MF.getRegInfo();
174 
175   if (!isPreISelGenericOpcode(I.getOpcode())) {
176     if (I.isCopy())
177       return selectCopy(I, MRI);
178 
179     return true;
180   }
181 
182   if (I.getOpcode() == Mips::G_MUL) {
183     MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
184                             .add(I.getOperand(0))
185                             .add(I.getOperand(1))
186                             .add(I.getOperand(2));
187     if (!constrainSelectedInstRegOperands(*Mul, TII, TRI, RBI))
188       return false;
189     Mul->getOperand(3).setIsDead(true);
190     Mul->getOperand(4).setIsDead(true);
191 
192     I.eraseFromParent();
193     return true;
194   }
195 
196   if (selectImpl(I, CoverageInfo))
197     return true;
198 
199   MachineInstr *MI = nullptr;
200   using namespace TargetOpcode;
201 
202   switch (I.getOpcode()) {
203   case G_UMULH: {
204     unsigned PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
205     MachineInstr *PseudoMULTu, *PseudoMove;
206 
207     PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu))
208                       .addDef(PseudoMULTuReg)
209                       .add(I.getOperand(1))
210                       .add(I.getOperand(2));
211     if (!constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI))
212       return false;
213 
214     PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI))
215                      .addDef(I.getOperand(0).getReg())
216                      .addUse(PseudoMULTuReg);
217     if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
218       return false;
219 
220     I.eraseFromParent();
221     return true;
222   }
223   case G_GEP: {
224     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
225              .add(I.getOperand(0))
226              .add(I.getOperand(1))
227              .add(I.getOperand(2));
228     break;
229   }
230   case G_FRAME_INDEX: {
231     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
232              .add(I.getOperand(0))
233              .add(I.getOperand(1))
234              .addImm(0);
235     break;
236   }
237   case G_BRCOND: {
238     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::BNE))
239              .add(I.getOperand(0))
240              .addUse(Mips::ZERO)
241              .add(I.getOperand(1));
242     break;
243   }
244   case G_PHI: {
245     const unsigned DestReg = I.getOperand(0).getReg();
246     const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
247     const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
248 
249     if (DestRegBank != Mips::GPRBRegBankID || OpSize != 32)
250       return false;
251 
252     const TargetRegisterClass *DefRC = &Mips::GPR32RegClass;
253     I.setDesc(TII.get(TargetOpcode::PHI));
254     return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
255   }
256   case G_STORE:
257   case G_LOAD:
258   case G_ZEXTLOAD:
259   case G_SEXTLOAD: {
260     const unsigned DestReg = I.getOperand(0).getReg();
261     const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
262     const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
263     const unsigned OpMemSizeInBytes = (*I.memoperands_begin())->getSize();
264 
265     if (DestRegBank != Mips::GPRBRegBankID || OpSize != 32)
266       return false;
267 
268     const unsigned NewOpc =
269         selectLoadStoreOpCode(I.getOpcode(), OpMemSizeInBytes);
270     if (NewOpc == I.getOpcode())
271       return false;
272 
273     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
274              .add(I.getOperand(0))
275              .add(I.getOperand(1))
276              .addImm(0)
277              .addMemOperand(*I.memoperands_begin());
278     break;
279   }
280   case G_UDIV:
281   case G_UREM:
282   case G_SDIV:
283   case G_SREM: {
284     unsigned HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
285     bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV;
286     bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV;
287 
288     MachineInstr *PseudoDIV, *PseudoMove;
289     PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
290                         TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
291                     .addDef(HILOReg)
292                     .add(I.getOperand(1))
293                     .add(I.getOperand(2));
294     if (!constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI))
295       return false;
296 
297     PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
298                          TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
299                      .addDef(I.getOperand(0).getReg())
300                      .addUse(HILOReg);
301     if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
302       return false;
303 
304     I.eraseFromParent();
305     return true;
306   }
307   case G_SELECT: {
308     // Handle operands with pointer type.
309     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
310              .add(I.getOperand(0))
311              .add(I.getOperand(2))
312              .add(I.getOperand(1))
313              .add(I.getOperand(3));
314     break;
315   }
316   case G_CONSTANT: {
317     MachineIRBuilder B(I);
318     if (!materialize32BitImm(I.getOperand(0).getReg(),
319                              I.getOperand(1).getCImm()->getValue(), B))
320       return false;
321 
322     I.eraseFromParent();
323     return true;
324   }
325   case G_FCONSTANT: {
326     const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
327     APInt APImm = FPimm.bitcastToAPInt();
328     unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
329 
330     if (Size == 32) {
331       unsigned GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
332       MachineIRBuilder B(I);
333       if (!materialize32BitImm(GPRReg, APImm, B))
334         return false;
335 
336       MachineInstrBuilder MTC1 =
337           B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
338       if (!MTC1.constrainAllUses(TII, TRI, RBI))
339         return false;
340     }
341     if (Size == 64) {
342       unsigned GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
343       unsigned GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
344       MachineIRBuilder B(I);
345       if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
346         return false;
347       if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
348         return false;
349 
350       MachineInstrBuilder PairF64 = B.buildInstr(
351           STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64,
352           {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
353       if (!PairF64.constrainAllUses(TII, TRI, RBI))
354         return false;
355     }
356 
357     I.eraseFromParent();
358     return true;
359   }
360   case G_FABS: {
361     unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
362     unsigned FABSOpcode =
363         Size == 32 ? Mips::FABS_S
364                    : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
365     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
366              .add(I.getOperand(0))
367              .add(I.getOperand(1));
368     break;
369   }
370   case G_GLOBAL_VALUE: {
371     const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
372     if (MF.getTarget().isPositionIndependent()) {
373       MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
374                                 .addDef(I.getOperand(0).getReg())
375                                 .addReg(MF.getInfo<MipsFunctionInfo>()
376                                             ->getGlobalBaseRegForGlobalISel())
377                                 .addGlobalAddress(GVal);
378       // Global Values that don't have local linkage are handled differently
379       // when they are part of call sequence. MipsCallLowering::lowerCall
380       // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
381       // MO_GOT_CALL flag when Callee doesn't have local linkage.
382       if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
383         LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL);
384       else
385         LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT);
386       LWGOT->addMemOperand(
387           MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF),
388                                       MachineMemOperand::MOLoad, 4, 4));
389       if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI))
390         return false;
391 
392       if (GVal->hasLocalLinkage()) {
393         unsigned LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
394         LWGOT->getOperand(0).setReg(LWGOTDef);
395 
396         MachineInstr *ADDiu =
397             BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
398                 .addDef(I.getOperand(0).getReg())
399                 .addReg(LWGOTDef)
400                 .addGlobalAddress(GVal);
401         ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
402         if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
403           return false;
404       }
405     } else {
406       unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
407 
408       MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
409                               .addDef(LUiReg)
410                               .addGlobalAddress(GVal);
411       LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI);
412       if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
413         return false;
414 
415       MachineInstr *ADDiu =
416           BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
417               .addDef(I.getOperand(0).getReg())
418               .addUse(LUiReg)
419               .addGlobalAddress(GVal);
420       ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
421       if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
422         return false;
423     }
424     I.eraseFromParent();
425     return true;
426   }
427   case G_ICMP: {
428     struct Instr {
429       unsigned Opcode, Def, LHS, RHS;
430       Instr(unsigned Opcode, unsigned Def, unsigned LHS, unsigned RHS)
431           : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
432 
433       bool hasImm() const {
434         if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
435           return true;
436         return false;
437       }
438     };
439 
440     SmallVector<struct Instr, 2> Instructions;
441     unsigned ICMPReg = I.getOperand(0).getReg();
442     unsigned Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
443     unsigned LHS = I.getOperand(2).getReg();
444     unsigned RHS = I.getOperand(3).getReg();
445     CmpInst::Predicate Cond =
446         static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
447 
448     switch (Cond) {
449     case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
450       Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
451       Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
452       break;
453     case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
454       Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
455       Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
456       break;
457     case CmpInst::ICMP_UGT: // LHS >  RHS -> RHS < LHS
458       Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
459       break;
460     case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
461       Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
462       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
463       break;
464     case CmpInst::ICMP_ULT: // LHS <  RHS -> LHS < RHS
465       Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
466       break;
467     case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
468       Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
469       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
470       break;
471     case CmpInst::ICMP_SGT: // LHS >  RHS -> RHS < LHS
472       Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
473       break;
474     case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
475       Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
476       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
477       break;
478     case CmpInst::ICMP_SLT: // LHS <  RHS -> LHS < RHS
479       Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
480       break;
481     case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
482       Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
483       Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
484       break;
485     default:
486       return false;
487     }
488 
489     MachineIRBuilder B(I);
490     for (const struct Instr &Instruction : Instructions) {
491       MachineInstrBuilder MIB = B.buildInstr(
492           Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
493 
494       if (Instruction.hasImm())
495         MIB.addImm(Instruction.RHS);
496       else
497         MIB.addUse(Instruction.RHS);
498 
499       if (!MIB.constrainAllUses(TII, TRI, RBI))
500         return false;
501     }
502 
503     I.eraseFromParent();
504     return true;
505   }
506   case G_FCMP: {
507     unsigned MipsFCMPCondCode;
508     bool isLogicallyNegated;
509     switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
510                 I.getOperand(1).getPredicate())) {
511     case CmpInst::FCMP_UNO: // Unordered
512     case CmpInst::FCMP_ORD: // Ordered (OR)
513       MipsFCMPCondCode = Mips::FCOND_UN;
514       isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
515       break;
516     case CmpInst::FCMP_OEQ: // Equal
517     case CmpInst::FCMP_UNE: // Not Equal (NEQ)
518       MipsFCMPCondCode = Mips::FCOND_OEQ;
519       isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
520       break;
521     case CmpInst::FCMP_UEQ: // Unordered or Equal
522     case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
523       MipsFCMPCondCode = Mips::FCOND_UEQ;
524       isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
525       break;
526     case CmpInst::FCMP_OLT: // Ordered or Less Than
527     case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
528       MipsFCMPCondCode = Mips::FCOND_OLT;
529       isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
530       break;
531     case CmpInst::FCMP_ULT: // Unordered or Less Than
532     case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
533       MipsFCMPCondCode = Mips::FCOND_ULT;
534       isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
535       break;
536     case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
537     case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
538       MipsFCMPCondCode = Mips::FCOND_OLE;
539       isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
540       break;
541     case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
542     case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
543       MipsFCMPCondCode = Mips::FCOND_ULE;
544       isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
545       break;
546     default:
547       return false;
548     }
549 
550     // Default compare result in gpr register will be `true`.
551     // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
552     // using MOVF_I. When orignal predicate (Cond) is logically negated
553     // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
554     unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
555 
556     unsigned TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
557     BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
558         .addDef(TrueInReg)
559         .addUse(Mips::ZERO)
560         .addImm(1);
561 
562     unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
563     unsigned FCMPOpcode =
564         Size == 32 ? Mips::FCMP_S32
565                    : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
566     MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
567                              .addUse(I.getOperand(2).getReg())
568                              .addUse(I.getOperand(3).getReg())
569                              .addImm(MipsFCMPCondCode);
570     if (!constrainSelectedInstRegOperands(*FCMP, TII, TRI, RBI))
571       return false;
572 
573     MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
574                              .addDef(I.getOperand(0).getReg())
575                              .addUse(Mips::ZERO)
576                              .addUse(Mips::FCC0)
577                              .addUse(TrueInReg);
578     if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
579       return false;
580 
581     I.eraseFromParent();
582     return true;
583   }
584   default:
585     return false;
586   }
587 
588   I.eraseFromParent();
589   return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
590 }
591 
592 namespace llvm {
593 InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM,
594                                                    MipsSubtarget &Subtarget,
595                                                    MipsRegisterBankInfo &RBI) {
596   return new MipsInstructionSelector(TM, Subtarget, RBI);
597 }
598 } // end namespace llvm
599