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