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