21 #include "llvm/IR/IntrinsicsMips.h"
23 #define DEBUG_TYPE "mips-isel"
29 #define GET_GLOBALISEL_PREDICATE_BITSET
30 #include "MipsGenGlobalISel.inc"
31 #undef GET_GLOBALISEL_PREDICATE_BITSET
65 #define GET_GLOBALISEL_PREDICATES_DECL
66 #include "MipsGenGlobalISel.inc"
67 #undef GET_GLOBALISEL_PREDICATES_DECL
69 #define GET_GLOBALISEL_TEMPORARIES_DECL
70 #include "MipsGenGlobalISel.inc"
71 #undef GET_GLOBALISEL_TEMPORARIES_DECL
76 #define GET_GLOBALISEL_IMPL
77 #include "MipsGenGlobalISel.inc"
78 #undef GET_GLOBALISEL_IMPL
80 MipsInstructionSelector::MipsInstructionSelector(
83 :
TM(
TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
87 #
include "MipsGenGlobalISel.inc"
90 #
include "MipsGenGlobalISel.inc"
95 bool MipsInstructionSelector::isRegInGprb(
Register Reg,
97 return RBI.getRegBank(
Reg,
MRI,
TRI)->getID() == Mips::GPRBRegBankID;
100 bool MipsInstructionSelector::isRegInFprb(
Register Reg,
102 return RBI.getRegBank(
Reg,
MRI,
TRI)->getID() == Mips::FPRBRegBankID;
107 Register DstReg =
I.getOperand(0).getReg();
108 if (Register::isPhysicalRegister(DstReg))
112 if (!RBI.constrainGenericRegister(DstReg, *RC,
MRI)) {
125 if (isRegInGprb(
Reg,
MRI)) {
127 "Register class not available for LLT, register bank combination");
128 return &Mips::GPR32RegClass;
131 if (isRegInFprb(
Reg,
MRI)) {
133 assert((TySize == 32 || TySize == 64) &&
134 "Register class not available for LLT, register bank combination");
136 return &Mips::FGR32RegClass;
137 return STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
144 bool MipsInstructionSelector::materialize32BitImm(
Register DestReg,
APInt Imm,
146 assert(
Imm.getBitWidth() == 32 &&
"Unsupported immediate size.");
148 if (
Imm.getHiBits(16).isZero()) {
150 B.buildInstr(Mips::ORi, {DestReg}, {
Register(Mips::ZERO)})
151 .addImm(
Imm.getLoBits(16).getLimitedValue());
155 if (
Imm.getLoBits(16).isZero()) {
157 .addImm(
Imm.getHiBits(16).getLimitedValue());
161 if (
Imm.isSignedIntN(16)) {
163 B.buildInstr(Mips::ADDiu, {DestReg}, {
Register(Mips::ZERO)})
164 .addImm(
Imm.getLoBits(16).getLimitedValue());
168 Register LUiReg =
B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
170 .addImm(
Imm.getHiBits(16).getLimitedValue());
171 MachineInstr *ORi =
B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
172 .addImm(
Imm.getLoBits(16).getLimitedValue());
182 MipsInstructionSelector::selectLoadStoreOpCode(
MachineInstr &
I,
184 const Register ValueReg =
I.getOperand(0).getReg();
187 const unsigned MemSizeInBytes = (*
I.memoperands_begin())->getSize();
188 unsigned Opc =
I.getOpcode();
189 const bool isStore = Opc == TargetOpcode::G_STORE;
191 if (isRegInGprb(ValueReg,
MRI)) {
193 (Ty.
isPointer() && TySize == 32 && MemSizeInBytes == 4)) &&
194 "Unsupported register bank, LLT, MemSizeInBytes combination");
197 switch (MemSizeInBytes) {
209 switch (MemSizeInBytes) {
213 return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
215 return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
221 if (isRegInFprb(ValueReg,
MRI)) {
223 assert(((TySize == 32 && MemSizeInBytes == 4) ||
224 (TySize == 64 && MemSizeInBytes == 8)) &&
225 "Unsupported register bank, LLT, MemSizeInBytes combination");
227 if (MemSizeInBytes == 4)
228 return isStore ? Mips::SWC1 : Mips::LWC1;
231 return isStore ? Mips::SDC164 : Mips::LDC164;
232 return isStore ? Mips::SDC1 : Mips::LDC1;
236 assert(STI.hasMSA() &&
"Vector instructions require target with MSA.");
237 assert((TySize == 128 && MemSizeInBytes == 16) &&
238 "Unsupported register bank, LLT, MemSizeInBytes combination");
241 return isStore ? Mips::ST_B : Mips::LD_B;
243 return isStore ? Mips::ST_H : Mips::LD_H;
245 return isStore ? Mips::ST_W : Mips::LD_W;
247 return isStore ? Mips::ST_D : Mips::LD_D;
257 bool MipsInstructionSelector::buildUnalignedStore(
262 .
add(
I.getOperand(0))
271 bool MipsInstructionSelector::buildUnalignedLoad(
299 if (
I.getOpcode() == Mips::G_MUL &&
300 isRegInGprb(
I.getOperand(0).getReg(),
MRI)) {
302 .
add(
I.getOperand(0))
303 .
add(
I.getOperand(1))
304 .
add(
I.getOperand(2));
318 using namespace TargetOpcode;
320 switch (
I.getOpcode()) {
325 PseudoMULTu =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(Mips::PseudoMULTu))
327 .
add(
I.getOperand(1))
328 .
add(
I.getOperand(2));
332 PseudoMove =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(Mips::PseudoMFHI))
333 .
addDef(
I.getOperand(0).getReg())
343 .
add(
I.getOperand(0))
344 .
add(
I.getOperand(1))
345 .
add(
I.getOperand(2));
350 I.setDesc(
TII.get(COPY));
353 case G_FRAME_INDEX: {
355 .
add(
I.getOperand(0))
356 .
add(
I.getOperand(1))
362 .
add(
I.getOperand(0))
364 .
add(
I.getOperand(1));
371 "Non-power-of-two jump-table entry size not supported.");
376 .
addUse(
I.getOperand(2).getReg())
384 .
addUse(
I.getOperand(0).getReg())
423 .
add(
I.getOperand(0));
427 const Register DestReg =
I.getOperand(0).getReg();
430 if (Register::isPhysicalRegister(DestReg))
433 DefRC = getRegClassForTypeOnBank(DestReg,
MRI);
435 I.setDesc(
TII.get(TargetOpcode::PHI));
436 return RBI.constrainGenericRegister(DestReg, *DefRC,
MRI);
442 auto MMO = *
I.memoperands_begin();
444 int64_t SignedOffset = 0;
453 if (
Addr->getOpcode() == G_PTR_ADD) {
455 if (
Offset->getOpcode() == G_CONSTANT) {
456 APInt OffsetValue =
Offset->getOperand(1).getCImm()->getValue();
458 BaseAddr =
Addr->getOperand(1);
466 !STI.systemSupportsUnalignedAccess()) {
467 if (MMO->
getSize() != 4 || !isRegInGprb(
I.getOperand(0).getReg(),
MRI))
470 if (
I.getOpcode() == G_STORE) {
471 if (!buildUnalignedStore(
I,
Mips::SWL, BaseAddr, SignedOffset + 3, MMO))
473 if (!buildUnalignedStore(
I,
Mips::SWR, BaseAddr, SignedOffset, MMO))
479 if (
I.getOpcode() == G_LOAD) {
484 if (!buildUnalignedLoad(
I,
Mips::LWL, Tmp, BaseAddr, SignedOffset + 3,
487 if (!buildUnalignedLoad(
I,
Mips::LWR,
I.getOperand(0).getReg(),
488 BaseAddr, SignedOffset, Tmp, MMO))
497 const unsigned NewOpc = selectLoadStoreOpCode(
I,
MRI);
498 if (NewOpc ==
I.getOpcode())
502 .
add(
I.getOperand(0))
513 bool IsSigned =
I.getOpcode() == G_SREM ||
I.getOpcode() == G_SDIV;
514 bool IsDiv =
I.getOpcode() == G_UDIV ||
I.getOpcode() == G_SDIV;
518 TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
520 .
add(
I.getOperand(1))
521 .
add(
I.getOperand(2));
526 TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
527 .
addDef(
I.getOperand(0).getReg())
538 .
add(
I.getOperand(0))
539 .
add(
I.getOperand(2))
540 .
add(
I.getOperand(1))
541 .
add(
I.getOperand(3));
544 case G_UNMERGE_VALUES: {
545 if (
I.getNumOperands() != 3)
550 if (!isRegInFprb(Src,
MRI) ||
551 !(isRegInGprb(
Lo,
MRI) && isRegInGprb(
Hi,
MRI)))
574 case G_IMPLICIT_DEF: {
585 if (!materialize32BitImm(
I.getOperand(0).getReg(),
586 I.getOperand(1).getCImm()->getValue(),
B))
593 const APFloat &FPimm =
I.getOperand(1).getFPImm()->getValueAPF();
600 if (!materialize32BitImm(GPRReg, APImm,
B))
604 B.buildInstr(Mips::MTC1, {
I.getOperand(0).
getReg()}, {GPRReg});
612 if (!materialize32BitImm(GPRRegHigh, APImm.
getHiBits(32).
trunc(32),
B))
619 {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
629 unsigned FABSOpcode =
630 Size == 32 ? Mips::FABS_S
631 : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
633 .
add(
I.getOperand(0))
634 .
add(
I.getOperand(1));
641 assert((ToSize == 32) &&
"Unsupported integer size for G_FPTOSI");
642 assert((FromSize == 32 || FromSize == 64) &&
643 "Unsupported floating point size for G_FPTOSI");
647 Opcode = Mips::TRUNC_W_S;
649 Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32;
653 .
addUse(
I.getOperand(1).getReg());
658 .
addDef(
I.getOperand(0).getReg())
666 case G_GLOBAL_VALUE: {
670 .
addDef(
I.getOperand(0).getReg())
684 MachineMemOperand::MOLoad, 4,
Align(4)));
694 .
addDef(
I.getOperand(0).getReg())
713 .
addDef(
I.getOperand(0).getReg())
726 .
addDef(
I.getOperand(0).getReg())
731 MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad, 4,
736 .
addDef(
I.getOperand(0).getReg())
749 if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
756 Register ICMPReg =
I.getOperand(0).getReg();
764 case CmpInst::ICMP_EQ:
766 Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
768 case CmpInst::ICMP_NE:
770 Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
772 case CmpInst::ICMP_UGT:
775 case CmpInst::ICMP_UGE:
777 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
779 case CmpInst::ICMP_ULT:
782 case CmpInst::ICMP_ULE:
784 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
786 case CmpInst::ICMP_SGT:
789 case CmpInst::ICMP_SGE:
791 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
793 case CmpInst::ICMP_SLT:
796 case CmpInst::ICMP_SLE:
798 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
807 Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
822 unsigned MipsFCMPCondCode;
823 bool isLogicallyNegated;
825 I.getOperand(1).getPredicate())) {
826 case CmpInst::FCMP_UNO:
827 case CmpInst::FCMP_ORD:
829 isLogicallyNegated =
Cond != CmpInst::FCMP_UNO;
831 case CmpInst::FCMP_OEQ:
832 case CmpInst::FCMP_UNE:
834 isLogicallyNegated =
Cond != CmpInst::FCMP_OEQ;
836 case CmpInst::FCMP_UEQ:
837 case CmpInst::FCMP_ONE:
839 isLogicallyNegated =
Cond != CmpInst::FCMP_UEQ;
841 case CmpInst::FCMP_OLT:
842 case CmpInst::FCMP_UGE:
844 isLogicallyNegated =
Cond != CmpInst::FCMP_OLT;
846 case CmpInst::FCMP_ULT:
847 case CmpInst::FCMP_OGE:
849 isLogicallyNegated =
Cond != CmpInst::FCMP_ULT;
851 case CmpInst::FCMP_OLE:
852 case CmpInst::FCMP_UGT:
854 isLogicallyNegated =
Cond != CmpInst::FCMP_OLE;
856 case CmpInst::FCMP_ULE:
857 case CmpInst::FCMP_OGT:
859 isLogicallyNegated =
Cond != CmpInst::FCMP_ULE;
869 unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
878 unsigned FCMPOpcode =
879 Size == 32 ? Mips::FCMP_S32
880 : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
882 .
addUse(
I.getOperand(2).getReg())
883 .
addUse(
I.getOperand(3).getReg())
884 .
addImm(MipsFCMPCondCode);
889 .
addDef(
I.getOperand(0).getReg())
918 .
addUse(
I.getOperand(0).getReg())
938 return new MipsInstructionSelector(
TM, Subtarget, RBI);