74 #define DEBUG_TYPE "mips-fastisel"
82 class MipsFastISel final :
public FastISel {
87 using BaseKind =
enum { RegBase, FrameIndexBase };
90 BaseKind Kind = RegBase;
102 Address() {
Base.Reg = 0; }
104 void setKind(BaseKind K) { Kind = K; }
105 BaseKind getKind()
const {
return Kind; }
106 bool isRegBase()
const {
return Kind == RegBase; }
107 bool isFIBase()
const {
return Kind == FrameIndexBase; }
109 void setReg(
unsigned Reg) {
110 assert(isRegBase() &&
"Invalid base register access!");
115 assert(isRegBase() &&
"Invalid base register access!");
119 void setFI(
unsigned FI) {
120 assert(isFIBase() &&
"Invalid base frame index access!");
124 unsigned getFI()
const {
125 assert(isFIBase() &&
"Invalid base frame index access!");
129 void setOffset(int64_t Offset_) {
Offset = Offset_; }
146 bool fastLowerArguments()
override;
147 bool fastLowerCall(CallLoweringInfo &CLI)
override;
148 bool fastLowerIntrinsicCall(
const IntrinsicInst *II)
override;
150 bool UnsupportedFPMode;
164 bool selectFPToInt(
const Instruction *
I,
bool IsSigned);
169 bool selectDivRem(
const Instruction *
I,
unsigned ISDOpcode);
172 bool isTypeLegal(
Type *Ty,
MVT &VT);
173 bool isTypeSupported(
Type *Ty,
MVT &VT);
174 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
175 bool computeAddress(
const Value *Obj, Address &
Addr);
176 bool computeCallAddress(
const Value *V, Address &
Addr);
177 void simplifyAddress(Address &
Addr);
183 unsigned emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
bool isZExt);
184 bool emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg,
187 bool emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
189 bool emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
190 bool emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
192 bool emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
195 unsigned getRegEnsuringSimpleIntegerWidening(
const Value *,
bool IsUnsigned);
197 unsigned emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
const Value *
LHS,
204 unsigned materializeExternalCallSym(
MCSymbol *Syn);
207 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc));
211 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
216 unsigned MemReg, int64_t MemOffset) {
221 unsigned MemReg, int64_t MemOffset) {
222 return emitInst(Opc, DstReg).
addReg(MemReg).
addImm(MemOffset);
225 unsigned fastEmitInst_rr(
unsigned MachineInstOpcode,
227 unsigned Op0,
unsigned Op1);
242 bool finishCall(CallLoweringInfo &CLI,
MVT RetVT,
unsigned NumBytes);
260 unsigned fastMaterializeAlloca(
const AllocaInst *AI)
override;
261 unsigned fastMaterializeConstant(
const Constant *
C)
override;
262 bool fastSelectInstruction(
const Instruction *
I)
override;
264 #include "MipsGenFastISel.inc"
285 #include "MipsGenCallingConv.inc"
291 unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
294 if (isa<ConstantInt>(
LHS) && !isa<ConstantInt>(
RHS))
317 if (
const auto *
C = dyn_cast<ConstantInt>(
RHS))
320 RHSReg = getRegForValue(
RHS);
324 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
328 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
332 unsigned MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
334 "Alloca should always return a pointer.");
337 FuncInfo.StaticAllocaMap.find(AI);
339 if (
SI != FuncInfo.StaticAllocaMap.end()) {
340 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
341 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::LEA_ADDiu),
351 unsigned MipsFastISel::materializeInt(
const Constant *
C,
MVT VT) {
359 unsigned MipsFastISel::materialize32BitInt(int64_t
Imm,
361 Register ResultReg = createResultReg(RC);
363 if (isInt<16>(
Imm)) {
364 unsigned Opc = Mips::ADDiu;
365 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(
Imm);
367 }
else if (isUInt<16>(
Imm)) {
368 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(
Imm);
371 unsigned Lo =
Imm & 0xFFFF;
372 unsigned Hi = (
Imm >> 16) & 0xFFFF;
375 Register TmpReg = createResultReg(RC);
376 emitInst(Mips::LUi, TmpReg).addImm(Hi);
377 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
379 emitInst(Mips::LUi, ResultReg).addImm(Hi);
384 unsigned MipsFastISel::materializeFP(
const ConstantFP *CFP,
MVT VT) {
385 if (UnsupportedFPMode)
390 Register DestReg = createResultReg(RC);
391 unsigned TempReg = materialize32BitInt(
Imm, &Mips::GPR32RegClass);
392 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
396 Register DestReg = createResultReg(RC);
397 unsigned TempReg1 = materialize32BitInt(
Imm >> 32, &Mips::GPR32RegClass);
399 materialize32BitInt(
Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
406 unsigned MipsFastISel::materializeGV(
const GlobalValue *GV,
MVT VT) {
411 Register DestReg = createResultReg(RC);
417 emitInst(Mips::LW, DestReg)
418 .addReg(MFI->getGlobalBaseReg(*MF))
422 Register TempReg = createResultReg(RC);
423 emitInst(Mips::ADDiu, TempReg)
431 unsigned MipsFastISel::materializeExternalCallSym(
MCSymbol *Sym) {
433 Register DestReg = createResultReg(RC);
434 emitInst(Mips::LW, DestReg)
435 .addReg(MFI->getGlobalBaseReg(*MF))
442 unsigned MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
443 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
450 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
451 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
452 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
453 return materializeGV(GV, VT);
454 else if (isa<ConstantInt>(
C))
455 return materializeInt(
C, VT);
460 bool MipsFastISel::computeAddress(
const Value *Obj, Address &
Addr) {
461 const User *U =
nullptr;
462 unsigned Opcode = Instruction::UserOp1;
463 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
466 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
467 FuncInfo.MBBMap[
I->getParent()] == FuncInfo.MBB) {
468 Opcode =
I->getOpcode();
471 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
472 Opcode =
C->getOpcode();
478 case Instruction::BitCast:
481 case Instruction::GetElementPtr: {
483 int64_t TmpOffset =
Addr.getOffset();
492 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
499 TmpOffset += CI->getSExtValue() *
S;
502 if (canFoldAddIntoGEP(U,
Op)) {
505 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
508 Op = cast<AddOperator>(
Op)->getOperand(0);
512 goto unsupported_gep;
517 Addr.setOffset(TmpOffset);
525 case Instruction::Alloca: {
528 FuncInfo.StaticAllocaMap.find(AI);
529 if (
SI != FuncInfo.StaticAllocaMap.end()) {
530 Addr.setKind(Address::FrameIndexBase);
537 Addr.setReg(getRegForValue(Obj));
538 return Addr.getReg() != 0;
541 bool MipsFastISel::computeCallAddress(
const Value *V, Address &
Addr) {
542 const User *U =
nullptr;
543 unsigned Opcode = Instruction::UserOp1;
545 if (
const auto *
I = dyn_cast<Instruction>(V)) {
548 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
549 Opcode =
I->getOpcode();
552 }
else if (
const auto *
C = dyn_cast<ConstantExpr>(V)) {
553 Opcode =
C->getOpcode();
560 case Instruction::BitCast:
564 case Instruction::IntToPtr:
567 TLI.getPointerTy(
DL))
570 case Instruction::PtrToInt:
572 if (TLI.getValueType(
DL, U->
getType()) == TLI.getPointerTy(
DL))
577 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
578 Addr.setGlobalValue(GV);
583 if (!
Addr.getGlobalValue()) {
584 Addr.setReg(getRegForValue(V));
585 return Addr.getReg() != 0;
591 bool MipsFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
592 EVT evt = TLI.getValueType(
DL, Ty,
true);
600 return TLI.isTypeLegal(VT);
603 bool MipsFastISel::isTypeSupported(
Type *Ty,
MVT &VT) {
607 if (isTypeLegal(Ty, VT))
618 bool MipsFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
619 if (isTypeLegal(Ty, VT))
636 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
639 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);
648 Register TempReg = createResultReg(&Mips::GPR32RegClass);
649 emitInst(
Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
650 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
654 Register TempReg = createResultReg(&Mips::GPR32RegClass);
655 emitInst(
Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
656 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
660 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
663 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
666 Register TempReg = createResultReg(&Mips::GPR32RegClass);
667 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
668 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
672 Register TempReg = createResultReg(&Mips::GPR32RegClass);
673 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
674 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
678 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
681 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
684 Register TempReg = createResultReg(&Mips::GPR32RegClass);
685 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
686 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
690 Register TempReg = createResultReg(&Mips::GPR32RegClass);
691 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
692 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
701 if (UnsupportedFPMode)
703 bool IsFloat =
Left->getType()->isFloatTy();
704 bool IsDouble =
Left->getType()->isDoubleTy();
705 if (!IsFloat && !IsDouble)
707 unsigned Opc, CondMovOpc;
710 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
711 CondMovOpc = Mips::MOVT_I;
714 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
715 CondMovOpc = Mips::MOVF_I;
718 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
719 CondMovOpc = Mips::MOVT_I;
722 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
723 CondMovOpc = Mips::MOVT_I;
726 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
727 CondMovOpc = Mips::MOVF_I;
730 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
731 CondMovOpc = Mips::MOVF_I;
736 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
737 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
738 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
739 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
742 emitInst(CondMovOpc, ResultReg)
745 .addReg(RegWithZero);
759 ResultReg = createResultReg(&Mips::GPR32RegClass);
763 ResultReg = createResultReg(&Mips::GPR32RegClass);
767 ResultReg = createResultReg(&Mips::GPR32RegClass);
771 if (UnsupportedFPMode)
773 ResultReg = createResultReg(&Mips::FGR32RegClass);
777 if (UnsupportedFPMode)
779 ResultReg = createResultReg(&Mips::AFGR64RegClass);
785 if (
Addr.isRegBase()) {
786 simplifyAddress(
Addr);
787 emitInstLoad(Opc, ResultReg,
Addr.getReg(),
Addr.getOffset());
790 if (
Addr.isFIBase()) {
791 unsigned FI =
Addr.getFI();
797 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
822 if (UnsupportedFPMode)
827 if (UnsupportedFPMode)
834 if (
Addr.isRegBase()) {
835 simplifyAddress(
Addr);
836 emitInstStore(Opc, SrcReg,
Addr.getReg(),
Addr.getOffset());
839 if (
Addr.isFIBase()) {
840 unsigned FI =
Addr.getFI();
846 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
856 bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
858 if (!isTypeSupported(
I->getType(), VT))
862 switch (
I->getOpcode()) {
865 case Instruction::And:
866 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
868 case Instruction::Or:
869 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
871 case Instruction::Xor:
872 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
879 updateValueMap(
I, ResultReg);
885 if (cast<LoadInst>(
I)->isAtomic())
890 if (!isLoadTypeLegal(
I->getType(), VT))
895 if (!computeAddress(
I->getOperand(0),
Addr))
901 updateValueMap(
I, ResultReg);
906 Value *Op0 =
I->getOperand(0);
910 if (cast<StoreInst>(
I)->isAtomic())
915 if (!isLoadTypeLegal(
I->getOperand(0)->getType(), VT))
919 SrcReg = getRegForValue(Op0);
925 if (!computeAddress(
I->getOperand(1),
Addr))
950 unsigned ZExtCondReg = 0;
953 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
960 if (ZExtCondReg == 0) {
966 if (ZExtCondReg == 0)
970 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
978 const CmpInst *CI = cast<CmpInst>(
I);
979 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
982 updateValueMap(
I, ResultReg);
988 if (UnsupportedFPMode)
990 Value *Src =
I->getOperand(0);
991 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
992 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1003 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1004 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1005 updateValueMap(
I, DestReg);
1009 bool MipsFastISel::selectSelect(
const Instruction *
I) {
1010 assert(isa<SelectInst>(
I) &&
"Expected a select instruction.");
1015 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1017 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1021 unsigned CondMovOpc;
1025 CondMovOpc = Mips::MOVN_I_I;
1026 RC = &Mips::GPR32RegClass;
1028 CondMovOpc = Mips::MOVN_I_S;
1029 RC = &Mips::FGR32RegClass;
1031 CondMovOpc = Mips::MOVN_I_D32;
1032 RC = &Mips::AFGR64RegClass;
1038 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1039 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1042 if (!Src1Reg || !Src2Reg || !CondReg)
1045 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1052 Register ResultReg = createResultReg(RC);
1053 Register TempReg = createResultReg(RC);
1055 if (!ResultReg || !TempReg)
1058 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1059 emitInst(CondMovOpc, ResultReg)
1060 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1061 updateValueMap(
I, ResultReg);
1066 bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1067 if (UnsupportedFPMode)
1069 Value *Src =
I->getOperand(0);
1070 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1071 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1076 Register SrcReg = getRegForValue(Src);
1080 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1084 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1085 updateValueMap(
I, DestReg);
1090 bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1091 if (UnsupportedFPMode)
1097 Type *DstTy =
I->getType();
1098 if (!isTypeLegal(DstTy, DstVT))
1104 Value *Src =
I->getOperand(0);
1105 Type *SrcTy = Src->getType();
1106 if (!isTypeLegal(SrcTy, SrcVT))
1112 Register SrcReg = getRegForValue(Src);
1118 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1119 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1120 unsigned Opc = (SrcVT ==
MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1123 emitInst(Opc, TempReg).addReg(SrcReg);
1124 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1126 updateValueMap(
I, DestReg);
1130 bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1132 unsigned &NumBytes) {
1136 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, CCAssignFnForCall(
CC));
1138 NumBytes = CCInfo.getNextStackOffset();
1143 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1146 for (
unsigned i = 0,
e = ArgLocs.size();
i !=
e; ++
i) {
1156 if (Subtarget->isFP64bit())
1161 }
else if (
i == 1) {
1166 if (Subtarget->isFP64bit())
1193 Register ArgReg = getRegForValue(ArgVal);
1205 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1213 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1224 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1238 if (isa<UndefValue>(ArgVal))
1248 unsigned BEAlign = 0;
1249 if (ArgSize < 8 && !Subtarget->isLittle())
1250 BEAlign = 8 - ArgSize;
1253 Addr.setKind(Address::RegBase);
1254 Addr.setReg(Mips::SP);
1270 bool MipsFastISel::finishCall(CallLoweringInfo &CLI,
MVT RetVT,
1271 unsigned NumBytes) {
1273 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1278 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips, CLI.RetTy,
1279 CLI.Symbol ? CLI.Symbol->getName().data()
1283 if (RVLocs.size() != 1)
1286 MVT CopyVT = RVLocs[0].getValVT();
1291 Register ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
1294 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1295 TII.get(TargetOpcode::COPY),
1296 ResultReg).
addReg(RVLocs[0].getLocReg());
1297 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1299 CLI.ResultReg = ResultReg;
1300 CLI.NumResultRegs = 1;
1305 bool MipsFastISel::fastLowerArguments() {
1308 if (!FuncInfo.CanLowerReturn) {
1314 if (
F->isVarArg()) {
1321 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1325 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1327 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1328 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1329 auto NextGPR32 = GPR32ArgRegs.begin();
1330 auto NextFGR32 = FGR32ArgRegs.begin();
1331 auto NextAFGR64 = AFGR64ArgRegs.begin();
1333 struct AllocatedReg {
1343 for (
const auto &FormalArg :
F->args()) {
1344 if (FormalArg.hasAttribute(Attribute::InReg) ||
1345 FormalArg.hasAttribute(Attribute::StructRet) ||
1346 FormalArg.hasAttribute(Attribute::ByVal)) {
1351 Type *ArgTy = FormalArg.getType();
1357 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
1369 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1370 !FormalArg.hasAttribute(Attribute::ZExt)) {
1373 LLVM_DEBUG(
dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1377 if (NextGPR32 == GPR32ArgRegs.end()) {
1378 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1383 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1386 NextFGR32 = FGR32ArgRegs.end();
1387 NextAFGR64 = AFGR64ArgRegs.end();
1391 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1393 LLVM_DEBUG(
dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1397 if (NextGPR32 == GPR32ArgRegs.end()) {
1398 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1403 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1406 NextFGR32 = FGR32ArgRegs.end();
1407 NextAFGR64 = AFGR64ArgRegs.end();
1411 if (UnsupportedFPMode) {
1415 if (NextFGR32 == FGR32ArgRegs.end()) {
1416 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1420 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1423 if (NextGPR32 != GPR32ArgRegs.end())
1425 if (NextAFGR64 != AFGR64ArgRegs.end())
1430 if (UnsupportedFPMode) {
1434 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1435 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1439 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1442 if (NextGPR32 != GPR32ArgRegs.end())
1444 if (NextGPR32 != GPR32ArgRegs.end())
1446 if (NextFGR32 != FGR32ArgRegs.end())
1456 for (
const auto &FormalArg :
F->args()) {
1457 unsigned ArgNo = FormalArg.getArgNo();
1458 unsigned SrcReg = Allocation[ArgNo].Reg;
1459 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1463 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1464 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1465 TII.get(TargetOpcode::COPY), ResultReg)
1467 updateValueMap(&FormalArg, ResultReg);
1472 unsigned IncomingArgSizeInBytes = 0;
1477 IncomingArgSizeInBytes =
std::min(getABI().GetCalleeAllocdArgSizeInBytes(
CC),
1478 IncomingArgSizeInBytes);
1486 bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1488 bool IsTailCall = CLI.IsTailCall;
1489 bool IsVarArg = CLI.IsVarArg;
1507 if (CLI.RetTy->isVoidTy())
1509 else if (!isTypeSupported(CLI.RetTy, RetVT))
1512 for (
auto Flag : CLI.OutFlags)
1518 OutVTs.
reserve(CLI.OutVals.size());
1520 for (
auto *Val : CLI.OutVals) {
1522 if (!isTypeLegal(Val->getType(), VT) &&
1530 OutVTs.push_back(VT);
1534 if (!computeCallAddress(Callee,
Addr))
1539 if (!processCallArgs(CLI, OutVTs, NumBytes))
1542 if (!
Addr.getGlobalValue())
1546 unsigned DestAddress;
1548 DestAddress = materializeExternalCallSym(Symbol);
1550 DestAddress = materializeGV(
Addr.getGlobalValue(),
MVT::i32);
1551 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1553 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::JALR),
1557 for (
auto Reg : CLI.OutRegs)
1572 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1577 return finishCall(CLI, RetVT, NumBytes);
1580 bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *II) {
1584 case Intrinsic::bswap: {
1588 if (!isTypeSupported(RetTy, VT))
1594 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1598 if (Subtarget->hasMips32r2()) {
1599 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1600 updateValueMap(II, DestReg);
1603 unsigned TempReg[3];
1604 for (
unsigned &R : TempReg) {
1605 R = createResultReg(&Mips::GPR32RegClass);
1609 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1610 emitInst(
Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1611 emitInst(
Mips::OR, TempReg[2]).addReg(TempReg[0]).addReg(TempReg[1]);
1612 emitInst(Mips::ANDi, DestReg).addReg(TempReg[2]).addImm(0xFFFF);
1613 updateValueMap(II, DestReg);
1617 if (Subtarget->hasMips32r2()) {
1618 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1619 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1620 emitInst(
Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1621 updateValueMap(II, DestReg);
1624 unsigned TempReg[8];
1625 for (
unsigned &R : TempReg) {
1626 R = createResultReg(&Mips::GPR32RegClass);
1631 emitInst(
Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1632 emitInst(
Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1633 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1634 emitInst(
Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1636 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1637 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1639 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1640 emitInst(
Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1641 emitInst(
Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1642 updateValueMap(II, DestReg);
1649 case Intrinsic::memmove: {
1650 const auto *MTI = cast<MemTransferInst>(II);
1652 if (MTI->isVolatile())
1654 if (!MTI->getLength()->getType()->isIntegerTy(32))
1656 const char *IntrMemName = isa<MemCpyInst>(II) ?
"memcpy" :
"memmove";
1657 return lowerCallTo(II, IntrMemName, II->
arg_size() - 1);
1659 case Intrinsic::memset: {
1660 const MemSetInst *MSI = cast<MemSetInst>(II);
1666 return lowerCallTo(II,
"memset", II->
arg_size() - 1);
1673 const Function &
F = *
I->getParent()->getParent();
1678 if (!FuncInfo.CanLowerReturn)
1684 if (
Ret->getNumOperands() > 0) {
1699 CCInfo.AnalyzeReturn(Outs, RetCC);
1702 if (ValLocs.size() != 1)
1706 const Value *RV =
Ret->getOperand(0);
1739 if (RVVT ==
MVT::f64 && UnsupportedFPMode) {
1746 if (RVVT != DestVT) {
1750 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1751 bool IsZExt = Outs[0].Flags.isZExt();
1752 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1759 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1760 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1766 for (
unsigned i = 0,
e = RetRegs.size();
i !=
e; ++
i)
1777 SrcVT = TLI.getValueType(
DL,
Op->getType(),
true);
1778 DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1791 updateValueMap(
I, SrcReg);
1795 bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1796 Type *DestTy =
I->getType();
1797 Value *Src =
I->getOperand(0);
1798 Type *SrcTy = Src->getType();
1800 bool isZExt = isa<ZExtInst>(
I);
1801 Register SrcReg = getRegForValue(Src);
1805 EVT SrcEVT, DestEVT;
1806 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1807 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1815 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1817 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1819 updateValueMap(
I, ResultReg);
1823 bool MipsFastISel::emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1836 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1837 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1838 emitInst(
Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1842 bool MipsFastISel::emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1848 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1851 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1857 bool MipsFastISel::emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1861 if (Subtarget->hasMips32r2())
1862 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1863 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1866 bool MipsFastISel::emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1884 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(
Imm);
1888 bool MipsFastISel::emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1889 unsigned DestReg,
bool IsZExt) {
1898 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1899 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1902 unsigned MipsFastISel::emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1904 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1905 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1909 bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1910 EVT DestEVT = TLI.getValueType(
DL,
I->getType(),
true);
1919 switch (ISDOpcode) {
1932 Register Src0Reg = getRegForValue(
I->getOperand(0));
1933 Register Src1Reg = getRegForValue(
I->getOperand(1));
1934 if (!Src0Reg || !Src1Reg)
1937 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1938 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1940 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1947 emitInst(MFOpc, ResultReg);
1949 updateValueMap(
I, ResultReg);
1956 if (!isTypeSupported(
I->getType(), RetVT))
1959 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1963 unsigned Opcode =
I->getOpcode();
1964 const Value *Op0 =
I->getOperand(0);
1965 Register Op0Reg = getRegForValue(Op0);
1970 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1971 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1975 MVT Op0MVT = TLI.getValueType(
DL, Op0->
getType(),
true).getSimpleVT();
1976 bool IsZExt = Opcode == Instruction::LShr;
1977 if (!emitIntExt(Op0MVT, Op0Reg,
MVT::i32, TempReg, IsZExt))
1983 if (
const auto *
C = dyn_cast<ConstantInt>(
I->getOperand(1))) {
1989 case Instruction::Shl:
1992 case Instruction::AShr:
1995 case Instruction::LShr:
2000 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2001 updateValueMap(
I, ResultReg);
2005 Register Op1Reg = getRegForValue(
I->getOperand(1));
2012 case Instruction::Shl:
2013 Opcode = Mips::SLLV;
2015 case Instruction::AShr:
2016 Opcode = Mips::SRAV;
2018 case Instruction::LShr:
2019 Opcode = Mips::SRLV;
2023 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2024 updateValueMap(
I, ResultReg);
2028 bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2029 switch (
I->getOpcode()) {
2033 return selectLoad(
I);
2035 return selectStore(
I);
2036 case Instruction::SDiv:
2040 case Instruction::UDiv:
2044 case Instruction::SRem:
2048 case Instruction::URem:
2052 case Instruction::Shl:
2053 case Instruction::LShr:
2054 case Instruction::AShr:
2055 return selectShift(
I);
2056 case Instruction::And:
2057 case Instruction::Or:
2058 case Instruction::Xor:
2059 return selectLogicalOp(
I);
2060 case Instruction::Br:
2061 return selectBranch(
I);
2063 return selectRet(
I);
2064 case Instruction::Trunc:
2065 return selectTrunc(
I);
2066 case Instruction::ZExt:
2067 case Instruction::SExt:
2068 return selectIntExt(
I);
2069 case Instruction::FPTrunc:
2070 return selectFPTrunc(
I);
2071 case Instruction::FPExt:
2072 return selectFPExt(
I);
2073 case Instruction::FPToSI:
2074 return selectFPToInt(
I,
true);
2075 case Instruction::FPToUI:
2076 return selectFPToInt(
I,
false);
2077 case Instruction::ICmp:
2078 case Instruction::FCmp:
2079 return selectCmp(
I);
2081 return selectSelect(
I);
2086 unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2091 MVT VMVT = TLI.getValueType(
DL, V->
getType(),
true).getSimpleVT();
2097 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2098 if (!emitIntExt(VMVT, VReg,
MVT::i32, TempReg, IsUnsigned))
2105 void MipsFastISel::simplifyAddress(Address &
Addr) {
2106 if (!isInt<16>(
Addr.getOffset())) {
2108 materialize32BitInt(
Addr.getOffset(), &Mips::GPR32RegClass);
2109 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2110 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(
Addr.getReg());
2111 Addr.setReg(DestReg);
2116 unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2118 unsigned Op0,
unsigned Op1) {
2126 Register ResultReg = createResultReg(RC);
2130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
2145 return new MipsFastISel(funcInfo, libInfo);