Home | History | Annotate | Line # | Download | only in Mips
      1 //===- MipsCallLowering.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 //
      9 /// \file
     10 /// This file implements the lowering of LLVM calls to machine code calls for
     11 /// GlobalISel.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "MipsCallLowering.h"
     16 #include "MipsCCState.h"
     17 #include "MipsMachineFunction.h"
     18 #include "MipsTargetMachine.h"
     19 #include "llvm/CodeGen/Analysis.h"
     20 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
     21 
     22 using namespace llvm;
     23 
     24 MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI)
     25     : CallLowering(&TLI) {}
     26 
     27 bool MipsCallLowering::MipsHandler::assign(Register VReg, const CCValAssign &VA,
     28                                            const EVT &VT) {
     29   if (VA.isRegLoc()) {
     30     assignValueToReg(VReg, VA, VT);
     31   } else if (VA.isMemLoc()) {
     32     assignValueToAddress(VReg, VA);
     33   } else {
     34     return false;
     35   }
     36   return true;
     37 }
     38 
     39 bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<Register> VRegs,
     40                                                 ArrayRef<CCValAssign> ArgLocs,
     41                                                 unsigned ArgLocsStartIndex,
     42                                                 const EVT &VT) {
     43   for (unsigned i = 0; i < VRegs.size(); ++i)
     44     if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i], VT))
     45       return false;
     46   return true;
     47 }
     48 
     49 void MipsCallLowering::MipsHandler::setLeastSignificantFirst(
     50     SmallVectorImpl<Register> &VRegs) {
     51   if (!MIRBuilder.getMF().getDataLayout().isLittleEndian())
     52     std::reverse(VRegs.begin(), VRegs.end());
     53 }
     54 
     55 bool MipsCallLowering::MipsHandler::handle(
     56     ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) {
     57   SmallVector<Register, 4> VRegs;
     58   unsigned SplitLength;
     59   const Function &F = MIRBuilder.getMF().getFunction();
     60   const DataLayout &DL = F.getParent()->getDataLayout();
     61   const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>(
     62       MIRBuilder.getMF().getSubtarget().getTargetLowering());
     63 
     64   for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size();
     65        ++ArgsIndex, ArgLocsIndex += SplitLength) {
     66     EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty);
     67     SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(),
     68                                                     F.getCallingConv(), VT);
     69     assert(Args[ArgsIndex].Regs.size() == 1 && "Can't handle multple regs yet");
     70 
     71     if (SplitLength > 1) {
     72       VRegs.clear();
     73       MVT RegisterVT = TLI.getRegisterTypeForCallingConv(
     74           F.getContext(), F.getCallingConv(), VT);
     75       for (unsigned i = 0; i < SplitLength; ++i)
     76         VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT}));
     77 
     78       if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Regs[0],
     79                        VT))
     80         return false;
     81     } else {
     82       if (!assign(Args[ArgsIndex].Regs[0], ArgLocs[ArgLocsIndex], VT))
     83         return false;
     84     }
     85   }
     86   return true;
     87 }
     88 
     89 namespace {
     90 class MipsIncomingValueHandler : public MipsCallLowering::MipsHandler {
     91 public:
     92   MipsIncomingValueHandler(MachineIRBuilder &MIRBuilder,
     93                            MachineRegisterInfo &MRI)
     94       : MipsHandler(MIRBuilder, MRI) {}
     95 
     96 private:
     97   void assignValueToReg(Register ValVReg, const CCValAssign &VA,
     98                         const EVT &VT) override;
     99 
    100   Register getStackAddress(const CCValAssign &VA,
    101                            MachineMemOperand *&MMO) override;
    102 
    103   void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override;
    104 
    105   bool handleSplit(SmallVectorImpl<Register> &VRegs,
    106                    ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
    107                    Register ArgsReg, const EVT &VT) override;
    108 
    109   virtual void markPhysRegUsed(unsigned PhysReg) {
    110     MIRBuilder.getMRI()->addLiveIn(PhysReg);
    111     MIRBuilder.getMBB().addLiveIn(PhysReg);
    112   }
    113 
    114   MachineInstrBuilder buildLoad(const DstOp &Res, const CCValAssign &VA) {
    115     MachineMemOperand *MMO;
    116     Register Addr = getStackAddress(VA, MMO);
    117     return MIRBuilder.buildLoad(Res, Addr, *MMO);
    118   }
    119 };
    120 
    121 class CallReturnHandler : public MipsIncomingValueHandler {
    122 public:
    123   CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
    124                     MachineInstrBuilder &MIB)
    125       : MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
    126 
    127 private:
    128   void markPhysRegUsed(unsigned PhysReg) override {
    129     MIB.addDef(PhysReg, RegState::Implicit);
    130   }
    131 
    132   MachineInstrBuilder &MIB;
    133 };
    134 
    135 } // end anonymous namespace
    136 
    137 void MipsIncomingValueHandler::assignValueToReg(Register ValVReg,
    138                                                 const CCValAssign &VA,
    139                                                 const EVT &VT) {
    140   Register PhysReg = VA.getLocReg();
    141   if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
    142     const MipsSubtarget &STI =
    143         static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
    144     bool IsEL = STI.isLittle();
    145     LLT s32 = LLT::scalar(32);
    146     auto Lo = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 0 : 1)));
    147     auto Hi = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 1 : 0)));
    148     MIRBuilder.buildMerge(ValVReg, {Lo, Hi});
    149     markPhysRegUsed(PhysReg);
    150     markPhysRegUsed(PhysReg + 1);
    151   } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
    152     MIRBuilder.buildCopy(ValVReg, PhysReg);
    153     markPhysRegUsed(PhysReg);
    154   } else {
    155     switch (VA.getLocInfo()) {
    156     case CCValAssign::LocInfo::SExt:
    157     case CCValAssign::LocInfo::ZExt:
    158     case CCValAssign::LocInfo::AExt: {
    159       auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
    160       MIRBuilder.buildTrunc(ValVReg, Copy);
    161       break;
    162     }
    163     default:
    164       MIRBuilder.buildCopy(ValVReg, PhysReg);
    165       break;
    166     }
    167     markPhysRegUsed(PhysReg);
    168   }
    169 }
    170 
    171 Register MipsIncomingValueHandler::getStackAddress(const CCValAssign &VA,
    172                                                    MachineMemOperand *&MMO) {
    173   MachineFunction &MF = MIRBuilder.getMF();
    174   unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
    175   unsigned Offset = VA.getLocMemOffset();
    176   MachineFrameInfo &MFI = MF.getFrameInfo();
    177 
    178   // FIXME: This should only be immutable for non-byval memory arguments.
    179   int FI = MFI.CreateFixedObject(Size, Offset, true);
    180   MachinePointerInfo MPO =
    181       MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
    182 
    183   const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
    184   Align Alignment = commonAlignment(TFL->getStackAlign(), Offset);
    185   MMO =
    186       MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, Size, Alignment);
    187 
    188   return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0);
    189 }
    190 
    191 void MipsIncomingValueHandler::assignValueToAddress(Register ValVReg,
    192                                                     const CCValAssign &VA) {
    193   if (VA.getLocInfo() == CCValAssign::SExt ||
    194       VA.getLocInfo() == CCValAssign::ZExt ||
    195       VA.getLocInfo() == CCValAssign::AExt) {
    196     auto Load = buildLoad(LLT::scalar(32), VA);
    197     MIRBuilder.buildTrunc(ValVReg, Load);
    198   } else
    199     buildLoad(ValVReg, VA);
    200 }
    201 
    202 bool MipsIncomingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs,
    203                                            ArrayRef<CCValAssign> ArgLocs,
    204                                            unsigned ArgLocsStartIndex,
    205                                            Register ArgsReg, const EVT &VT) {
    206   if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT))
    207     return false;
    208   setLeastSignificantFirst(VRegs);
    209   MIRBuilder.buildMerge(ArgsReg, VRegs);
    210   return true;
    211 }
    212 
    213 namespace {
    214 class MipsOutgoingValueHandler : public MipsCallLowering::MipsHandler {
    215 public:
    216   MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
    217                            MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)
    218       : MipsHandler(MIRBuilder, MRI), MIB(MIB) {}
    219 
    220 private:
    221   void assignValueToReg(Register ValVReg, const CCValAssign &VA,
    222                         const EVT &VT) override;
    223 
    224   Register getStackAddress(const CCValAssign &VA,
    225                            MachineMemOperand *&MMO) override;
    226 
    227   void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override;
    228 
    229   bool handleSplit(SmallVectorImpl<Register> &VRegs,
    230                    ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
    231                    Register ArgsReg, const EVT &VT) override;
    232 
    233   Register extendRegister(Register ValReg, const CCValAssign &VA);
    234 
    235   MachineInstrBuilder &MIB;
    236 };
    237 } // end anonymous namespace
    238 
    239 void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg,
    240                                                 const CCValAssign &VA,
    241                                                 const EVT &VT) {
    242   Register PhysReg = VA.getLocReg();
    243   if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
    244     const MipsSubtarget &STI =
    245         static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
    246     bool IsEL = STI.isLittle();
    247     auto Unmerge = MIRBuilder.buildUnmerge(LLT::scalar(32), ValVReg);
    248     MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 0 : 1)), Unmerge.getReg(0));
    249     MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 1 : 0)), Unmerge.getReg(1));
    250   } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) {
    251     MIRBuilder.buildCopy(PhysReg, ValVReg);
    252   } else {
    253     Register ExtReg = extendRegister(ValVReg, VA);
    254     MIRBuilder.buildCopy(PhysReg, ExtReg);
    255     MIB.addUse(PhysReg, RegState::Implicit);
    256   }
    257 }
    258 
    259 Register MipsOutgoingValueHandler::getStackAddress(const CCValAssign &VA,
    260                                                    MachineMemOperand *&MMO) {
    261   MachineFunction &MF = MIRBuilder.getMF();
    262   const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
    263 
    264   LLT p0 = LLT::pointer(0, 32);
    265   LLT s32 = LLT::scalar(32);
    266   auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP));
    267 
    268   unsigned Offset = VA.getLocMemOffset();
    269   auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);
    270 
    271   auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
    272 
    273   MachinePointerInfo MPO =
    274       MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
    275   unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
    276   Align Alignment = commonAlignment(TFL->getStackAlign(), Offset);
    277   MMO =
    278       MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, Size, Alignment);
    279 
    280   return AddrReg.getReg(0);
    281 }
    282 
    283 void MipsOutgoingValueHandler::assignValueToAddress(Register ValVReg,
    284                                                     const CCValAssign &VA) {
    285   MachineMemOperand *MMO;
    286   Register Addr = getStackAddress(VA, MMO);
    287   Register ExtReg = extendRegister(ValVReg, VA);
    288   MIRBuilder.buildStore(ExtReg, Addr, *MMO);
    289 }
    290 
    291 Register MipsOutgoingValueHandler::extendRegister(Register ValReg,
    292                                                   const CCValAssign &VA) {
    293   LLT LocTy{VA.getLocVT()};
    294   switch (VA.getLocInfo()) {
    295   case CCValAssign::SExt: {
    296     return MIRBuilder.buildSExt(LocTy, ValReg).getReg(0);
    297   }
    298   case CCValAssign::ZExt: {
    299     return MIRBuilder.buildZExt(LocTy, ValReg).getReg(0);
    300   }
    301   case CCValAssign::AExt: {
    302     return MIRBuilder.buildAnyExt(LocTy, ValReg).getReg(0);
    303   }
    304   // TODO : handle upper extends
    305   case CCValAssign::Full:
    306     return ValReg;
    307   default:
    308     break;
    309   }
    310   llvm_unreachable("unable to extend register");
    311 }
    312 
    313 bool MipsOutgoingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs,
    314                                            ArrayRef<CCValAssign> ArgLocs,
    315                                            unsigned ArgLocsStartIndex,
    316                                            Register ArgsReg, const EVT &VT) {
    317   MIRBuilder.buildUnmerge(VRegs, ArgsReg);
    318   setLeastSignificantFirst(VRegs);
    319   if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT))
    320     return false;
    321 
    322   return true;
    323 }
    324 
    325 static bool isSupportedArgumentType(Type *T) {
    326   if (T->isIntegerTy())
    327     return true;
    328   if (T->isPointerTy())
    329     return true;
    330   if (T->isFloatingPointTy())
    331     return true;
    332   return false;
    333 }
    334 
    335 static bool isSupportedReturnType(Type *T) {
    336   if (T->isIntegerTy())
    337     return true;
    338   if (T->isPointerTy())
    339     return true;
    340   if (T->isFloatingPointTy())
    341     return true;
    342   if (T->isAggregateType())
    343     return true;
    344   return false;
    345 }
    346 
    347 static CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT,
    348                                              const ISD::ArgFlagsTy &Flags) {
    349   // > does not mean loss of information as type RegisterVT can't hold type VT,
    350   // it means that type VT is split into multiple registers of type RegisterVT
    351   if (VT.getFixedSizeInBits() >= RegisterVT.getFixedSizeInBits())
    352     return CCValAssign::LocInfo::Full;
    353   if (Flags.isSExt())
    354     return CCValAssign::LocInfo::SExt;
    355   if (Flags.isZExt())
    356     return CCValAssign::LocInfo::ZExt;
    357   return CCValAssign::LocInfo::AExt;
    358 }
    359 
    360 template <typename T>
    361 static void setLocInfo(SmallVectorImpl<CCValAssign> &ArgLocs,
    362                        const SmallVectorImpl<T> &Arguments) {
    363   for (unsigned i = 0; i < ArgLocs.size(); ++i) {
    364     const CCValAssign &VA = ArgLocs[i];
    365     CCValAssign::LocInfo LocInfo = determineLocInfo(
    366         Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags);
    367     if (VA.isMemLoc())
    368       ArgLocs[i] =
    369           CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
    370                               VA.getLocMemOffset(), VA.getLocVT(), LocInfo);
    371     else
    372       ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
    373                                        VA.getLocReg(), VA.getLocVT(), LocInfo);
    374   }
    375 }
    376 
    377 bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
    378                                    const Value *Val, ArrayRef<Register> VRegs,
    379                                    FunctionLoweringInfo &FLI) const {
    380 
    381   MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
    382 
    383   if (Val != nullptr && !isSupportedReturnType(Val->getType()))
    384     return false;
    385 
    386   if (!VRegs.empty()) {
    387     MachineFunction &MF = MIRBuilder.getMF();
    388     const Function &F = MF.getFunction();
    389     const DataLayout &DL = MF.getDataLayout();
    390     const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
    391 
    392     SmallVector<ArgInfo, 8> RetInfos;
    393     SmallVector<unsigned, 8> OrigArgIndices;
    394 
    395     ArgInfo ArgRetInfo(VRegs, Val->getType());
    396     setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);
    397     splitToValueTypes(DL, ArgRetInfo, 0, RetInfos, OrigArgIndices);
    398 
    399     SmallVector<ISD::OutputArg, 8> Outs;
    400     subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs);
    401 
    402     SmallVector<CCValAssign, 16> ArgLocs;
    403     MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
    404                        F.getContext());
    405     CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn());
    406     setLocInfo(ArgLocs, Outs);
    407 
    408     MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
    409     if (!RetHandler.handle(ArgLocs, RetInfos)) {
    410       return false;
    411     }
    412   }
    413   MIRBuilder.insertInstr(Ret);
    414   return true;
    415 }
    416 
    417 bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
    418                                             const Function &F,
    419                                             ArrayRef<ArrayRef<Register>> VRegs,
    420                                             FunctionLoweringInfo &FLI) const {
    421 
    422   // Quick exit if there aren't any args.
    423   if (F.arg_empty())
    424     return true;
    425 
    426   for (auto &Arg : F.args()) {
    427     if (!isSupportedArgumentType(Arg.getType()))
    428       return false;
    429   }
    430 
    431   MachineFunction &MF = MIRBuilder.getMF();
    432   const DataLayout &DL = MF.getDataLayout();
    433   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
    434 
    435   SmallVector<ArgInfo, 8> ArgInfos;
    436   SmallVector<unsigned, 8> OrigArgIndices;
    437   unsigned i = 0;
    438   for (auto &Arg : F.args()) {
    439     ArgInfo AInfo(VRegs[i], Arg.getType());
    440     setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
    441     ArgInfos.push_back(AInfo);
    442     OrigArgIndices.push_back(i);
    443     ++i;
    444   }
    445 
    446   SmallVector<ISD::InputArg, 8> Ins;
    447   subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins);
    448 
    449   SmallVector<CCValAssign, 16> ArgLocs;
    450   MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
    451                      F.getContext());
    452 
    453   const MipsTargetMachine &TM =
    454       static_cast<const MipsTargetMachine &>(MF.getTarget());
    455   const MipsABIInfo &ABI = TM.getABI();
    456   CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
    457                        Align(1));
    458   CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());
    459   setLocInfo(ArgLocs, Ins);
    460 
    461   MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
    462   if (!Handler.handle(ArgLocs, ArgInfos))
    463     return false;
    464 
    465   if (F.isVarArg()) {
    466     ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
    467     unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
    468 
    469     int VaArgOffset;
    470     unsigned RegSize = 4;
    471     if (ArgRegs.size() == Idx)
    472       VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize);
    473     else {
    474       VaArgOffset =
    475           (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
    476           (int)(RegSize * (ArgRegs.size() - Idx));
    477     }
    478 
    479     MachineFrameInfo &MFI = MF.getFrameInfo();
    480     int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
    481     MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
    482 
    483     for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
    484       MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
    485 
    486       MachineInstrBuilder Copy =
    487           MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I]));
    488       FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
    489       MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI);
    490       MachineInstrBuilder FrameIndex =
    491           MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI);
    492       MachineMemOperand *MMO = MF.getMachineMemOperand(
    493           MPO, MachineMemOperand::MOStore, RegSize, Align(RegSize));
    494       MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
    495     }
    496   }
    497 
    498   return true;
    499 }
    500 
    501 bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
    502                                  CallLoweringInfo &Info) const {
    503 
    504   if (Info.CallConv != CallingConv::C)
    505     return false;
    506 
    507   for (auto &Arg : Info.OrigArgs) {
    508     if (!isSupportedArgumentType(Arg.Ty))
    509       return false;
    510     if (Arg.Flags[0].isByVal())
    511       return false;
    512     if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy())
    513       return false;
    514   }
    515 
    516   if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty))
    517     return false;
    518 
    519   MachineFunction &MF = MIRBuilder.getMF();
    520   const Function &F = MF.getFunction();
    521   const DataLayout &DL = MF.getDataLayout();
    522   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
    523   const MipsTargetMachine &TM =
    524       static_cast<const MipsTargetMachine &>(MF.getTarget());
    525   const MipsABIInfo &ABI = TM.getABI();
    526 
    527   MachineInstrBuilder CallSeqStart =
    528       MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
    529 
    530   const bool IsCalleeGlobalPIC =
    531       Info.Callee.isGlobal() && TM.isPositionIndependent();
    532 
    533   MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(
    534       Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL);
    535   MIB.addDef(Mips::SP, RegState::Implicit);
    536   if (IsCalleeGlobalPIC) {
    537     Register CalleeReg =
    538         MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32));
    539     MachineInstr *CalleeGlobalValue =
    540         MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal());
    541     if (!Info.Callee.getGlobal()->hasLocalLinkage())
    542       CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL);
    543     MIB.addUse(CalleeReg);
    544   } else
    545     MIB.add(Info.Callee);
    546   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
    547   MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
    548 
    549   TargetLowering::ArgListTy FuncOrigArgs;
    550   FuncOrigArgs.reserve(Info.OrigArgs.size());
    551 
    552   SmallVector<ArgInfo, 8> ArgInfos;
    553   SmallVector<unsigned, 8> OrigArgIndices;
    554   unsigned i = 0;
    555   for (auto &Arg : Info.OrigArgs) {
    556 
    557     TargetLowering::ArgListEntry Entry;
    558     Entry.Ty = Arg.Ty;
    559     FuncOrigArgs.push_back(Entry);
    560 
    561     ArgInfos.push_back(Arg);
    562     OrigArgIndices.push_back(i);
    563     ++i;
    564   }
    565 
    566   SmallVector<ISD::OutputArg, 8> Outs;
    567   subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
    568 
    569   SmallVector<CCValAssign, 8> ArgLocs;
    570   bool IsCalleeVarArg = false;
    571   if (Info.Callee.isGlobal()) {
    572     const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
    573     IsCalleeVarArg = CF->isVarArg();
    574   }
    575   MipsCCState CCInfo(F.getCallingConv(), IsCalleeVarArg, MF, ArgLocs,
    576                      F.getContext());
    577 
    578   CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv),
    579                        Align(1));
    580   const char *Call =
    581       Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr;
    582   CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
    583   setLocInfo(ArgLocs, Outs);
    584 
    585   MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
    586   if (!RetHandler.handle(ArgLocs, ArgInfos)) {
    587     return false;
    588   }
    589 
    590   unsigned NextStackOffset = CCInfo.getNextStackOffset();
    591   const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
    592   unsigned StackAlignment = TFL->getStackAlignment();
    593   NextStackOffset = alignTo(NextStackOffset, StackAlignment);
    594   CallSeqStart.addImm(NextStackOffset).addImm(0);
    595 
    596   if (IsCalleeGlobalPIC) {
    597     MIRBuilder.buildCopy(
    598       Register(Mips::GP),
    599       MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel(MF));
    600     MIB.addDef(Mips::GP, RegState::Implicit);
    601   }
    602   MIRBuilder.insertInstr(MIB);
    603   if (MIB->getOpcode() == Mips::JALRPseudo) {
    604     const MipsSubtarget &STI =
    605         static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
    606     MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
    607                          *STI.getRegBankInfo());
    608   }
    609 
    610   if (!Info.OrigRet.Ty->isVoidTy()) {
    611     ArgInfos.clear();
    612     SmallVector<unsigned, 8> OrigRetIndices;
    613 
    614     splitToValueTypes(DL, Info.OrigRet, 0, ArgInfos, OrigRetIndices);
    615 
    616     SmallVector<ISD::InputArg, 8> Ins;
    617     subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins);
    618 
    619     SmallVector<CCValAssign, 8> ArgLocs;
    620     MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
    621                        F.getContext());
    622 
    623     CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), Info.OrigRet.Ty,
    624                              Call);
    625     setLocInfo(ArgLocs, Ins);
    626 
    627     CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB);
    628     if (!Handler.handle(ArgLocs, ArgInfos))
    629       return false;
    630   }
    631 
    632   MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0);
    633 
    634   return true;
    635 }
    636 
    637 template <typename T>
    638 void MipsCallLowering::subTargetRegTypeForCallingConv(
    639     const Function &F, ArrayRef<ArgInfo> Args,
    640     ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
    641   const DataLayout &DL = F.getParent()->getDataLayout();
    642   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
    643 
    644   unsigned ArgNo = 0;
    645   for (auto &Arg : Args) {
    646 
    647     EVT VT = TLI.getValueType(DL, Arg.Ty);
    648     MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
    649                                                        F.getCallingConv(), VT);
    650     unsigned NumRegs = TLI.getNumRegistersForCallingConv(
    651         F.getContext(), F.getCallingConv(), VT);
    652 
    653     for (unsigned i = 0; i < NumRegs; ++i) {
    654       ISD::ArgFlagsTy Flags = Arg.Flags[0];
    655 
    656       if (i == 0)
    657         Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
    658       else
    659         Flags.setOrigAlign(Align(1));
    660 
    661       ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
    662                            0);
    663     }
    664     ++ArgNo;
    665   }
    666 }
    667 
    668 // FIXME: This should be removed and the generic version used
    669 void MipsCallLowering::splitToValueTypes(
    670     const DataLayout &DL, const ArgInfo &OrigArg, unsigned OriginalIndex,
    671     SmallVectorImpl<ArgInfo> &SplitArgs,
    672     SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const {
    673 
    674   SmallVector<EVT, 4> SplitEVTs;
    675   SmallVector<Register, 4> SplitVRegs;
    676   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
    677   LLVMContext &Ctx = OrigArg.Ty->getContext();
    678 
    679   ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitEVTs);
    680 
    681   for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
    682     ArgInfo Info = ArgInfo{OrigArg.Regs[i], SplitEVTs[i].getTypeForEVT(Ctx)};
    683     Info.Flags = OrigArg.Flags;
    684     SplitArgs.push_back(Info);
    685     SplitArgsOrigIndices.push_back(OriginalIndex);
    686   }
    687 }
    688