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 415 MachineInstrBuilder Copy = 416 MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I])); 417 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); 418 MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI); 419 MachineInstrBuilder FrameIndex = 420 MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI); 421 MachineMemOperand *MMO = MF.getMachineMemOperand( 422 MPO, MachineMemOperand::MOStore, RegSize, Align(RegSize)); 423 MIRBuilder.buildStore(Copy, FrameIndex, *MMO); 424 } 425 } 426 427 return true; 428 } 429 430 bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 431 CallLoweringInfo &Info) const { 432 433 if (Info.CallConv != CallingConv::C) 434 return false; 435 436 for (auto &Arg : Info.OrigArgs) { 437 if (!isSupportedArgumentType(Arg.Ty)) 438 return false; 439 if (Arg.Flags[0].isByVal()) 440 return false; 441 if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy()) 442 return false; 443 } 444 445 if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty)) 446 return false; 447 448 MachineFunction &MF = MIRBuilder.getMF(); 449 const Function &F = MF.getFunction(); 450 const DataLayout &DL = MF.getDataLayout(); 451 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 452 const MipsTargetMachine &TM = 453 static_cast<const MipsTargetMachine &>(MF.getTarget()); 454 const MipsABIInfo &ABI = TM.getABI(); 455 456 MachineInstrBuilder CallSeqStart = 457 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN); 458 459 const bool IsCalleeGlobalPIC = 460 Info.Callee.isGlobal() && TM.isPositionIndependent(); 461 462 MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert( 463 Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL); 464 MIB.addDef(Mips::SP, RegState::Implicit); 465 if (IsCalleeGlobalPIC) { 466 Register CalleeReg = 467 MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32)); 468 MachineInstr *CalleeGlobalValue = 469 MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal()); 470 if (!Info.Callee.getGlobal()->hasLocalLinkage()) 471 CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL); 472 MIB.addUse(CalleeReg); 473 } else 474 MIB.add(Info.Callee); 475 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 476 MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv)); 477 478 TargetLowering::ArgListTy FuncOrigArgs; 479 FuncOrigArgs.reserve(Info.OrigArgs.size()); 480 481 SmallVector<ArgInfo, 8> ArgInfos; 482 for (auto &Arg : Info.OrigArgs) 483 splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv); 484 485 SmallVector<CCValAssign, 8> ArgLocs; 486 bool IsCalleeVarArg = false; 487 if (Info.Callee.isGlobal()) { 488 const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal()); 489 IsCalleeVarArg = CF->isVarArg(); 490 } 491 492 // FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it 493 // depends on looking directly at the call target. 494 MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs, 495 F.getContext()); 496 497 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), 498 Align(1)); 499 500 const char *Call = 501 Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr; 502 503 MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForCall(), Call, 504 /*IsReturn*/ false); 505 if (!determineAssignments(Assigner, ArgInfos, CCInfo)) 506 return false; 507 508 MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB); 509 if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) 510 return false; 511 512 unsigned NextStackOffset = CCInfo.getNextStackOffset(); 513 unsigned StackAlignment = F.getParent()->getOverrideStackAlignment(); 514 if (!StackAlignment) { 515 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); 516 StackAlignment = TFL->getStackAlignment(); 517 } 518 NextStackOffset = alignTo(NextStackOffset, StackAlignment); 519 CallSeqStart.addImm(NextStackOffset).addImm(0); 520 521 if (IsCalleeGlobalPIC) { 522 MIRBuilder.buildCopy( 523 Register(Mips::GP), 524 MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel(MF)); 525 MIB.addDef(Mips::GP, RegState::Implicit); 526 } 527 MIRBuilder.insertInstr(MIB); 528 if (MIB->getOpcode() == Mips::JALRPseudo) { 529 const MipsSubtarget &STI = 530 static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); 531 MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), 532 *STI.getRegBankInfo()); 533 } 534 535 if (!Info.OrigRet.Ty->isVoidTy()) { 536 ArgInfos.clear(); 537 538 CallLowering::splitToValueTypes(Info.OrigRet, ArgInfos, DL, 539 F.getCallingConv()); 540 541 const std::string FuncName = F.getName().str(); 542 SmallVector<ISD::InputArg, 8> Ins; 543 SmallVector<CCValAssign, 8> ArgLocs; 544 MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForReturn(), 545 FuncName.c_str(), 546 /*IsReturn*/ true); 547 CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB); 548 549 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, 550 F.getContext()); 551 552 if (!determineAssignments(Assigner, ArgInfos, CCInfo)) 553 return false; 554 555 if (!handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) 556 return false; 557 } 558 559 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0); 560 561 return true; 562 } 563