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 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 37 MipsOutgoingValueAssigner(CCAssignFn *AssignFn_, const char *Func, 38 bool IsReturn) 39 : OutgoingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {} 40 41 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 65 MipsIncomingValueAssigner(CCAssignFn *AssignFn_, const char *Func, 66 bool IsReturn) 67 : IncomingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {} 68 69 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: 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 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 MachinePointerInfo &MPO, CCValAssign &VA) override; 103 104 unsigned assignCustomValue(CallLowering::ArgInfo &Arg, 105 ArrayRef<CCValAssign> VAs, 106 std::function<void()> *Thunk = nullptr) override; 107 108 virtual void markPhysRegUsed(unsigned PhysReg) { 109 MIRBuilder.getMRI()->addLiveIn(PhysReg); 110 MIRBuilder.getMBB().addLiveIn(PhysReg); 111 } 112 }; 113 114 class CallReturnHandler : public MipsIncomingValueHandler { 115 public: 116 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 117 MachineInstrBuilder &MIB) 118 : MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {} 119 120 private: 121 void markPhysRegUsed(unsigned PhysReg) override { 122 MIB.addDef(PhysReg, RegState::Implicit); 123 } 124 125 MachineInstrBuilder &MIB; 126 }; 127 128 } // end anonymous namespace 129 130 void MipsIncomingValueHandler::assignValueToReg(Register ValVReg, 131 Register PhysReg, 132 CCValAssign VA) { 133 markPhysRegUsed(PhysReg); 134 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 135 } 136 137 Register MipsIncomingValueHandler::getStackAddress(uint64_t Size, 138 int64_t Offset, 139 MachinePointerInfo &MPO, 140 ISD::ArgFlagsTy Flags) { 141 142 MachineFunction &MF = MIRBuilder.getMF(); 143 MachineFrameInfo &MFI = MF.getFrameInfo(); 144 145 // FIXME: This should only be immutable for non-byval memory arguments. 146 int FI = MFI.CreateFixedObject(Size, Offset, true); 147 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 148 149 return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0); 150 } 151 152 void MipsIncomingValueHandler::assignValueToAddress(Register ValVReg, 153 Register Addr, LLT MemTy, 154 MachinePointerInfo &MPO, 155 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 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: 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 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 MachinePointerInfo &MPO, CCValAssign &VA) override; 211 unsigned assignCustomValue(CallLowering::ArgInfo &Arg, 212 ArrayRef<CCValAssign> VAs, 213 std::function<void()> *Thunk) override; 214 215 MachineInstrBuilder &MIB; 216 }; 217 } // end anonymous namespace 218 219 void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg, 220 Register PhysReg, 221 CCValAssign VA) { 222 Register ExtReg = extendRegister(ValVReg, VA); 223 MIRBuilder.buildCopy(PhysReg, ExtReg); 224 MIB.addUse(PhysReg, RegState::Implicit); 225 } 226 227 Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size, 228 int64_t Offset, 229 MachinePointerInfo &MPO, 230 ISD::ArgFlagsTy Flags) { 231 MachineFunction &MF = MIRBuilder.getMF(); 232 MPO = MachinePointerInfo::getStack(MF, Offset); 233 234 LLT p0 = LLT::pointer(0, 32); 235 LLT s32 = LLT::scalar(32); 236 auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP)); 237 238 auto OffsetReg = MIRBuilder.buildConstant(s32, Offset); 239 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg); 240 return AddrReg.getReg(0); 241 } 242 243 void MipsOutgoingValueHandler::assignValueToAddress(Register ValVReg, 244 Register Addr, LLT MemTy, 245 MachinePointerInfo &MPO, 246 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 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 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 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 315 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 SmallVector<ISD::OutputArg, 8> Outs; 338 339 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, 340 F.getContext()); 341 342 MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret); 343 std::string FuncName = F.getName().str(); 344 MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForReturn(), 345 FuncName.c_str(), /*IsReturn*/ true); 346 347 if (!determineAssignments(Assigner, RetInfos, CCInfo)) 348 return false; 349 350 if (!handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder)) 351 return false; 352 } 353 354 MIRBuilder.insertInstr(Ret); 355 return true; 356 } 357 358 bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 359 const Function &F, 360 ArrayRef<ArrayRef<Register>> VRegs, 361 FunctionLoweringInfo &FLI) const { 362 363 // Quick exit if there aren't any args. 364 if (F.arg_empty()) 365 return true; 366 367 for (auto &Arg : F.args()) { 368 if (!isSupportedArgumentType(Arg.getType())) 369 return false; 370 } 371 372 MachineFunction &MF = MIRBuilder.getMF(); 373 const DataLayout &DL = MF.getDataLayout(); 374 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 375 376 SmallVector<ArgInfo, 8> ArgInfos; 377 unsigned i = 0; 378 for (auto &Arg : F.args()) { 379 ArgInfo AInfo(VRegs[i], Arg, i); 380 setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F); 381 382 splitToValueTypes(AInfo, ArgInfos, DL, F.getCallingConv()); 383 ++i; 384 } 385 386 SmallVector<ISD::InputArg, 8> Ins; 387 388 SmallVector<CCValAssign, 16> ArgLocs; 389 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, 390 F.getContext()); 391 392 const MipsTargetMachine &TM = 393 static_cast<const MipsTargetMachine &>(MF.getTarget()); 394 const MipsABIInfo &ABI = TM.getABI(); 395 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()), 396 Align(1)); 397 398 const std::string FuncName = F.getName().str(); 399 MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForCall(), FuncName.c_str(), 400 /*IsReturn*/ false); 401 if (!determineAssignments(Assigner, ArgInfos, CCInfo)) 402 return false; 403 404 MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo()); 405 if (!handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) 406 return false; 407 408 if (F.isVarArg()) { 409 ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs(); 410 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs); 411 412 int VaArgOffset; 413 unsigned RegSize = 4; 414 if (ArgRegs.size() == Idx) 415 VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize); 416 else { 417 VaArgOffset = 418 (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) - 419 (int)(RegSize * (ArgRegs.size() - Idx)); 420 } 421 422 MachineFrameInfo &MFI = MF.getFrameInfo(); 423 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); 424 MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI); 425 426 for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) { 427 MIRBuilder.getMBB().addLiveIn(ArgRegs[I]); 428 LLT RegTy = LLT::scalar(RegSize * 8); 429 MachineInstrBuilder Copy = 430 MIRBuilder.buildCopy(RegTy, Register(ArgRegs[I])); 431 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); 432 MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI); 433 434 const LLT PtrTy = LLT::pointer(MPO.getAddrSpace(), 32); 435 auto FrameIndex = MIRBuilder.buildFrameIndex(PtrTy, FI); 436 MachineMemOperand *MMO = MF.getMachineMemOperand( 437 MPO, MachineMemOperand::MOStore, RegTy, Align(RegSize)); 438 MIRBuilder.buildStore(Copy, FrameIndex, *MMO); 439 } 440 } 441 442 return true; 443 } 444 445 bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 446 CallLoweringInfo &Info) const { 447 448 if (Info.CallConv != CallingConv::C) 449 return false; 450 451 for (auto &Arg : Info.OrigArgs) { 452 if (!isSupportedArgumentType(Arg.Ty)) 453 return false; 454 if (Arg.Flags[0].isByVal()) 455 return false; 456 if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy()) 457 return false; 458 } 459 460 if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty)) 461 return false; 462 463 MachineFunction &MF = MIRBuilder.getMF(); 464 const Function &F = MF.getFunction(); 465 const DataLayout &DL = MF.getDataLayout(); 466 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 467 const MipsTargetMachine &TM = 468 static_cast<const MipsTargetMachine &>(MF.getTarget()); 469 const MipsABIInfo &ABI = TM.getABI(); 470 471 MachineInstrBuilder CallSeqStart = 472 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN); 473 474 const bool IsCalleeGlobalPIC = 475 Info.Callee.isGlobal() && TM.isPositionIndependent(); 476 477 MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert( 478 Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL); 479 MIB.addDef(Mips::SP, RegState::Implicit); 480 if (IsCalleeGlobalPIC) { 481 Register CalleeReg = 482 MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32)); 483 MachineInstr *CalleeGlobalValue = 484 MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal()); 485 if (!Info.Callee.getGlobal()->hasLocalLinkage()) 486 CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL); 487 MIB.addUse(CalleeReg); 488 } else 489 MIB.add(Info.Callee); 490 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 491 MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv)); 492 493 TargetLowering::ArgListTy FuncOrigArgs; 494 FuncOrigArgs.reserve(Info.OrigArgs.size()); 495 496 SmallVector<ArgInfo, 8> ArgInfos; 497 for (auto &Arg : Info.OrigArgs) 498 splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv); 499 500 SmallVector<CCValAssign, 8> ArgLocs; 501 bool IsCalleeVarArg = false; 502 if (Info.Callee.isGlobal()) { 503 const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal()); 504 IsCalleeVarArg = CF->isVarArg(); 505 } 506 507 // FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it 508 // depends on looking directly at the call target. 509 MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs, 510 F.getContext()); 511 512 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), 513 Align(1)); 514 515 const char *Call = 516 Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr; 517 518 MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForCall(), Call, 519 /*IsReturn*/ false); 520 if (!determineAssignments(Assigner, ArgInfos, CCInfo)) 521 return false; 522 523 MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB); 524 if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) 525 return false; 526 527 unsigned NextStackOffset = CCInfo.getNextStackOffset(); 528 unsigned StackAlignment = F.getParent()->getOverrideStackAlignment(); 529 if (!StackAlignment) { 530 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); 531 StackAlignment = TFL->getStackAlignment(); 532 } 533 NextStackOffset = alignTo(NextStackOffset, StackAlignment); 534 CallSeqStart.addImm(NextStackOffset).addImm(0); 535 536 if (IsCalleeGlobalPIC) { 537 MIRBuilder.buildCopy( 538 Register(Mips::GP), 539 MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel(MF)); 540 MIB.addDef(Mips::GP, RegState::Implicit); 541 } 542 MIRBuilder.insertInstr(MIB); 543 if (MIB->getOpcode() == Mips::JALRPseudo) { 544 const MipsSubtarget &STI = MIRBuilder.getMF().getSubtarget<MipsSubtarget>(); 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