xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsCallLowering.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 #include "llvm/CodeGen/MachineFrameInfo.h"
22 
23 using namespace llvm;
24 
MipsCallLowering(const MipsTargetLowering & TLI)25 MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI)
26     : CallLowering(&TLI) {}
27 
28 namespace {
29 struct MipsOutgoingValueAssigner : public CallLowering::OutgoingValueAssigner {
30   /// This is the name of the function being called
31   /// FIXME: Relying on this is unsound
32   const char *Func = nullptr;
33 
34   /// Is this a return value, or an outgoing call operand.
35   bool IsReturn;
36 
MipsOutgoingValueAssigner__anon76a11c0a0111::MipsOutgoingValueAssigner37   MipsOutgoingValueAssigner(CCAssignFn *AssignFn_, const char *Func,
38                             bool IsReturn)
39       : OutgoingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {}
40 
assignArg__anon76a11c0a0111::MipsOutgoingValueAssigner41   bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
42                  CCValAssign::LocInfo LocInfo,
43                  const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
44                  CCState &State_) override {
45     MipsCCState &State = static_cast<MipsCCState &>(State_);
46 
47     if (IsReturn)
48       State.PreAnalyzeReturnValue(EVT::getEVT(Info.Ty));
49     else
50       State.PreAnalyzeCallOperand(Info.Ty, Info.IsFixed, Func);
51 
52     return CallLowering::OutgoingValueAssigner::assignArg(
53         ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State);
54   }
55 };
56 
57 struct MipsIncomingValueAssigner : public CallLowering::IncomingValueAssigner {
58   /// This is the name of the function being called
59   /// FIXME: Relying on this is unsound
60   const char *Func = nullptr;
61 
62   /// Is this a call return value, or an incoming function argument.
63   bool IsReturn;
64 
MipsIncomingValueAssigner__anon76a11c0a0111::MipsIncomingValueAssigner65   MipsIncomingValueAssigner(CCAssignFn *AssignFn_, const char *Func,
66                             bool IsReturn)
67       : IncomingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {}
68 
assignArg__anon76a11c0a0111::MipsIncomingValueAssigner69   bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
70                  CCValAssign::LocInfo LocInfo,
71                  const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
72                  CCState &State_) override {
73     MipsCCState &State = static_cast<MipsCCState &>(State_);
74 
75     if (IsReturn)
76       State.PreAnalyzeCallResult(Info.Ty, Func);
77     else
78       State.PreAnalyzeFormalArgument(Info.Ty, Flags);
79 
80     return CallLowering::IncomingValueAssigner::assignArg(
81         ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State);
82   }
83 };
84 
85 class MipsIncomingValueHandler : public CallLowering::IncomingValueHandler {
86   const MipsSubtarget &STI;
87 
88 public:
MipsIncomingValueHandler(MachineIRBuilder & MIRBuilder,MachineRegisterInfo & MRI)89   MipsIncomingValueHandler(MachineIRBuilder &MIRBuilder,
90                            MachineRegisterInfo &MRI)
91       : IncomingValueHandler(MIRBuilder, MRI),
92         STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()) {}
93 
94 private:
95   void assignValueToReg(Register ValVReg, Register PhysReg,
96                         const CCValAssign &VA) override;
97 
98   Register getStackAddress(uint64_t Size, int64_t Offset,
99                            MachinePointerInfo &MPO,
100                            ISD::ArgFlagsTy Flags) override;
101   void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
102                             const MachinePointerInfo &MPO,
103                             const CCValAssign &VA) override;
104 
105   unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
106                              ArrayRef<CCValAssign> VAs,
107                              std::function<void()> *Thunk = nullptr) override;
108 
markPhysRegUsed(unsigned PhysReg)109   virtual void markPhysRegUsed(unsigned PhysReg) {
110     MIRBuilder.getMRI()->addLiveIn(PhysReg);
111     MIRBuilder.getMBB().addLiveIn(PhysReg);
112   }
113 };
114 
115 class CallReturnHandler : public MipsIncomingValueHandler {
116 public:
CallReturnHandler(MachineIRBuilder & MIRBuilder,MachineRegisterInfo & MRI,MachineInstrBuilder & MIB)117   CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
118                     MachineInstrBuilder &MIB)
119       : MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
120 
121 private:
markPhysRegUsed(unsigned PhysReg)122   void markPhysRegUsed(unsigned PhysReg) override {
123     MIB.addDef(PhysReg, RegState::Implicit);
124   }
125 
126   MachineInstrBuilder &MIB;
127 };
128 
129 } // end anonymous namespace
130 
assignValueToReg(Register ValVReg,Register PhysReg,const CCValAssign & VA)131 void MipsIncomingValueHandler::assignValueToReg(Register ValVReg,
132                                                 Register PhysReg,
133                                                 const CCValAssign &VA) {
134   markPhysRegUsed(PhysReg);
135   IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
136 }
137 
getStackAddress(uint64_t Size,int64_t Offset,MachinePointerInfo & MPO,ISD::ArgFlagsTy Flags)138 Register MipsIncomingValueHandler::getStackAddress(uint64_t Size,
139                                                    int64_t Offset,
140                                                    MachinePointerInfo &MPO,
141                                                    ISD::ArgFlagsTy Flags) {
142 
143   MachineFunction &MF = MIRBuilder.getMF();
144   MachineFrameInfo &MFI = MF.getFrameInfo();
145 
146   // FIXME: This should only be immutable for non-byval memory arguments.
147   int FI = MFI.CreateFixedObject(Size, Offset, true);
148   MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
149 
150   return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0);
151 }
152 
assignValueToAddress(Register ValVReg,Register Addr,LLT MemTy,const MachinePointerInfo & MPO,const CCValAssign & VA)153 void MipsIncomingValueHandler::assignValueToAddress(
154     Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
155     const CCValAssign &VA) {
156   MachineFunction &MF = MIRBuilder.getMF();
157   auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
158                                      inferAlignFromPtrInfo(MF, MPO));
159   MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
160 }
161 
162 /// Handle cases when f64 is split into 2 32-bit GPRs. This is a custom
163 /// assignment because generic code assumes getNumRegistersForCallingConv is
164 /// accurate. In this case it is not because the type/number are context
165 /// dependent on other arguments.
166 unsigned
assignCustomValue(CallLowering::ArgInfo & Arg,ArrayRef<CCValAssign> VAs,std::function<void ()> * Thunk)167 MipsIncomingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
168                                             ArrayRef<CCValAssign> VAs,
169                                             std::function<void()> *Thunk) {
170   const CCValAssign &VALo = VAs[0];
171   const CCValAssign &VAHi = VAs[1];
172 
173   assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
174          VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
175          "unexpected custom value");
176 
177   auto CopyLo = MIRBuilder.buildCopy(LLT::scalar(32), VALo.getLocReg());
178   auto CopyHi = MIRBuilder.buildCopy(LLT::scalar(32), VAHi.getLocReg());
179   if (!STI.isLittle())
180     std::swap(CopyLo, CopyHi);
181 
182   Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
183   Arg.Regs = { CopyLo.getReg(0), CopyHi.getReg(0) };
184   MIRBuilder.buildMergeLikeInstr(Arg.OrigRegs[0], {CopyLo, CopyHi});
185 
186   markPhysRegUsed(VALo.getLocReg());
187   markPhysRegUsed(VAHi.getLocReg());
188   return 2;
189 }
190 
191 namespace {
192 class MipsOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
193   const MipsSubtarget &STI;
194 
195 public:
MipsOutgoingValueHandler(MachineIRBuilder & MIRBuilder,MachineRegisterInfo & MRI,MachineInstrBuilder & MIB)196   MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
197                            MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)
198       : OutgoingValueHandler(MIRBuilder, MRI),
199         STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()), MIB(MIB) {}
200 
201 private:
202   void assignValueToReg(Register ValVReg, Register PhysReg,
203                         const CCValAssign &VA) override;
204 
205   Register getStackAddress(uint64_t Size, int64_t Offset,
206                            MachinePointerInfo &MPO,
207                            ISD::ArgFlagsTy Flags) override;
208 
209   void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
210                             const MachinePointerInfo &MPO,
211                             const CCValAssign &VA) override;
212   unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
213                              ArrayRef<CCValAssign> VAs,
214                              std::function<void()> *Thunk) override;
215 
216   MachineInstrBuilder &MIB;
217 };
218 } // end anonymous namespace
219 
assignValueToReg(Register ValVReg,Register PhysReg,const CCValAssign & VA)220 void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg,
221                                                 Register PhysReg,
222                                                 const CCValAssign &VA) {
223   Register ExtReg = extendRegister(ValVReg, VA);
224   MIRBuilder.buildCopy(PhysReg, ExtReg);
225   MIB.addUse(PhysReg, RegState::Implicit);
226 }
227 
getStackAddress(uint64_t Size,int64_t Offset,MachinePointerInfo & MPO,ISD::ArgFlagsTy Flags)228 Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size,
229                                                    int64_t Offset,
230                                                    MachinePointerInfo &MPO,
231                                                    ISD::ArgFlagsTy Flags) {
232   MachineFunction &MF = MIRBuilder.getMF();
233   MPO = MachinePointerInfo::getStack(MF, Offset);
234 
235   LLT p0 = LLT::pointer(0, 32);
236   LLT s32 = LLT::scalar(32);
237   auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP));
238 
239   auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);
240   auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
241   return AddrReg.getReg(0);
242 }
243 
assignValueToAddress(Register ValVReg,Register Addr,LLT MemTy,const MachinePointerInfo & MPO,const CCValAssign & VA)244 void MipsOutgoingValueHandler::assignValueToAddress(
245     Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
246     const CCValAssign &VA) {
247   MachineFunction &MF = MIRBuilder.getMF();
248   uint64_t LocMemOffset = VA.getLocMemOffset();
249 
250   auto MMO = MF.getMachineMemOperand(
251       MPO, MachineMemOperand::MOStore, MemTy,
252       commonAlignment(STI.getStackAlignment(), LocMemOffset));
253 
254   Register ExtReg = extendRegister(ValVReg, VA);
255   MIRBuilder.buildStore(ExtReg, Addr, *MMO);
256 }
257 
258 unsigned
assignCustomValue(CallLowering::ArgInfo & Arg,ArrayRef<CCValAssign> VAs,std::function<void ()> * Thunk)259 MipsOutgoingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
260                                             ArrayRef<CCValAssign> VAs,
261                                             std::function<void()> *Thunk) {
262   const CCValAssign &VALo = VAs[0];
263   const CCValAssign &VAHi = VAs[1];
264 
265   assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
266          VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
267          "unexpected custom value");
268 
269   auto Unmerge =
270       MIRBuilder.buildUnmerge({LLT::scalar(32), LLT::scalar(32)}, Arg.Regs[0]);
271   Register Lo = Unmerge.getReg(0);
272   Register Hi = Unmerge.getReg(1);
273 
274   Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
275   Arg.Regs = { Lo, Hi };
276   if (!STI.isLittle())
277     std::swap(Lo, Hi);
278 
279   // If we can return a thunk, just include the register copies. The unmerge can
280   // be emitted earlier.
281   if (Thunk) {
282     *Thunk = [=]() {
283       MIRBuilder.buildCopy(VALo.getLocReg(), Lo);
284       MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);
285     };
286     return 2;
287   }
288   MIRBuilder.buildCopy(VALo.getLocReg(), Lo);
289   MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);
290   return 2;
291 }
292 
isSupportedArgumentType(Type * T)293 static bool isSupportedArgumentType(Type *T) {
294   if (T->isIntegerTy())
295     return true;
296   if (T->isPointerTy())
297     return true;
298   if (T->isFloatingPointTy())
299     return true;
300   return false;
301 }
302 
isSupportedReturnType(Type * T)303 static bool isSupportedReturnType(Type *T) {
304   if (T->isIntegerTy())
305     return true;
306   if (T->isPointerTy())
307     return true;
308   if (T->isFloatingPointTy())
309     return true;
310   if (T->isAggregateType())
311     return true;
312   return false;
313 }
314 
lowerReturn(MachineIRBuilder & MIRBuilder,const Value * Val,ArrayRef<Register> VRegs,FunctionLoweringInfo & FLI) const315 bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
316                                    const Value *Val, ArrayRef<Register> VRegs,
317                                    FunctionLoweringInfo &FLI) const {
318 
319   MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
320 
321   if (Val != nullptr && !isSupportedReturnType(Val->getType()))
322     return false;
323 
324   if (!VRegs.empty()) {
325     MachineFunction &MF = MIRBuilder.getMF();
326     const Function &F = MF.getFunction();
327     const DataLayout &DL = MF.getDataLayout();
328     const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
329 
330     SmallVector<ArgInfo, 8> RetInfos;
331 
332     ArgInfo ArgRetInfo(VRegs, *Val, 0);
333     setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);
334     splitToValueTypes(ArgRetInfo, RetInfos, DL, F.getCallingConv());
335 
336     SmallVector<CCValAssign, 16> ArgLocs;
337 
338     MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
339                        F.getContext());
340 
341     MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
342     std::string FuncName = F.getName().str();
343     MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForReturn(),
344                                        FuncName.c_str(), /*IsReturn*/ true);
345 
346     if (!determineAssignments(Assigner, RetInfos, CCInfo))
347       return false;
348 
349     if (!handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder))
350       return false;
351   }
352 
353   MIRBuilder.insertInstr(Ret);
354   return true;
355 }
356 
lowerFormalArguments(MachineIRBuilder & MIRBuilder,const Function & F,ArrayRef<ArrayRef<Register>> VRegs,FunctionLoweringInfo & FLI) const357 bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
358                                             const Function &F,
359                                             ArrayRef<ArrayRef<Register>> VRegs,
360                                             FunctionLoweringInfo &FLI) const {
361 
362   // Quick exit if there aren't any args.
363   if (F.arg_empty())
364     return true;
365 
366   for (auto &Arg : F.args()) {
367     if (!isSupportedArgumentType(Arg.getType()))
368       return false;
369   }
370 
371   MachineFunction &MF = MIRBuilder.getMF();
372   const DataLayout &DL = MF.getDataLayout();
373   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
374 
375   SmallVector<ArgInfo, 8> ArgInfos;
376   unsigned i = 0;
377   for (auto &Arg : F.args()) {
378     ArgInfo AInfo(VRegs[i], Arg, i);
379     setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
380 
381     splitToValueTypes(AInfo, ArgInfos, DL, F.getCallingConv());
382     ++i;
383   }
384 
385   SmallVector<CCValAssign, 16> ArgLocs;
386   MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
387                      F.getContext());
388 
389   const MipsTargetMachine &TM =
390       static_cast<const MipsTargetMachine &>(MF.getTarget());
391   const MipsABIInfo &ABI = TM.getABI();
392   CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
393                        Align(1));
394 
395   const std::string FuncName = F.getName().str();
396   MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForCall(), FuncName.c_str(),
397                                      /*IsReturn*/ false);
398   if (!determineAssignments(Assigner, ArgInfos, CCInfo))
399     return false;
400 
401   MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
402   if (!handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
403     return false;
404 
405   if (F.isVarArg()) {
406     ArrayRef<MCPhysReg> ArgRegs =
407         ABI.getVarArgRegs(MF.getSubtarget<MipsSubtarget>().isGP64bit());
408     unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
409 
410     int VaArgOffset;
411     unsigned RegSize = 4;
412     if (ArgRegs.size() == Idx)
413       VaArgOffset = alignTo(CCInfo.getStackSize(), RegSize);
414     else {
415       VaArgOffset =
416           (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
417           (int)(RegSize * (ArgRegs.size() - Idx));
418     }
419 
420     MachineFrameInfo &MFI = MF.getFrameInfo();
421     int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
422     MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
423 
424     for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
425       MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
426       LLT RegTy = LLT::scalar(RegSize * 8);
427       MachineInstrBuilder Copy =
428           MIRBuilder.buildCopy(RegTy, Register(ArgRegs[I]));
429       FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
430       MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI);
431 
432       const LLT PtrTy = LLT::pointer(MPO.getAddrSpace(), 32);
433       auto FrameIndex = MIRBuilder.buildFrameIndex(PtrTy, FI);
434       MachineMemOperand *MMO = MF.getMachineMemOperand(
435           MPO, MachineMemOperand::MOStore, RegTy, Align(RegSize));
436       MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
437     }
438   }
439 
440   return true;
441 }
442 
lowerCall(MachineIRBuilder & MIRBuilder,CallLoweringInfo & Info) const443 bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
444                                  CallLoweringInfo &Info) const {
445 
446   if (Info.CallConv != CallingConv::C)
447     return false;
448 
449   for (auto &Arg : Info.OrigArgs) {
450     if (!isSupportedArgumentType(Arg.Ty))
451       return false;
452     if (Arg.Flags[0].isByVal())
453       return false;
454     if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy())
455       return false;
456   }
457 
458   if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty))
459     return false;
460 
461   MachineFunction &MF = MIRBuilder.getMF();
462   const Function &F = MF.getFunction();
463   const DataLayout &DL = MF.getDataLayout();
464   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
465   const MipsTargetMachine &TM =
466       static_cast<const MipsTargetMachine &>(MF.getTarget());
467   const MipsABIInfo &ABI = TM.getABI();
468 
469   MachineInstrBuilder CallSeqStart =
470       MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
471 
472   const bool IsCalleeGlobalPIC =
473       Info.Callee.isGlobal() && TM.isPositionIndependent();
474 
475   MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(
476       Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL);
477   MIB.addDef(Mips::SP, RegState::Implicit);
478   if (IsCalleeGlobalPIC) {
479     Register CalleeReg =
480         MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32));
481     MachineInstr *CalleeGlobalValue =
482         MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal());
483     if (!Info.Callee.getGlobal()->hasLocalLinkage())
484       CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL);
485     MIB.addUse(CalleeReg);
486   } else
487     MIB.add(Info.Callee);
488   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
489   MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
490 
491   TargetLowering::ArgListTy FuncOrigArgs;
492   FuncOrigArgs.reserve(Info.OrigArgs.size());
493 
494   SmallVector<ArgInfo, 8> ArgInfos;
495   for (auto &Arg : Info.OrigArgs)
496     splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
497 
498   SmallVector<CCValAssign, 8> ArgLocs;
499   bool IsCalleeVarArg = false;
500   if (Info.Callee.isGlobal()) {
501     const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
502     IsCalleeVarArg = CF->isVarArg();
503   }
504 
505   // FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it
506   // depends on looking directly at the call target.
507   MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs,
508                      F.getContext());
509 
510   CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv),
511                        Align(1));
512 
513   const char *Call =
514       Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr;
515 
516   MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForCall(), Call,
517                                      /*IsReturn*/ false);
518   if (!determineAssignments(Assigner, ArgInfos, CCInfo))
519     return false;
520 
521   MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB);
522   if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
523     return false;
524 
525   unsigned StackSize = CCInfo.getStackSize();
526   unsigned StackAlignment = F.getParent()->getOverrideStackAlignment();
527   if (!StackAlignment) {
528     const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
529     StackAlignment = TFL->getStackAlignment();
530   }
531   StackSize = alignTo(StackSize, StackAlignment);
532   CallSeqStart.addImm(StackSize).addImm(0);
533 
534   if (IsCalleeGlobalPIC) {
535     MIRBuilder.buildCopy(
536       Register(Mips::GP),
537       MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel(MF));
538     MIB.addDef(Mips::GP, RegState::Implicit);
539   }
540   MIRBuilder.insertInstr(MIB);
541   if (MIB->getOpcode() == Mips::JALRPseudo) {
542     const MipsSubtarget &STI = MIRBuilder.getMF().getSubtarget<MipsSubtarget>();
543     MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
544                          *STI.getRegBankInfo());
545   }
546 
547   if (!Info.OrigRet.Ty->isVoidTy()) {
548     ArgInfos.clear();
549 
550     CallLowering::splitToValueTypes(Info.OrigRet, ArgInfos, DL,
551                                     F.getCallingConv());
552 
553     const std::string FuncName = F.getName().str();
554     SmallVector<CCValAssign, 8> ArgLocs;
555     MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForReturn(),
556                                        FuncName.c_str(),
557                                        /*IsReturn*/ true);
558     CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
559 
560     MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
561                        F.getContext());
562 
563     if (!determineAssignments(Assigner, ArgInfos, CCInfo))
564       return false;
565 
566     if (!handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
567       return false;
568   }
569 
570   MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(StackSize).addImm(0);
571 
572   return true;
573 }
574