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 bool MipsCallLowering::MipsHandler::assign(Register VReg, const CCValAssign &VA, 28 const EVT &VT) { 29 if (VA.isRegLoc()) { 30 assignValueToReg(VReg, VA, VT); 31 } else if (VA.isMemLoc()) { 32 assignValueToAddress(VReg, VA); 33 } else { 34 return false; 35 } 36 return true; 37 } 38 39 bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<Register> VRegs, 40 ArrayRef<CCValAssign> ArgLocs, 41 unsigned ArgLocsStartIndex, 42 const EVT &VT) { 43 for (unsigned i = 0; i < VRegs.size(); ++i) 44 if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i], VT)) 45 return false; 46 return true; 47 } 48 49 void MipsCallLowering::MipsHandler::setLeastSignificantFirst( 50 SmallVectorImpl<Register> &VRegs) { 51 if (!MIRBuilder.getMF().getDataLayout().isLittleEndian()) 52 std::reverse(VRegs.begin(), VRegs.end()); 53 } 54 55 bool MipsCallLowering::MipsHandler::handle( 56 ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) { 57 SmallVector<Register, 4> VRegs; 58 unsigned SplitLength; 59 const Function &F = MIRBuilder.getMF().getFunction(); 60 const DataLayout &DL = F.getParent()->getDataLayout(); 61 const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>( 62 MIRBuilder.getMF().getSubtarget().getTargetLowering()); 63 64 for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size(); 65 ++ArgsIndex, ArgLocsIndex += SplitLength) { 66 EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty); 67 SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(), 68 F.getCallingConv(), VT); 69 assert(Args[ArgsIndex].Regs.size() == 1 && "Can't handle multple regs yet"); 70 71 if (SplitLength > 1) { 72 VRegs.clear(); 73 MVT RegisterVT = TLI.getRegisterTypeForCallingConv( 74 F.getContext(), F.getCallingConv(), VT); 75 for (unsigned i = 0; i < SplitLength; ++i) 76 VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT})); 77 78 if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Regs[0], 79 VT)) 80 return false; 81 } else { 82 if (!assign(Args[ArgsIndex].Regs[0], ArgLocs[ArgLocsIndex], VT)) 83 return false; 84 } 85 } 86 return true; 87 } 88 89 namespace { 90 class IncomingValueHandler : public MipsCallLowering::MipsHandler { 91 public: 92 IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) 93 : MipsHandler(MIRBuilder, MRI) {} 94 95 private: 96 void assignValueToReg(Register ValVReg, const CCValAssign &VA, 97 const EVT &VT) override; 98 99 Register getStackAddress(const CCValAssign &VA, 100 MachineMemOperand *&MMO) override; 101 102 void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override; 103 104 bool handleSplit(SmallVectorImpl<Register> &VRegs, 105 ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, 106 Register ArgsReg, const EVT &VT) override; 107 108 virtual void markPhysRegUsed(unsigned PhysReg) { 109 MIRBuilder.getMRI()->addLiveIn(PhysReg); 110 MIRBuilder.getMBB().addLiveIn(PhysReg); 111 } 112 113 MachineInstrBuilder buildLoad(const DstOp &Res, const CCValAssign &VA) { 114 MachineMemOperand *MMO; 115 Register Addr = getStackAddress(VA, MMO); 116 return MIRBuilder.buildLoad(Res, Addr, *MMO); 117 } 118 }; 119 120 class CallReturnHandler : public IncomingValueHandler { 121 public: 122 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 123 MachineInstrBuilder &MIB) 124 : IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {} 125 126 private: 127 void markPhysRegUsed(unsigned PhysReg) override { 128 MIB.addDef(PhysReg, RegState::Implicit); 129 } 130 131 MachineInstrBuilder &MIB; 132 }; 133 134 } // end anonymous namespace 135 136 void IncomingValueHandler::assignValueToReg(Register ValVReg, 137 const CCValAssign &VA, 138 const EVT &VT) { 139 Register PhysReg = VA.getLocReg(); 140 if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { 141 const MipsSubtarget &STI = 142 static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); 143 bool IsEL = STI.isLittle(); 144 LLT s32 = LLT::scalar(32); 145 auto Lo = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 0 : 1))); 146 auto Hi = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 1 : 0))); 147 MIRBuilder.buildMerge(ValVReg, {Lo, Hi}); 148 markPhysRegUsed(PhysReg); 149 markPhysRegUsed(PhysReg + 1); 150 } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { 151 MIRBuilder.buildCopy(ValVReg, PhysReg); 152 markPhysRegUsed(PhysReg); 153 } else { 154 switch (VA.getLocInfo()) { 155 case CCValAssign::LocInfo::SExt: 156 case CCValAssign::LocInfo::ZExt: 157 case CCValAssign::LocInfo::AExt: { 158 auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg); 159 MIRBuilder.buildTrunc(ValVReg, Copy); 160 break; 161 } 162 default: 163 MIRBuilder.buildCopy(ValVReg, PhysReg); 164 break; 165 } 166 markPhysRegUsed(PhysReg); 167 } 168 } 169 170 Register IncomingValueHandler::getStackAddress(const CCValAssign &VA, 171 MachineMemOperand *&MMO) { 172 MachineFunction &MF = MIRBuilder.getMF(); 173 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8; 174 unsigned Offset = VA.getLocMemOffset(); 175 MachineFrameInfo &MFI = MF.getFrameInfo(); 176 177 int FI = MFI.CreateFixedObject(Size, Offset, true); 178 MachinePointerInfo MPO = 179 MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 180 181 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); 182 unsigned Align = MinAlign(TFL->getStackAlignment(), Offset); 183 MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, Size, Align); 184 185 return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0); 186 } 187 188 void IncomingValueHandler::assignValueToAddress(Register ValVReg, 189 const CCValAssign &VA) { 190 if (VA.getLocInfo() == CCValAssign::SExt || 191 VA.getLocInfo() == CCValAssign::ZExt || 192 VA.getLocInfo() == CCValAssign::AExt) { 193 auto Load = buildLoad(LLT::scalar(32), VA); 194 MIRBuilder.buildTrunc(ValVReg, Load); 195 } else 196 buildLoad(ValVReg, VA); 197 } 198 199 bool IncomingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs, 200 ArrayRef<CCValAssign> ArgLocs, 201 unsigned ArgLocsStartIndex, 202 Register ArgsReg, const EVT &VT) { 203 if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT)) 204 return false; 205 setLeastSignificantFirst(VRegs); 206 MIRBuilder.buildMerge(ArgsReg, VRegs); 207 return true; 208 } 209 210 namespace { 211 class OutgoingValueHandler : public MipsCallLowering::MipsHandler { 212 public: 213 OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 214 MachineInstrBuilder &MIB) 215 : MipsHandler(MIRBuilder, MRI), MIB(MIB) {} 216 217 private: 218 void assignValueToReg(Register ValVReg, const CCValAssign &VA, 219 const EVT &VT) override; 220 221 Register getStackAddress(const CCValAssign &VA, 222 MachineMemOperand *&MMO) override; 223 224 void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override; 225 226 bool handleSplit(SmallVectorImpl<Register> &VRegs, 227 ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, 228 Register ArgsReg, const EVT &VT) override; 229 230 Register extendRegister(Register ValReg, const CCValAssign &VA); 231 232 MachineInstrBuilder &MIB; 233 }; 234 } // end anonymous namespace 235 236 void OutgoingValueHandler::assignValueToReg(Register ValVReg, 237 const CCValAssign &VA, 238 const EVT &VT) { 239 Register PhysReg = VA.getLocReg(); 240 if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { 241 const MipsSubtarget &STI = 242 static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); 243 bool IsEL = STI.isLittle(); 244 auto Unmerge = MIRBuilder.buildUnmerge(LLT::scalar(32), ValVReg); 245 MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 0 : 1)), Unmerge.getReg(0)); 246 MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 1 : 0)), Unmerge.getReg(1)); 247 } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { 248 MIRBuilder.buildCopy(PhysReg, ValVReg); 249 } else { 250 Register ExtReg = extendRegister(ValVReg, VA); 251 MIRBuilder.buildCopy(PhysReg, ExtReg); 252 MIB.addUse(PhysReg, RegState::Implicit); 253 } 254 } 255 256 Register OutgoingValueHandler::getStackAddress(const CCValAssign &VA, 257 MachineMemOperand *&MMO) { 258 MachineFunction &MF = MIRBuilder.getMF(); 259 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); 260 261 LLT p0 = LLT::pointer(0, 32); 262 LLT s32 = LLT::scalar(32); 263 auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP)); 264 265 unsigned Offset = VA.getLocMemOffset(); 266 auto OffsetReg = MIRBuilder.buildConstant(s32, Offset); 267 268 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg); 269 270 MachinePointerInfo MPO = 271 MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset); 272 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8; 273 unsigned Align = MinAlign(TFL->getStackAlignment(), Offset); 274 MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, Size, Align); 275 276 return AddrReg.getReg(0); 277 } 278 279 void OutgoingValueHandler::assignValueToAddress(Register ValVReg, 280 const CCValAssign &VA) { 281 MachineMemOperand *MMO; 282 Register Addr = getStackAddress(VA, MMO); 283 Register ExtReg = extendRegister(ValVReg, VA); 284 MIRBuilder.buildStore(ExtReg, Addr, *MMO); 285 } 286 287 Register OutgoingValueHandler::extendRegister(Register ValReg, 288 const CCValAssign &VA) { 289 LLT LocTy{VA.getLocVT()}; 290 switch (VA.getLocInfo()) { 291 case CCValAssign::SExt: { 292 return MIRBuilder.buildSExt(LocTy, ValReg).getReg(0); 293 } 294 case CCValAssign::ZExt: { 295 return MIRBuilder.buildZExt(LocTy, ValReg).getReg(0); 296 } 297 case CCValAssign::AExt: { 298 return MIRBuilder.buildAnyExt(LocTy, ValReg).getReg(0); 299 } 300 // TODO : handle upper extends 301 case CCValAssign::Full: 302 return ValReg; 303 default: 304 break; 305 } 306 llvm_unreachable("unable to extend register"); 307 } 308 309 bool OutgoingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs, 310 ArrayRef<CCValAssign> ArgLocs, 311 unsigned ArgLocsStartIndex, 312 Register ArgsReg, const EVT &VT) { 313 MIRBuilder.buildUnmerge(VRegs, ArgsReg); 314 setLeastSignificantFirst(VRegs); 315 if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT)) 316 return false; 317 318 return true; 319 } 320 321 static bool isSupportedArgumentType(Type *T) { 322 if (T->isIntegerTy()) 323 return true; 324 if (T->isPointerTy()) 325 return true; 326 if (T->isFloatingPointTy()) 327 return true; 328 return false; 329 } 330 331 static bool isSupportedReturnType(Type *T) { 332 if (T->isIntegerTy()) 333 return true; 334 if (T->isPointerTy()) 335 return true; 336 if (T->isFloatingPointTy()) 337 return true; 338 if (T->isAggregateType()) 339 return true; 340 return false; 341 } 342 343 static CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT, 344 const ISD::ArgFlagsTy &Flags) { 345 // > does not mean loss of information as type RegisterVT can't hold type VT, 346 // it means that type VT is split into multiple registers of type RegisterVT 347 if (VT.getSizeInBits() >= RegisterVT.getSizeInBits()) 348 return CCValAssign::LocInfo::Full; 349 if (Flags.isSExt()) 350 return CCValAssign::LocInfo::SExt; 351 if (Flags.isZExt()) 352 return CCValAssign::LocInfo::ZExt; 353 return CCValAssign::LocInfo::AExt; 354 } 355 356 template <typename T> 357 static void setLocInfo(SmallVectorImpl<CCValAssign> &ArgLocs, 358 const SmallVectorImpl<T> &Arguments) { 359 for (unsigned i = 0; i < ArgLocs.size(); ++i) { 360 const CCValAssign &VA = ArgLocs[i]; 361 CCValAssign::LocInfo LocInfo = determineLocInfo( 362 Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags); 363 if (VA.isMemLoc()) 364 ArgLocs[i] = 365 CCValAssign::getMem(VA.getValNo(), VA.getValVT(), 366 VA.getLocMemOffset(), VA.getLocVT(), LocInfo); 367 else 368 ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), 369 VA.getLocReg(), VA.getLocVT(), LocInfo); 370 } 371 } 372 373 bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 374 const Value *Val, 375 ArrayRef<Register> VRegs) const { 376 377 MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA); 378 379 if (Val != nullptr && !isSupportedReturnType(Val->getType())) 380 return false; 381 382 if (!VRegs.empty()) { 383 MachineFunction &MF = MIRBuilder.getMF(); 384 const Function &F = MF.getFunction(); 385 const DataLayout &DL = MF.getDataLayout(); 386 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 387 388 SmallVector<ArgInfo, 8> RetInfos; 389 SmallVector<unsigned, 8> OrigArgIndices; 390 391 ArgInfo ArgRetInfo(VRegs, Val->getType()); 392 setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F); 393 splitToValueTypes(DL, ArgRetInfo, 0, RetInfos, OrigArgIndices); 394 395 SmallVector<ISD::OutputArg, 8> Outs; 396 subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs); 397 398 SmallVector<CCValAssign, 16> ArgLocs; 399 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, 400 F.getContext()); 401 CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn()); 402 setLocInfo(ArgLocs, Outs); 403 404 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret); 405 if (!RetHandler.handle(ArgLocs, RetInfos)) { 406 return false; 407 } 408 } 409 MIRBuilder.insertInstr(Ret); 410 return true; 411 } 412 413 bool MipsCallLowering::lowerFormalArguments( 414 MachineIRBuilder &MIRBuilder, const Function &F, 415 ArrayRef<ArrayRef<Register>> VRegs) const { 416 417 // Quick exit if there aren't any args. 418 if (F.arg_empty()) 419 return true; 420 421 for (auto &Arg : F.args()) { 422 if (!isSupportedArgumentType(Arg.getType())) 423 return false; 424 } 425 426 MachineFunction &MF = MIRBuilder.getMF(); 427 const DataLayout &DL = MF.getDataLayout(); 428 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 429 430 SmallVector<ArgInfo, 8> ArgInfos; 431 SmallVector<unsigned, 8> OrigArgIndices; 432 unsigned i = 0; 433 for (auto &Arg : F.args()) { 434 ArgInfo AInfo(VRegs[i], Arg.getType()); 435 setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F); 436 ArgInfos.push_back(AInfo); 437 OrigArgIndices.push_back(i); 438 ++i; 439 } 440 441 SmallVector<ISD::InputArg, 8> Ins; 442 subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins); 443 444 SmallVector<CCValAssign, 16> ArgLocs; 445 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, 446 F.getContext()); 447 448 const MipsTargetMachine &TM = 449 static_cast<const MipsTargetMachine &>(MF.getTarget()); 450 const MipsABIInfo &ABI = TM.getABI(); 451 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()), 452 1); 453 CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall()); 454 setLocInfo(ArgLocs, Ins); 455 456 IncomingValueHandler Handler(MIRBuilder, MF.getRegInfo()); 457 if (!Handler.handle(ArgLocs, ArgInfos)) 458 return false; 459 460 if (F.isVarArg()) { 461 ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs(); 462 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs); 463 464 int VaArgOffset; 465 unsigned RegSize = 4; 466 if (ArgRegs.size() == Idx) 467 VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize); 468 else { 469 VaArgOffset = 470 (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) - 471 (int)(RegSize * (ArgRegs.size() - Idx)); 472 } 473 474 MachineFrameInfo &MFI = MF.getFrameInfo(); 475 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); 476 MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI); 477 478 for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) { 479 MIRBuilder.getMBB().addLiveIn(ArgRegs[I]); 480 481 MachineInstrBuilder Copy = 482 MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I])); 483 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); 484 MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI); 485 MachineInstrBuilder FrameIndex = 486 MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI); 487 MachineMemOperand *MMO = 488 MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, RegSize, 489 /* Alignment */ RegSize); 490 MIRBuilder.buildStore(Copy, FrameIndex, *MMO); 491 } 492 } 493 494 return true; 495 } 496 497 bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 498 CallLoweringInfo &Info) const { 499 500 if (Info.CallConv != CallingConv::C) 501 return false; 502 503 for (auto &Arg : Info.OrigArgs) { 504 if (!isSupportedArgumentType(Arg.Ty)) 505 return false; 506 if (Arg.Flags[0].isByVal()) 507 return false; 508 if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy()) 509 return false; 510 } 511 512 if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty)) 513 return false; 514 515 MachineFunction &MF = MIRBuilder.getMF(); 516 const Function &F = MF.getFunction(); 517 const DataLayout &DL = MF.getDataLayout(); 518 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 519 const MipsTargetMachine &TM = 520 static_cast<const MipsTargetMachine &>(MF.getTarget()); 521 const MipsABIInfo &ABI = TM.getABI(); 522 523 MachineInstrBuilder CallSeqStart = 524 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN); 525 526 const bool IsCalleeGlobalPIC = 527 Info.Callee.isGlobal() && TM.isPositionIndependent(); 528 529 MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert( 530 Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL); 531 MIB.addDef(Mips::SP, RegState::Implicit); 532 if (IsCalleeGlobalPIC) { 533 Register CalleeReg = 534 MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32)); 535 MachineInstr *CalleeGlobalValue = 536 MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal()); 537 if (!Info.Callee.getGlobal()->hasLocalLinkage()) 538 CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL); 539 MIB.addUse(CalleeReg); 540 } else 541 MIB.add(Info.Callee); 542 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 543 MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv())); 544 545 TargetLowering::ArgListTy FuncOrigArgs; 546 FuncOrigArgs.reserve(Info.OrigArgs.size()); 547 548 SmallVector<ArgInfo, 8> ArgInfos; 549 SmallVector<unsigned, 8> OrigArgIndices; 550 unsigned i = 0; 551 for (auto &Arg : Info.OrigArgs) { 552 553 TargetLowering::ArgListEntry Entry; 554 Entry.Ty = Arg.Ty; 555 FuncOrigArgs.push_back(Entry); 556 557 ArgInfos.push_back(Arg); 558 OrigArgIndices.push_back(i); 559 ++i; 560 } 561 562 SmallVector<ISD::OutputArg, 8> Outs; 563 subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs); 564 565 SmallVector<CCValAssign, 8> ArgLocs; 566 bool IsCalleeVarArg = false; 567 if (Info.Callee.isGlobal()) { 568 const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal()); 569 IsCalleeVarArg = CF->isVarArg(); 570 } 571 MipsCCState CCInfo(F.getCallingConv(), IsCalleeVarArg, MF, ArgLocs, 572 F.getContext()); 573 574 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), 1); 575 const char *Call = 576 Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr; 577 CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call); 578 setLocInfo(ArgLocs, Outs); 579 580 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB); 581 if (!RetHandler.handle(ArgLocs, ArgInfos)) { 582 return false; 583 } 584 585 unsigned NextStackOffset = CCInfo.getNextStackOffset(); 586 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); 587 unsigned StackAlignment = TFL->getStackAlignment(); 588 NextStackOffset = alignTo(NextStackOffset, StackAlignment); 589 CallSeqStart.addImm(NextStackOffset).addImm(0); 590 591 if (IsCalleeGlobalPIC) { 592 MIRBuilder.buildCopy( 593 Register(Mips::GP), 594 MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel()); 595 MIB.addDef(Mips::GP, RegState::Implicit); 596 } 597 MIRBuilder.insertInstr(MIB); 598 if (MIB->getOpcode() == Mips::JALRPseudo) { 599 const MipsSubtarget &STI = 600 static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); 601 MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), 602 *STI.getRegBankInfo()); 603 } 604 605 if (!Info.OrigRet.Ty->isVoidTy()) { 606 ArgInfos.clear(); 607 SmallVector<unsigned, 8> OrigRetIndices; 608 609 splitToValueTypes(DL, Info.OrigRet, 0, ArgInfos, OrigRetIndices); 610 611 SmallVector<ISD::InputArg, 8> Ins; 612 subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins); 613 614 SmallVector<CCValAssign, 8> ArgLocs; 615 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, 616 F.getContext()); 617 618 CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), Info.OrigRet.Ty, 619 Call); 620 setLocInfo(ArgLocs, Ins); 621 622 CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB); 623 if (!Handler.handle(ArgLocs, ArgInfos)) 624 return false; 625 } 626 627 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0); 628 629 return true; 630 } 631 632 template <typename T> 633 void MipsCallLowering::subTargetRegTypeForCallingConv( 634 const Function &F, ArrayRef<ArgInfo> Args, 635 ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const { 636 const DataLayout &DL = F.getParent()->getDataLayout(); 637 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 638 639 unsigned ArgNo = 0; 640 for (auto &Arg : Args) { 641 642 EVT VT = TLI.getValueType(DL, Arg.Ty); 643 MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(), 644 F.getCallingConv(), VT); 645 unsigned NumRegs = TLI.getNumRegistersForCallingConv( 646 F.getContext(), F.getCallingConv(), VT); 647 648 for (unsigned i = 0; i < NumRegs; ++i) { 649 ISD::ArgFlagsTy Flags = Arg.Flags[0]; 650 651 if (i == 0) 652 Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL)); 653 else 654 Flags.setOrigAlign(Align(1)); 655 656 ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo], 657 0); 658 } 659 ++ArgNo; 660 } 661 } 662 663 void MipsCallLowering::splitToValueTypes( 664 const DataLayout &DL, const ArgInfo &OrigArg, unsigned OriginalIndex, 665 SmallVectorImpl<ArgInfo> &SplitArgs, 666 SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const { 667 668 SmallVector<EVT, 4> SplitEVTs; 669 SmallVector<Register, 4> SplitVRegs; 670 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); 671 LLVMContext &Ctx = OrigArg.Ty->getContext(); 672 673 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitEVTs); 674 675 for (unsigned i = 0; i < SplitEVTs.size(); ++i) { 676 ArgInfo Info = ArgInfo{OrigArg.Regs[i], SplitEVTs[i].getTypeForEVT(Ctx)}; 677 Info.Flags = OrigArg.Flags; 678 SplitArgs.push_back(Info); 679 SplitArgsOrigIndices.push_back(OriginalIndex); 680 } 681 } 682