1 //===- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering ------------===// 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 "ARMCallLowering.h" 16 #include "ARMBaseInstrInfo.h" 17 #include "ARMISelLowering.h" 18 #include "ARMSubtarget.h" 19 #include "Utils/ARMBaseInfo.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/CodeGen/Analysis.h" 22 #include "llvm/CodeGen/CallingConvLower.h" 23 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 24 #include "llvm/CodeGen/GlobalISel/Utils.h" 25 #include "llvm/CodeGen/LowLevelType.h" 26 #include "llvm/CodeGen/MachineBasicBlock.h" 27 #include "llvm/CodeGen/MachineFrameInfo.h" 28 #include "llvm/CodeGen/MachineFunction.h" 29 #include "llvm/CodeGen/MachineInstrBuilder.h" 30 #include "llvm/CodeGen/MachineMemOperand.h" 31 #include "llvm/CodeGen/MachineOperand.h" 32 #include "llvm/CodeGen/MachineRegisterInfo.h" 33 #include "llvm/CodeGen/TargetRegisterInfo.h" 34 #include "llvm/CodeGen/TargetSubtargetInfo.h" 35 #include "llvm/CodeGen/ValueTypes.h" 36 #include "llvm/IR/Attributes.h" 37 #include "llvm/IR/DataLayout.h" 38 #include "llvm/IR/DerivedTypes.h" 39 #include "llvm/IR/Function.h" 40 #include "llvm/IR/Type.h" 41 #include "llvm/IR/Value.h" 42 #include "llvm/Support/Casting.h" 43 #include "llvm/Support/LowLevelTypeImpl.h" 44 #include "llvm/Support/MachineValueType.h" 45 #include <algorithm> 46 #include <cassert> 47 #include <cstdint> 48 #include <utility> 49 50 using namespace llvm; 51 52 ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI) 53 : CallLowering(&TLI) {} 54 55 static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, 56 Type *T) { 57 if (T->isArrayTy()) 58 return isSupportedType(DL, TLI, T->getArrayElementType()); 59 60 if (T->isStructTy()) { 61 // For now we only allow homogeneous structs that we can manipulate with 62 // G_MERGE_VALUES and G_UNMERGE_VALUES 63 auto StructT = cast<StructType>(T); 64 for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i) 65 if (StructT->getElementType(i) != StructT->getElementType(0)) 66 return false; 67 return isSupportedType(DL, TLI, StructT->getElementType(0)); 68 } 69 70 EVT VT = TLI.getValueType(DL, T, true); 71 if (!VT.isSimple() || VT.isVector() || 72 !(VT.isInteger() || VT.isFloatingPoint())) 73 return false; 74 75 unsigned VTSize = VT.getSimpleVT().getSizeInBits(); 76 77 if (VTSize == 64) 78 // FIXME: Support i64 too 79 return VT.isFloatingPoint(); 80 81 return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32; 82 } 83 84 namespace { 85 86 /// Helper class for values going out through an ABI boundary (used for handling 87 /// function return values and call parameters). 88 struct OutgoingValueHandler : public CallLowering::ValueHandler { 89 OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 90 MachineInstrBuilder &MIB, CCAssignFn *AssignFn) 91 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} 92 93 unsigned getStackAddress(uint64_t Size, int64_t Offset, 94 MachinePointerInfo &MPO) override { 95 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) && 96 "Unsupported size"); 97 98 LLT p0 = LLT::pointer(0, 32); 99 LLT s32 = LLT::scalar(32); 100 unsigned SPReg = MRI.createGenericVirtualRegister(p0); 101 MIRBuilder.buildCopy(SPReg, ARM::SP); 102 103 unsigned OffsetReg = MRI.createGenericVirtualRegister(s32); 104 MIRBuilder.buildConstant(OffsetReg, Offset); 105 106 unsigned AddrReg = MRI.createGenericVirtualRegister(p0); 107 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg); 108 109 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset); 110 return AddrReg; 111 } 112 113 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 114 CCValAssign &VA) override { 115 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg"); 116 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?"); 117 118 assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size"); 119 assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size"); 120 121 unsigned ExtReg = extendRegister(ValVReg, VA); 122 MIRBuilder.buildCopy(PhysReg, ExtReg); 123 MIB.addUse(PhysReg, RegState::Implicit); 124 } 125 126 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 127 MachinePointerInfo &MPO, CCValAssign &VA) override { 128 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) && 129 "Unsupported size"); 130 131 unsigned ExtReg = extendRegister(ValVReg, VA); 132 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 133 MPO, MachineMemOperand::MOStore, VA.getLocVT().getStoreSize(), 134 /* Alignment */ 1); 135 MIRBuilder.buildStore(ExtReg, Addr, *MMO); 136 } 137 138 unsigned assignCustomValue(const CallLowering::ArgInfo &Arg, 139 ArrayRef<CCValAssign> VAs) override { 140 CCValAssign VA = VAs[0]; 141 assert(VA.needsCustom() && "Value doesn't need custom handling"); 142 assert(VA.getValVT() == MVT::f64 && "Unsupported type"); 143 144 CCValAssign NextVA = VAs[1]; 145 assert(NextVA.needsCustom() && "Value doesn't need custom handling"); 146 assert(NextVA.getValVT() == MVT::f64 && "Unsupported type"); 147 148 assert(VA.getValNo() == NextVA.getValNo() && 149 "Values belong to different arguments"); 150 151 assert(VA.isRegLoc() && "Value should be in reg"); 152 assert(NextVA.isRegLoc() && "Value should be in reg"); 153 154 unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)), 155 MRI.createGenericVirtualRegister(LLT::scalar(32))}; 156 MIRBuilder.buildUnmerge(NewRegs, Arg.Reg); 157 158 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle(); 159 if (!IsLittle) 160 std::swap(NewRegs[0], NewRegs[1]); 161 162 assignValueToReg(NewRegs[0], VA.getLocReg(), VA); 163 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA); 164 165 return 1; 166 } 167 168 bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, 169 CCValAssign::LocInfo LocInfo, 170 const CallLowering::ArgInfo &Info, CCState &State) override { 171 if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State)) 172 return true; 173 174 StackSize = 175 std::max(StackSize, static_cast<uint64_t>(State.getNextStackOffset())); 176 return false; 177 } 178 179 MachineInstrBuilder &MIB; 180 uint64_t StackSize = 0; 181 }; 182 183 } // end anonymous namespace 184 185 void ARMCallLowering::splitToValueTypes( 186 const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs, 187 MachineFunction &MF, const SplitArgTy &PerformArgSplit) const { 188 const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>(); 189 LLVMContext &Ctx = OrigArg.Ty->getContext(); 190 const DataLayout &DL = MF.getDataLayout(); 191 MachineRegisterInfo &MRI = MF.getRegInfo(); 192 const Function &F = MF.getFunction(); 193 194 SmallVector<EVT, 4> SplitVTs; 195 SmallVector<uint64_t, 4> Offsets; 196 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); 197 198 if (SplitVTs.size() == 1) { 199 // Even if there is no splitting to do, we still want to replace the 200 // original type (e.g. pointer type -> integer). 201 auto Flags = OrigArg.Flags; 202 unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty); 203 Flags.setOrigAlign(OriginalAlignment); 204 SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags, 205 OrigArg.IsFixed); 206 return; 207 } 208 209 unsigned FirstRegIdx = SplitArgs.size(); 210 for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) { 211 EVT SplitVT = SplitVTs[i]; 212 Type *SplitTy = SplitVT.getTypeForEVT(Ctx); 213 auto Flags = OrigArg.Flags; 214 215 unsigned OriginalAlignment = DL.getABITypeAlignment(SplitTy); 216 Flags.setOrigAlign(OriginalAlignment); 217 218 bool NeedsConsecutiveRegisters = 219 TLI.functionArgumentNeedsConsecutiveRegisters( 220 SplitTy, F.getCallingConv(), F.isVarArg()); 221 if (NeedsConsecutiveRegisters) { 222 Flags.setInConsecutiveRegs(); 223 if (i == e - 1) 224 Flags.setInConsecutiveRegsLast(); 225 } 226 227 SplitArgs.push_back( 228 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)), 229 SplitTy, Flags, OrigArg.IsFixed}); 230 } 231 232 for (unsigned i = 0; i < Offsets.size(); ++i) 233 PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8); 234 } 235 236 /// Lower the return value for the already existing \p Ret. This assumes that 237 /// \p MIRBuilder's insertion point is correct. 238 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, 239 const Value *Val, ArrayRef<unsigned> VRegs, 240 MachineInstrBuilder &Ret) const { 241 if (!Val) 242 // Nothing to do here. 243 return true; 244 245 auto &MF = MIRBuilder.getMF(); 246 const auto &F = MF.getFunction(); 247 248 auto DL = MF.getDataLayout(); 249 auto &TLI = *getTLI<ARMTargetLowering>(); 250 if (!isSupportedType(DL, TLI, Val->getType())) 251 return false; 252 253 SmallVector<EVT, 4> SplitEVTs; 254 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs); 255 assert(VRegs.size() == SplitEVTs.size() && 256 "For each split Type there should be exactly one VReg."); 257 258 SmallVector<ArgInfo, 4> SplitVTs; 259 LLVMContext &Ctx = Val->getType()->getContext(); 260 for (unsigned i = 0; i < SplitEVTs.size(); ++i) { 261 ArgInfo CurArgInfo(VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)); 262 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); 263 264 SmallVector<unsigned, 4> Regs; 265 splitToValueTypes( 266 CurArgInfo, SplitVTs, MF, 267 [&](unsigned Reg, uint64_t Offset) { Regs.push_back(Reg); }); 268 if (Regs.size() > 1) 269 MIRBuilder.buildUnmerge(Regs, VRegs[i]); 270 } 271 272 CCAssignFn *AssignFn = 273 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg()); 274 275 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn); 276 return handleAssignments(MIRBuilder, SplitVTs, RetHandler); 277 } 278 279 bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 280 const Value *Val, 281 ArrayRef<unsigned> VRegs) const { 282 assert(!Val == VRegs.empty() && "Return value without a vreg"); 283 284 auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>(); 285 unsigned Opcode = ST.getReturnOpcode(); 286 auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL)); 287 288 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret)) 289 return false; 290 291 MIRBuilder.insertInstr(Ret); 292 return true; 293 } 294 295 namespace { 296 297 /// Helper class for values coming in through an ABI boundary (used for handling 298 /// formal arguments and call return values). 299 struct IncomingValueHandler : public CallLowering::ValueHandler { 300 IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 301 CCAssignFn AssignFn) 302 : ValueHandler(MIRBuilder, MRI, AssignFn) {} 303 304 bool isArgumentHandler() const override { return true; } 305 306 unsigned getStackAddress(uint64_t Size, int64_t Offset, 307 MachinePointerInfo &MPO) override { 308 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) && 309 "Unsupported size"); 310 311 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 312 313 int FI = MFI.CreateFixedObject(Size, Offset, true); 314 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 315 316 unsigned AddrReg = 317 MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32)); 318 MIRBuilder.buildFrameIndex(AddrReg, FI); 319 320 return AddrReg; 321 } 322 323 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 324 MachinePointerInfo &MPO, CCValAssign &VA) override { 325 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) && 326 "Unsupported size"); 327 328 if (VA.getLocInfo() == CCValAssign::SExt || 329 VA.getLocInfo() == CCValAssign::ZExt) { 330 // If the value is zero- or sign-extended, its size becomes 4 bytes, so 331 // that's what we should load. 332 Size = 4; 333 assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm"); 334 335 auto LoadVReg = MRI.createGenericVirtualRegister(LLT::scalar(32)); 336 buildLoad(LoadVReg, Addr, Size, /* Alignment */ 1, MPO); 337 MIRBuilder.buildTrunc(ValVReg, LoadVReg); 338 } else { 339 // If the value is not extended, a simple load will suffice. 340 buildLoad(ValVReg, Addr, Size, /* Alignment */ 1, MPO); 341 } 342 } 343 344 void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment, 345 MachinePointerInfo &MPO) { 346 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 347 MPO, MachineMemOperand::MOLoad, Size, Alignment); 348 MIRBuilder.buildLoad(Val, Addr, *MMO); 349 } 350 351 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 352 CCValAssign &VA) override { 353 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg"); 354 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?"); 355 356 auto ValSize = VA.getValVT().getSizeInBits(); 357 auto LocSize = VA.getLocVT().getSizeInBits(); 358 359 assert(ValSize <= 64 && "Unsupported value size"); 360 assert(LocSize <= 64 && "Unsupported location size"); 361 362 markPhysRegUsed(PhysReg); 363 if (ValSize == LocSize) { 364 MIRBuilder.buildCopy(ValVReg, PhysReg); 365 } else { 366 assert(ValSize < LocSize && "Extensions not supported"); 367 368 // We cannot create a truncating copy, nor a trunc of a physical register. 369 // Therefore, we need to copy the content of the physical register into a 370 // virtual one and then truncate that. 371 auto PhysRegToVReg = 372 MRI.createGenericVirtualRegister(LLT::scalar(LocSize)); 373 MIRBuilder.buildCopy(PhysRegToVReg, PhysReg); 374 MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg); 375 } 376 } 377 378 unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg, 379 ArrayRef<CCValAssign> VAs) override { 380 CCValAssign VA = VAs[0]; 381 assert(VA.needsCustom() && "Value doesn't need custom handling"); 382 assert(VA.getValVT() == MVT::f64 && "Unsupported type"); 383 384 CCValAssign NextVA = VAs[1]; 385 assert(NextVA.needsCustom() && "Value doesn't need custom handling"); 386 assert(NextVA.getValVT() == MVT::f64 && "Unsupported type"); 387 388 assert(VA.getValNo() == NextVA.getValNo() && 389 "Values belong to different arguments"); 390 391 assert(VA.isRegLoc() && "Value should be in reg"); 392 assert(NextVA.isRegLoc() && "Value should be in reg"); 393 394 unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)), 395 MRI.createGenericVirtualRegister(LLT::scalar(32))}; 396 397 assignValueToReg(NewRegs[0], VA.getLocReg(), VA); 398 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA); 399 400 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle(); 401 if (!IsLittle) 402 std::swap(NewRegs[0], NewRegs[1]); 403 404 MIRBuilder.buildMerge(Arg.Reg, NewRegs); 405 406 return 1; 407 } 408 409 /// Marking a physical register as used is different between formal 410 /// parameters, where it's a basic block live-in, and call returns, where it's 411 /// an implicit-def of the call instruction. 412 virtual void markPhysRegUsed(unsigned PhysReg) = 0; 413 }; 414 415 struct FormalArgHandler : public IncomingValueHandler { 416 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 417 CCAssignFn AssignFn) 418 : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {} 419 420 void markPhysRegUsed(unsigned PhysReg) override { 421 MIRBuilder.getMBB().addLiveIn(PhysReg); 422 } 423 }; 424 425 } // end anonymous namespace 426 427 bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 428 const Function &F, 429 ArrayRef<unsigned> VRegs) const { 430 auto &TLI = *getTLI<ARMTargetLowering>(); 431 auto Subtarget = TLI.getSubtarget(); 432 433 if (Subtarget->isThumb1Only()) 434 return false; 435 436 // Quick exit if there aren't any args 437 if (F.arg_empty()) 438 return true; 439 440 if (F.isVarArg()) 441 return false; 442 443 auto &MF = MIRBuilder.getMF(); 444 auto &MBB = MIRBuilder.getMBB(); 445 auto DL = MF.getDataLayout(); 446 447 for (auto &Arg : F.args()) { 448 if (!isSupportedType(DL, TLI, Arg.getType())) 449 return false; 450 if (Arg.hasByValOrInAllocaAttr()) 451 return false; 452 } 453 454 CCAssignFn *AssignFn = 455 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg()); 456 457 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(), 458 AssignFn); 459 460 SmallVector<ArgInfo, 8> ArgInfos; 461 SmallVector<unsigned, 4> SplitRegs; 462 unsigned Idx = 0; 463 for (auto &Arg : F.args()) { 464 ArgInfo AInfo(VRegs[Idx], Arg.getType()); 465 setArgFlags(AInfo, Idx + AttributeList::FirstArgIndex, DL, F); 466 467 SplitRegs.clear(); 468 469 splitToValueTypes(AInfo, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) { 470 SplitRegs.push_back(Reg); 471 }); 472 473 if (!SplitRegs.empty()) 474 MIRBuilder.buildMerge(VRegs[Idx], SplitRegs); 475 476 Idx++; 477 } 478 479 if (!MBB.empty()) 480 MIRBuilder.setInstr(*MBB.begin()); 481 482 if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler)) 483 return false; 484 485 // Move back to the end of the basic block. 486 MIRBuilder.setMBB(MBB); 487 return true; 488 } 489 490 namespace { 491 492 struct CallReturnHandler : public IncomingValueHandler { 493 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 494 MachineInstrBuilder MIB, CCAssignFn *AssignFn) 495 : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} 496 497 void markPhysRegUsed(unsigned PhysReg) override { 498 MIB.addDef(PhysReg, RegState::Implicit); 499 } 500 501 MachineInstrBuilder MIB; 502 }; 503 504 // FIXME: This should move to the ARMSubtarget when it supports all the opcodes. 505 unsigned getCallOpcode(const ARMSubtarget &STI, bool isDirect) { 506 if (isDirect) 507 return STI.isThumb() ? ARM::tBL : ARM::BL; 508 509 if (STI.isThumb()) 510 return ARM::tBLXr; 511 512 if (STI.hasV5TOps()) 513 return ARM::BLX; 514 515 if (STI.hasV4TOps()) 516 return ARM::BX_CALL; 517 518 return ARM::BMOVPCRX_CALL; 519 } 520 } // end anonymous namespace 521 522 bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 523 CallingConv::ID CallConv, 524 const MachineOperand &Callee, 525 const ArgInfo &OrigRet, 526 ArrayRef<ArgInfo> OrigArgs) const { 527 MachineFunction &MF = MIRBuilder.getMF(); 528 const auto &TLI = *getTLI<ARMTargetLowering>(); 529 const auto &DL = MF.getDataLayout(); 530 const auto &STI = MF.getSubtarget<ARMSubtarget>(); 531 const TargetRegisterInfo *TRI = STI.getRegisterInfo(); 532 MachineRegisterInfo &MRI = MF.getRegInfo(); 533 534 if (STI.genLongCalls()) 535 return false; 536 537 if (STI.isThumb1Only()) 538 return false; 539 540 auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN); 541 542 // Create the call instruction so we can add the implicit uses of arg 543 // registers, but don't insert it yet. 544 bool IsDirect = !Callee.isReg(); 545 auto CallOpcode = getCallOpcode(STI, IsDirect); 546 auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode); 547 548 bool IsThumb = STI.isThumb(); 549 if (IsThumb) 550 MIB.add(predOps(ARMCC::AL)); 551 552 MIB.add(Callee); 553 if (!IsDirect) { 554 auto CalleeReg = Callee.getReg(); 555 if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg)) { 556 unsigned CalleeIdx = IsThumb ? 2 : 0; 557 MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass( 558 MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(), 559 *MIB.getInstr(), MIB->getDesc(), Callee, CalleeIdx)); 560 } 561 } 562 563 MIB.addRegMask(TRI->getCallPreservedMask(MF, CallConv)); 564 565 bool IsVarArg = false; 566 SmallVector<ArgInfo, 8> ArgInfos; 567 for (auto Arg : OrigArgs) { 568 if (!isSupportedType(DL, TLI, Arg.Ty)) 569 return false; 570 571 if (!Arg.IsFixed) 572 IsVarArg = true; 573 574 if (Arg.Flags.isByVal()) 575 return false; 576 577 SmallVector<unsigned, 8> Regs; 578 splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) { 579 Regs.push_back(Reg); 580 }); 581 582 if (Regs.size() > 1) 583 MIRBuilder.buildUnmerge(Regs, Arg.Reg); 584 } 585 586 auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, IsVarArg); 587 OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn); 588 if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler)) 589 return false; 590 591 // Now we can add the actual call instruction to the correct basic block. 592 MIRBuilder.insertInstr(MIB); 593 594 if (!OrigRet.Ty->isVoidTy()) { 595 if (!isSupportedType(DL, TLI, OrigRet.Ty)) 596 return false; 597 598 ArgInfos.clear(); 599 SmallVector<unsigned, 8> SplitRegs; 600 splitToValueTypes(OrigRet, ArgInfos, MF, 601 [&](unsigned Reg, uint64_t Offset) { 602 SplitRegs.push_back(Reg); 603 }); 604 605 auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, IsVarArg); 606 CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn); 607 if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler)) 608 return false; 609 610 if (!SplitRegs.empty()) { 611 // We have split the value and allocated each individual piece, now build 612 // it up again. 613 MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs); 614 } 615 } 616 617 // We now know the size of the stack - update the ADJCALLSTACKDOWN 618 // accordingly. 619 CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL)); 620 621 MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP) 622 .addImm(ArgHandler.StackSize) 623 .addImm(0) 624 .add(predOps(ARMCC::AL)); 625 626 return true; 627 } 628