1 //===- MipsInstructionSelector.cpp ------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 /// This file implements the targeting of the InstructionSelector class for
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
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"
21 #define DEBUG_TYPE "mips-isel"
27 #define GET_GLOBALISEL_PREDICATE_BITSET
28 #include "MipsGenGlobalISel.inc"
29 #undef GET_GLOBALISEL_PREDICATE_BITSET
31 class MipsInstructionSelector
: public InstructionSelector
{
33 MipsInstructionSelector(const MipsTargetMachine
&TM
, const MipsSubtarget
&STI
,
34 const MipsRegisterBankInfo
&RBI
);
36 bool select(MachineInstr
&I
, CodeGenCoverage
&CoverageInfo
) const override
;
37 static const char *getName() { return DEBUG_TYPE
; }
40 bool selectImpl(MachineInstr
&I
, CodeGenCoverage
&CoverageInfo
) const;
41 bool materialize32BitImm(Register DestReg
, APInt Imm
,
42 MachineIRBuilder
&B
) const;
43 bool selectCopy(MachineInstr
&I
, MachineRegisterInfo
&MRI
) const;
44 const TargetRegisterClass
*
45 getRegClassForTypeOnBank(unsigned OpSize
, const RegisterBank
&RB
,
46 const RegisterBankInfo
&RBI
) const;
48 const MipsTargetMachine
&TM
;
49 const MipsSubtarget
&STI
;
50 const MipsInstrInfo
&TII
;
51 const MipsRegisterInfo
&TRI
;
52 const MipsRegisterBankInfo
&RBI
;
54 #define GET_GLOBALISEL_PREDICATES_DECL
55 #include "MipsGenGlobalISel.inc"
56 #undef GET_GLOBALISEL_PREDICATES_DECL
58 #define GET_GLOBALISEL_TEMPORARIES_DECL
59 #include "MipsGenGlobalISel.inc"
60 #undef GET_GLOBALISEL_TEMPORARIES_DECL
63 } // end anonymous namespace
65 #define GET_GLOBALISEL_IMPL
66 #include "MipsGenGlobalISel.inc"
67 #undef GET_GLOBALISEL_IMPL
69 MipsInstructionSelector::MipsInstructionSelector(
70 const MipsTargetMachine
&TM
, const MipsSubtarget
&STI
,
71 const MipsRegisterBankInfo
&RBI
)
72 : InstructionSelector(), TM(TM
), STI(STI
), TII(*STI
.getInstrInfo()),
73 TRI(*STI
.getRegisterInfo()), RBI(RBI
),
75 #define GET_GLOBALISEL_PREDICATES_INIT
76 #include "MipsGenGlobalISel.inc"
77 #undef GET_GLOBALISEL_PREDICATES_INIT
78 #define GET_GLOBALISEL_TEMPORARIES_INIT
79 #include "MipsGenGlobalISel.inc"
80 #undef GET_GLOBALISEL_TEMPORARIES_INIT
84 bool MipsInstructionSelector::selectCopy(MachineInstr
&I
,
85 MachineRegisterInfo
&MRI
) const {
86 Register DstReg
= I
.getOperand(0).getReg();
87 if (TargetRegisterInfo::isPhysicalRegister(DstReg
))
90 const RegisterBank
*RegBank
= RBI
.getRegBank(DstReg
, MRI
, TRI
);
91 const unsigned DstSize
= MRI
.getType(DstReg
).getSizeInBits();
93 const TargetRegisterClass
*RC
= &Mips::GPR32RegClass
;
94 if (RegBank
->getID() == Mips::FPRBRegBankID
) {
96 RC
= &Mips::FGR32RegClass
;
97 else if (DstSize
== 64)
98 RC
= STI
.isFP64bit() ? &Mips::FGR64RegClass
: &Mips::AFGR64RegClass
;
100 llvm_unreachable("Unsupported destination size");
102 if (!RBI
.constrainGenericRegister(DstReg
, *RC
, MRI
)) {
103 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII
.getName(I
.getOpcode())
110 const TargetRegisterClass
*MipsInstructionSelector::getRegClassForTypeOnBank(
111 unsigned OpSize
, const RegisterBank
&RB
,
112 const RegisterBankInfo
&RBI
) const {
113 if (RB
.getID() == Mips::GPRBRegBankID
)
114 return &Mips::GPR32RegClass
;
116 if (RB
.getID() == Mips::FPRBRegBankID
)
118 ? &Mips::FGR32RegClass
119 : STI
.hasMips32r6() || STI
.isFP64bit() ? &Mips::FGR64RegClass
120 : &Mips::AFGR64RegClass
;
122 llvm_unreachable("getRegClassForTypeOnBank can't find register class.");
126 bool MipsInstructionSelector::materialize32BitImm(Register DestReg
, APInt Imm
,
127 MachineIRBuilder
&B
) const {
128 assert(Imm
.getBitWidth() == 32 && "Unsupported immediate size.");
129 // Ori zero extends immediate. Used for values with zeros in high 16 bits.
130 if (Imm
.getHiBits(16).isNullValue()) {
131 MachineInstr
*Inst
= B
.buildInstr(Mips::ORi
, {DestReg
}, {Register(Mips::ZERO
)})
132 .addImm(Imm
.getLoBits(16).getLimitedValue());
133 return constrainSelectedInstRegOperands(*Inst
, TII
, TRI
, RBI
);
135 // Lui places immediate in high 16 bits and sets low 16 bits to zero.
136 if (Imm
.getLoBits(16).isNullValue()) {
137 MachineInstr
*Inst
= B
.buildInstr(Mips::LUi
, {DestReg
}, {})
138 .addImm(Imm
.getHiBits(16).getLimitedValue());
139 return constrainSelectedInstRegOperands(*Inst
, TII
, TRI
, RBI
);
141 // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
142 if (Imm
.isSignedIntN(16)) {
143 MachineInstr
*Inst
= B
.buildInstr(Mips::ADDiu
, {DestReg
}, {Register(Mips::ZERO
)})
144 .addImm(Imm
.getLoBits(16).getLimitedValue());
145 return constrainSelectedInstRegOperands(*Inst
, TII
, TRI
, RBI
);
147 // Values that cannot be materialized with single immediate instruction.
148 Register LUiReg
= B
.getMRI()->createVirtualRegister(&Mips::GPR32RegClass
);
149 MachineInstr
*LUi
= B
.buildInstr(Mips::LUi
, {LUiReg
}, {})
150 .addImm(Imm
.getHiBits(16).getLimitedValue());
151 MachineInstr
*ORi
= B
.buildInstr(Mips::ORi
, {DestReg
}, {LUiReg
})
152 .addImm(Imm
.getLoBits(16).getLimitedValue());
153 if (!constrainSelectedInstRegOperands(*LUi
, TII
, TRI
, RBI
))
155 if (!constrainSelectedInstRegOperands(*ORi
, TII
, TRI
, RBI
))
160 /// Returning Opc indicates that we failed to select MIPS instruction opcode.
161 static unsigned selectLoadStoreOpCode(unsigned Opc
, unsigned MemSizeInBytes
,
162 unsigned RegBank
, bool isFP64
) {
163 bool isStore
= Opc
== TargetOpcode::G_STORE
;
164 if (RegBank
== Mips::GPRBRegBankID
) {
166 switch (MemSizeInBytes
) {
177 // Unspecified extending load is selected into zeroExtending load.
178 switch (MemSizeInBytes
) {
182 return Opc
== TargetOpcode::G_SEXTLOAD
? Mips::LH
: Mips::LHu
;
184 return Opc
== TargetOpcode::G_SEXTLOAD
? Mips::LB
: Mips::LBu
;
190 if (RegBank
== Mips::FPRBRegBankID
) {
191 switch (MemSizeInBytes
) {
193 return isStore
? Mips::SWC1
: Mips::LWC1
;
196 return isStore
? Mips::SDC164
: Mips::LDC164
;
198 return isStore
? Mips::SDC1
: Mips::LDC1
;
206 bool MipsInstructionSelector::select(MachineInstr
&I
,
207 CodeGenCoverage
&CoverageInfo
) const {
209 MachineBasicBlock
&MBB
= *I
.getParent();
210 MachineFunction
&MF
= *MBB
.getParent();
211 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
213 if (!isPreISelGenericOpcode(I
.getOpcode())) {
215 return selectCopy(I
, MRI
);
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
))
227 Mul
->getOperand(3).setIsDead(true);
228 Mul
->getOperand(4).setIsDead(true);
234 if (selectImpl(I
, CoverageInfo
))
237 MachineInstr
*MI
= nullptr;
238 using namespace TargetOpcode
;
240 switch (I
.getOpcode()) {
242 Register PseudoMULTuReg
= MRI
.createVirtualRegister(&Mips::ACC64RegClass
);
243 MachineInstr
*PseudoMULTu
, *PseudoMove
;
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
))
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
))
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));
270 I
.setDesc(TII
.get(COPY
));
271 return selectCopy(I
, MRI
);
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))
281 MI
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::BNE
))
282 .add(I
.getOperand(0))
284 .add(I
.getOperand(1));
288 const Register DestReg
= I
.getOperand(0).getReg();
289 const unsigned OpSize
= MRI
.getType(DestReg
).getSizeInBits();
291 const TargetRegisterClass
*DefRC
= nullptr;
292 if (TargetRegisterInfo::isPhysicalRegister(DestReg
))
293 DefRC
= TRI
.getRegClass(DestReg
);
295 DefRC
= getRegClassForTypeOnBank(OpSize
,
296 *RBI
.getRegBank(DestReg
, MRI
, TRI
), RBI
);
298 I
.setDesc(TII
.get(TargetOpcode::PHI
));
299 return RBI
.constrainGenericRegister(DestReg
, *DefRC
, MRI
);
305 const Register DestReg
= I
.getOperand(0).getReg();
306 const unsigned DestRegBank
= RBI
.getRegBank(DestReg
, MRI
, TRI
)->getID();
307 const unsigned OpSize
= MRI
.getType(DestReg
).getSizeInBits();
308 const unsigned OpMemSizeInBytes
= (*I
.memoperands_begin())->getSize();
310 if (DestRegBank
== Mips::GPRBRegBankID
&& OpSize
!= 32)
313 if (DestRegBank
== Mips::FPRBRegBankID
&& OpSize
!= 32 && OpSize
!= 64)
316 const unsigned NewOpc
= selectLoadStoreOpCode(
317 I
.getOpcode(), OpMemSizeInBytes
, DestRegBank
, STI
.isFP64bit());
318 if (NewOpc
== I
.getOpcode())
321 MI
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(NewOpc
))
322 .add(I
.getOperand(0))
323 .add(I
.getOperand(1))
325 .addMemOperand(*I
.memoperands_begin());
332 Register HILOReg
= MRI
.createVirtualRegister(&Mips::ACC64RegClass
);
333 bool IsSigned
= I
.getOpcode() == G_SREM
|| I
.getOpcode() == G_SDIV
;
334 bool IsDiv
= I
.getOpcode() == G_UDIV
|| I
.getOpcode() == G_SDIV
;
336 MachineInstr
*PseudoDIV
, *PseudoMove
;
337 PseudoDIV
= BuildMI(MBB
, I
, I
.getDebugLoc(),
338 TII
.get(IsSigned
? Mips::PseudoSDIV
: Mips::PseudoUDIV
))
340 .add(I
.getOperand(1))
341 .add(I
.getOperand(2));
342 if (!constrainSelectedInstRegOperands(*PseudoDIV
, TII
, TRI
, RBI
))
345 PseudoMove
= BuildMI(MBB
, I
, I
.getDebugLoc(),
346 TII
.get(IsDiv
? Mips::PseudoMFLO
: Mips::PseudoMFHI
))
347 .addDef(I
.getOperand(0).getReg())
349 if (!constrainSelectedInstRegOperands(*PseudoMove
, TII
, TRI
, RBI
))
356 // Handle operands with pointer type.
357 MI
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::MOVN_I_I
))
358 .add(I
.getOperand(0))
359 .add(I
.getOperand(2))
360 .add(I
.getOperand(1))
361 .add(I
.getOperand(3));
365 MachineIRBuilder
B(I
);
366 if (!materialize32BitImm(I
.getOperand(0).getReg(),
367 I
.getOperand(1).getCImm()->getValue(), B
))
374 const APFloat
&FPimm
= I
.getOperand(1).getFPImm()->getValueAPF();
375 APInt APImm
= FPimm
.bitcastToAPInt();
376 unsigned Size
= MRI
.getType(I
.getOperand(0).getReg()).getSizeInBits();
379 Register GPRReg
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
380 MachineIRBuilder
B(I
);
381 if (!materialize32BitImm(GPRReg
, APImm
, B
))
384 MachineInstrBuilder MTC1
=
385 B
.buildInstr(Mips::MTC1
, {I
.getOperand(0).getReg()}, {GPRReg
});
386 if (!MTC1
.constrainAllUses(TII
, TRI
, RBI
))
390 Register GPRRegHigh
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
391 Register GPRRegLow
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
392 MachineIRBuilder
B(I
);
393 if (!materialize32BitImm(GPRRegHigh
, APImm
.getHiBits(32).trunc(32), B
))
395 if (!materialize32BitImm(GPRRegLow
, APImm
.getLoBits(32).trunc(32), B
))
398 MachineInstrBuilder PairF64
= B
.buildInstr(
399 STI
.isFP64bit() ? Mips::BuildPairF64_64
: Mips::BuildPairF64
,
400 {I
.getOperand(0).getReg()}, {GPRRegLow
, GPRRegHigh
});
401 if (!PairF64
.constrainAllUses(TII
, TRI
, RBI
))
409 unsigned Size
= MRI
.getType(I
.getOperand(0).getReg()).getSizeInBits();
410 unsigned FABSOpcode
=
411 Size
== 32 ? Mips::FABS_S
412 : STI
.isFP64bit() ? Mips::FABS_D64
: Mips::FABS_D32
;
413 MI
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(FABSOpcode
))
414 .add(I
.getOperand(0))
415 .add(I
.getOperand(1));
419 unsigned FromSize
= MRI
.getType(I
.getOperand(1).getReg()).getSizeInBits();
420 unsigned ToSize
= MRI
.getType(I
.getOperand(0).getReg()).getSizeInBits();
422 assert((ToSize
== 32) && "Unsupported integer size for G_FPTOSI");
423 assert((FromSize
== 32 || FromSize
== 64) &&
424 "Unsupported floating point size for G_FPTOSI");
428 Opcode
= Mips::TRUNC_W_S
;
430 Opcode
= STI
.isFP64bit() ? Mips::TRUNC_W_D64
: Mips::TRUNC_W_D32
;
431 unsigned ResultInFPR
= MRI
.createVirtualRegister(&Mips::FGR32RegClass
);
432 MachineInstr
*Trunc
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Opcode
))
434 .addUse(I
.getOperand(1).getReg());
435 if (!constrainSelectedInstRegOperands(*Trunc
, TII
, TRI
, RBI
))
438 MachineInstr
*Move
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::MFC1
))
439 .addDef(I
.getOperand(0).getReg())
440 .addUse(ResultInFPR
);
441 if (!constrainSelectedInstRegOperands(*Move
, TII
, TRI
, RBI
))
447 case G_GLOBAL_VALUE
: {
448 const llvm::GlobalValue
*GVal
= I
.getOperand(1).getGlobal();
449 if (MF
.getTarget().isPositionIndependent()) {
450 MachineInstr
*LWGOT
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::LW
))
451 .addDef(I
.getOperand(0).getReg())
452 .addReg(MF
.getInfo
<MipsFunctionInfo
>()
453 ->getGlobalBaseRegForGlobalISel())
454 .addGlobalAddress(GVal
);
455 // Global Values that don't have local linkage are handled differently
456 // when they are part of call sequence. MipsCallLowering::lowerCall
457 // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
458 // MO_GOT_CALL flag when Callee doesn't have local linkage.
459 if (I
.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL
)
460 LWGOT
->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL
);
462 LWGOT
->getOperand(2).setTargetFlags(MipsII::MO_GOT
);
463 LWGOT
->addMemOperand(
464 MF
, MF
.getMachineMemOperand(MachinePointerInfo::getGOT(MF
),
465 MachineMemOperand::MOLoad
, 4, 4));
466 if (!constrainSelectedInstRegOperands(*LWGOT
, TII
, TRI
, RBI
))
469 if (GVal
->hasLocalLinkage()) {
470 Register LWGOTDef
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
471 LWGOT
->getOperand(0).setReg(LWGOTDef
);
473 MachineInstr
*ADDiu
=
474 BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::ADDiu
))
475 .addDef(I
.getOperand(0).getReg())
477 .addGlobalAddress(GVal
);
478 ADDiu
->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO
);
479 if (!constrainSelectedInstRegOperands(*ADDiu
, TII
, TRI
, RBI
))
483 Register LUiReg
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
485 MachineInstr
*LUi
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::LUi
))
487 .addGlobalAddress(GVal
);
488 LUi
->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI
);
489 if (!constrainSelectedInstRegOperands(*LUi
, TII
, TRI
, RBI
))
492 MachineInstr
*ADDiu
=
493 BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::ADDiu
))
494 .addDef(I
.getOperand(0).getReg())
496 .addGlobalAddress(GVal
);
497 ADDiu
->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO
);
498 if (!constrainSelectedInstRegOperands(*ADDiu
, TII
, TRI
, RBI
))
507 Register Def
, LHS
, RHS
;
508 Instr(unsigned Opcode
, Register Def
, Register LHS
, Register RHS
)
509 : Opcode(Opcode
), Def(Def
), LHS(LHS
), RHS(RHS
){};
511 bool hasImm() const {
512 if (Opcode
== Mips::SLTiu
|| Opcode
== Mips::XORi
)
518 SmallVector
<struct Instr
, 2> Instructions
;
519 Register ICMPReg
= I
.getOperand(0).getReg();
520 Register Temp
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
521 Register LHS
= I
.getOperand(2).getReg();
522 Register RHS
= I
.getOperand(3).getReg();
523 CmpInst::Predicate Cond
=
524 static_cast<CmpInst::Predicate
>(I
.getOperand(1).getPredicate());
527 case CmpInst::ICMP_EQ
: // LHS == RHS -> (LHS ^ RHS) < 1
528 Instructions
.emplace_back(Mips::XOR
, Temp
, LHS
, RHS
);
529 Instructions
.emplace_back(Mips::SLTiu
, ICMPReg
, Temp
, 1);
531 case CmpInst::ICMP_NE
: // LHS != RHS -> 0 < (LHS ^ RHS)
532 Instructions
.emplace_back(Mips::XOR
, Temp
, LHS
, RHS
);
533 Instructions
.emplace_back(Mips::SLTu
, ICMPReg
, Mips::ZERO
, Temp
);
535 case CmpInst::ICMP_UGT
: // LHS > RHS -> RHS < LHS
536 Instructions
.emplace_back(Mips::SLTu
, ICMPReg
, RHS
, LHS
);
538 case CmpInst::ICMP_UGE
: // LHS >= RHS -> !(LHS < RHS)
539 Instructions
.emplace_back(Mips::SLTu
, Temp
, LHS
, RHS
);
540 Instructions
.emplace_back(Mips::XORi
, ICMPReg
, Temp
, 1);
542 case CmpInst::ICMP_ULT
: // LHS < RHS -> LHS < RHS
543 Instructions
.emplace_back(Mips::SLTu
, ICMPReg
, LHS
, RHS
);
545 case CmpInst::ICMP_ULE
: // LHS <= RHS -> !(RHS < LHS)
546 Instructions
.emplace_back(Mips::SLTu
, Temp
, RHS
, LHS
);
547 Instructions
.emplace_back(Mips::XORi
, ICMPReg
, Temp
, 1);
549 case CmpInst::ICMP_SGT
: // LHS > RHS -> RHS < LHS
550 Instructions
.emplace_back(Mips::SLT
, ICMPReg
, RHS
, LHS
);
552 case CmpInst::ICMP_SGE
: // LHS >= RHS -> !(LHS < RHS)
553 Instructions
.emplace_back(Mips::SLT
, Temp
, LHS
, RHS
);
554 Instructions
.emplace_back(Mips::XORi
, ICMPReg
, Temp
, 1);
556 case CmpInst::ICMP_SLT
: // LHS < RHS -> LHS < RHS
557 Instructions
.emplace_back(Mips::SLT
, ICMPReg
, LHS
, RHS
);
559 case CmpInst::ICMP_SLE
: // LHS <= RHS -> !(RHS < LHS)
560 Instructions
.emplace_back(Mips::SLT
, Temp
, RHS
, LHS
);
561 Instructions
.emplace_back(Mips::XORi
, ICMPReg
, Temp
, 1);
567 MachineIRBuilder
B(I
);
568 for (const struct Instr
&Instruction
: Instructions
) {
569 MachineInstrBuilder MIB
= B
.buildInstr(
570 Instruction
.Opcode
, {Instruction
.Def
}, {Instruction
.LHS
});
572 if (Instruction
.hasImm())
573 MIB
.addImm(Instruction
.RHS
);
575 MIB
.addUse(Instruction
.RHS
);
577 if (!MIB
.constrainAllUses(TII
, TRI
, RBI
))
585 unsigned MipsFCMPCondCode
;
586 bool isLogicallyNegated
;
587 switch (CmpInst::Predicate Cond
= static_cast<CmpInst::Predicate
>(
588 I
.getOperand(1).getPredicate())) {
589 case CmpInst::FCMP_UNO
: // Unordered
590 case CmpInst::FCMP_ORD
: // Ordered (OR)
591 MipsFCMPCondCode
= Mips::FCOND_UN
;
592 isLogicallyNegated
= Cond
!= CmpInst::FCMP_UNO
;
594 case CmpInst::FCMP_OEQ
: // Equal
595 case CmpInst::FCMP_UNE
: // Not Equal (NEQ)
596 MipsFCMPCondCode
= Mips::FCOND_OEQ
;
597 isLogicallyNegated
= Cond
!= CmpInst::FCMP_OEQ
;
599 case CmpInst::FCMP_UEQ
: // Unordered or Equal
600 case CmpInst::FCMP_ONE
: // Ordered or Greater Than or Less Than (OGL)
601 MipsFCMPCondCode
= Mips::FCOND_UEQ
;
602 isLogicallyNegated
= Cond
!= CmpInst::FCMP_UEQ
;
604 case CmpInst::FCMP_OLT
: // Ordered or Less Than
605 case CmpInst::FCMP_UGE
: // Unordered or Greater Than or Equal (UGE)
606 MipsFCMPCondCode
= Mips::FCOND_OLT
;
607 isLogicallyNegated
= Cond
!= CmpInst::FCMP_OLT
;
609 case CmpInst::FCMP_ULT
: // Unordered or Less Than
610 case CmpInst::FCMP_OGE
: // Ordered or Greater Than or Equal (OGE)
611 MipsFCMPCondCode
= Mips::FCOND_ULT
;
612 isLogicallyNegated
= Cond
!= CmpInst::FCMP_ULT
;
614 case CmpInst::FCMP_OLE
: // Ordered or Less Than or Equal
615 case CmpInst::FCMP_UGT
: // Unordered or Greater Than (UGT)
616 MipsFCMPCondCode
= Mips::FCOND_OLE
;
617 isLogicallyNegated
= Cond
!= CmpInst::FCMP_OLE
;
619 case CmpInst::FCMP_ULE
: // Unordered or Less Than or Equal
620 case CmpInst::FCMP_OGT
: // Ordered or Greater Than (OGT)
621 MipsFCMPCondCode
= Mips::FCOND_ULE
;
622 isLogicallyNegated
= Cond
!= CmpInst::FCMP_ULE
;
628 // Default compare result in gpr register will be `true`.
629 // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
630 // using MOVF_I. When orignal predicate (Cond) is logically negated
631 // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
632 unsigned MoveOpcode
= isLogicallyNegated
? Mips::MOVT_I
: Mips::MOVF_I
;
634 unsigned TrueInReg
= MRI
.createVirtualRegister(&Mips::GPR32RegClass
);
635 BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Mips::ADDiu
))
640 unsigned Size
= MRI
.getType(I
.getOperand(2).getReg()).getSizeInBits();
641 unsigned FCMPOpcode
=
642 Size
== 32 ? Mips::FCMP_S32
643 : STI
.isFP64bit() ? Mips::FCMP_D64
: Mips::FCMP_D32
;
644 MachineInstr
*FCMP
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(FCMPOpcode
))
645 .addUse(I
.getOperand(2).getReg())
646 .addUse(I
.getOperand(3).getReg())
647 .addImm(MipsFCMPCondCode
);
648 if (!constrainSelectedInstRegOperands(*FCMP
, TII
, TRI
, RBI
))
651 MachineInstr
*Move
= BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(MoveOpcode
))
652 .addDef(I
.getOperand(0).getReg())
656 if (!constrainSelectedInstRegOperands(*Move
, TII
, TRI
, RBI
))
667 return constrainSelectedInstRegOperands(*MI
, TII
, TRI
, RBI
);
671 InstructionSelector
*createMipsInstructionSelector(const MipsTargetMachine
&TM
,
672 MipsSubtarget
&Subtarget
,
673 MipsRegisterBankInfo
&RBI
) {
674 return new MipsInstructionSelector(TM
, Subtarget
, RBI
);
676 } // end namespace llvm