blob: 8a00a3fe94c5961ceb982f6acad344b49002a14f [file] [log] [blame]
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +00001//===--- AArch64CallLowering.cpp - Call lowering --------------------------===//
Quentin Colombetba2a0162016-02-16 19:26:02 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Quentin Colombetba2a0162016-02-16 19:26:02 +00006//
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 "AArch64CallLowering.h"
16#include "AArch64ISelLowering.h"
Tim Northovere9600d82017-02-08 17:57:27 +000017#include "AArch64MachineFunctionInfo.h"
18#include "AArch64Subtarget.h"
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000019#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/SmallVector.h"
Tim Northoverb18ea162016-09-20 15:20:36 +000021#include "llvm/CodeGen/Analysis.h"
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000022#include "llvm/CodeGen/CallingConvLower.h"
Quentin Colombetf38015e2016-12-22 21:56:31 +000023#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Quentin Colombetf38015e2016-12-22 21:56:31 +000024#include "llvm/CodeGen/GlobalISel/Utils.h"
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000025#include "llvm/CodeGen/LowLevelType.h"
26#include "llvm/CodeGen/MachineBasicBlock.h"
27#include "llvm/CodeGen/MachineFrameInfo.h"
28#include "llvm/CodeGen/MachineFunction.h"
Quentin Colombetba2a0162016-02-16 19:26:02 +000029#include "llvm/CodeGen/MachineInstrBuilder.h"
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000030#include "llvm/CodeGen/MachineMemOperand.h"
31#include "llvm/CodeGen/MachineOperand.h"
Tim Northoverb18ea162016-09-20 15:20:36 +000032#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000033#include "llvm/CodeGen/TargetRegisterInfo.h"
34#include "llvm/CodeGen/TargetSubtargetInfo.h"
Craig Topper2fa14362018-03-29 17:21:10 +000035#include "llvm/CodeGen/ValueTypes.h"
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000036#include "llvm/IR/Argument.h"
37#include "llvm/IR/Attributes.h"
38#include "llvm/IR/Function.h"
39#include "llvm/IR/Type.h"
40#include "llvm/IR/Value.h"
David Blaikie13e77db2018-03-23 23:58:25 +000041#include "llvm/Support/MachineValueType.h"
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000042#include <algorithm>
43#include <cassert>
44#include <cstdint>
45#include <iterator>
46
Quentin Colombetba2a0162016-02-16 19:26:02 +000047using namespace llvm;
48
49AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +000050 : CallLowering(&TLI) {}
Quentin Colombetba2a0162016-02-16 19:26:02 +000051
Benjamin Kramer49a49fe2017-08-20 13:03:48 +000052namespace {
Diana Picusf11f0422016-12-05 10:40:33 +000053struct IncomingArgHandler : public CallLowering::ValueHandler {
Tim Northoverd9433542017-01-17 22:30:10 +000054 IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
55 CCAssignFn *AssignFn)
Tim Northovere9600d82017-02-08 17:57:27 +000056 : ValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {}
Tim Northovera5e38fa2016-09-22 13:49:25 +000057
58 unsigned getStackAddress(uint64_t Size, int64_t Offset,
59 MachinePointerInfo &MPO) override {
60 auto &MFI = MIRBuilder.getMF().getFrameInfo();
61 int FI = MFI.CreateFixedObject(Size, Offset, true);
62 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
63 unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 64));
64 MIRBuilder.buildFrameIndex(AddrReg, FI);
Tim Northovere9600d82017-02-08 17:57:27 +000065 StackUsed = std::max(StackUsed, Size + Offset);
Tim Northovera5e38fa2016-09-22 13:49:25 +000066 return AddrReg;
67 }
68
69 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
70 CCValAssign &VA) override {
71 markPhysRegUsed(PhysReg);
Aditya Nandakumarc3bfc812017-10-09 20:07:43 +000072 switch (VA.getLocInfo()) {
73 default:
74 MIRBuilder.buildCopy(ValVReg, PhysReg);
75 break;
76 case CCValAssign::LocInfo::SExt:
77 case CCValAssign::LocInfo::ZExt:
78 case CCValAssign::LocInfo::AExt: {
79 auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
80 MIRBuilder.buildTrunc(ValVReg, Copy);
81 break;
82 }
83 }
Tim Northovera5e38fa2016-09-22 13:49:25 +000084 }
85
86 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
87 MachinePointerInfo &MPO, CCValAssign &VA) override {
Matt Arsenault2a645982019-01-31 01:38:47 +000088 // FIXME: Get alignment
Tim Northovera5e38fa2016-09-22 13:49:25 +000089 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
90 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
Matt Arsenault2a645982019-01-31 01:38:47 +000091 1);
Tim Northovera5e38fa2016-09-22 13:49:25 +000092 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
93 }
94
95 /// How the physical register gets marked varies between formal
96 /// parameters (it's a basic-block live-in), and a call instruction
97 /// (it's an implicit-def of the BL).
98 virtual void markPhysRegUsed(unsigned PhysReg) = 0;
Tim Northovere9600d82017-02-08 17:57:27 +000099
100 uint64_t StackUsed;
Tim Northovera5e38fa2016-09-22 13:49:25 +0000101};
102
103struct FormalArgHandler : public IncomingArgHandler {
Tim Northoverd9433542017-01-17 22:30:10 +0000104 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
105 CCAssignFn *AssignFn)
106 : IncomingArgHandler(MIRBuilder, MRI, AssignFn) {}
Tim Northovera5e38fa2016-09-22 13:49:25 +0000107
108 void markPhysRegUsed(unsigned PhysReg) override {
109 MIRBuilder.getMBB().addLiveIn(PhysReg);
110 }
111};
112
113struct CallReturnHandler : public IncomingArgHandler {
114 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
Tim Northoverd9433542017-01-17 22:30:10 +0000115 MachineInstrBuilder MIB, CCAssignFn *AssignFn)
116 : IncomingArgHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
Tim Northovera5e38fa2016-09-22 13:49:25 +0000117
118 void markPhysRegUsed(unsigned PhysReg) override {
119 MIB.addDef(PhysReg, RegState::Implicit);
120 }
121
122 MachineInstrBuilder MIB;
123};
124
Diana Picusf11f0422016-12-05 10:40:33 +0000125struct OutgoingArgHandler : public CallLowering::ValueHandler {
Tim Northovera5e38fa2016-09-22 13:49:25 +0000126 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
Tim Northoverd9433542017-01-17 22:30:10 +0000127 MachineInstrBuilder MIB, CCAssignFn *AssignFn,
128 CCAssignFn *AssignFnVarArg)
129 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
Tim Northover509091f2017-01-17 22:43:34 +0000130 AssignFnVarArg(AssignFnVarArg), StackSize(0) {}
Tim Northovera5e38fa2016-09-22 13:49:25 +0000131
132 unsigned getStackAddress(uint64_t Size, int64_t Offset,
133 MachinePointerInfo &MPO) override {
134 LLT p0 = LLT::pointer(0, 64);
135 LLT s64 = LLT::scalar(64);
136 unsigned SPReg = MRI.createGenericVirtualRegister(p0);
137 MIRBuilder.buildCopy(SPReg, AArch64::SP);
138
139 unsigned OffsetReg = MRI.createGenericVirtualRegister(s64);
140 MIRBuilder.buildConstant(OffsetReg, Offset);
141
142 unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
143 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
144
145 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
146 return AddrReg;
147 }
148
149 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
150 CCValAssign &VA) override {
151 MIB.addUse(PhysReg, RegState::Implicit);
152 unsigned ExtReg = extendRegister(ValVReg, VA);
153 MIRBuilder.buildCopy(PhysReg, ExtReg);
154 }
155
156 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
157 MachinePointerInfo &MPO, CCValAssign &VA) override {
Amara Emersond912ffa2018-07-03 15:59:26 +0000158 if (VA.getLocInfo() == CCValAssign::LocInfo::AExt) {
Amara Emerson846f2432018-07-02 16:39:09 +0000159 Size = VA.getLocVT().getSizeInBits() / 8;
Amara Emersond912ffa2018-07-03 15:59:26 +0000160 ValVReg = MIRBuilder.buildAnyExt(LLT::scalar(Size * 8), ValVReg)
161 ->getOperand(0)
162 .getReg();
163 }
Tim Northovera5e38fa2016-09-22 13:49:25 +0000164 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
Matt Arsenault2a645982019-01-31 01:38:47 +0000165 MPO, MachineMemOperand::MOStore, Size, 1);
Tim Northovera5e38fa2016-09-22 13:49:25 +0000166 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
167 }
168
Eugene Zelenkoc5eb8e22017-02-01 22:56:06 +0000169 bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
170 CCValAssign::LocInfo LocInfo,
171 const CallLowering::ArgInfo &Info,
172 CCState &State) override {
Tim Northovere80d6d12017-03-02 15:34:18 +0000173 bool Res;
Tim Northoverd9433542017-01-17 22:30:10 +0000174 if (Info.IsFixed)
Tim Northovere80d6d12017-03-02 15:34:18 +0000175 Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
176 else
177 Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
178
179 StackSize = State.getNextStackOffset();
180 return Res;
Tim Northoverd9433542017-01-17 22:30:10 +0000181 }
182
Tim Northovera5e38fa2016-09-22 13:49:25 +0000183 MachineInstrBuilder MIB;
Tim Northoverd9433542017-01-17 22:30:10 +0000184 CCAssignFn *AssignFnVarArg;
Tim Northover509091f2017-01-17 22:43:34 +0000185 uint64_t StackSize;
Tim Northovera5e38fa2016-09-22 13:49:25 +0000186};
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000187} // namespace
Tim Northovera5e38fa2016-09-22 13:49:25 +0000188
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000189void AArch64CallLowering::splitToValueTypes(
190 const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000191 const DataLayout &DL, MachineRegisterInfo &MRI, CallingConv::ID CallConv,
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000192 const SplitArgTy &PerformArgSplit) const {
Tim Northoverb18ea162016-09-20 15:20:36 +0000193 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
Tim Northover9a467182016-09-21 12:57:45 +0000194 LLVMContext &Ctx = OrigArg.Ty->getContext();
Tim Northoverb18ea162016-09-20 15:20:36 +0000195
Amara Emerson0d6a26d2018-05-16 10:32:02 +0000196 if (OrigArg.Ty->isVoidTy())
197 return;
198
Tim Northoverb18ea162016-09-20 15:20:36 +0000199 SmallVector<EVT, 4> SplitVTs;
200 SmallVector<uint64_t, 4> Offsets;
Tim Northover9a467182016-09-21 12:57:45 +0000201 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
Tim Northoverb18ea162016-09-20 15:20:36 +0000202
203 if (SplitVTs.size() == 1) {
Tim Northoverd1fd3832016-12-05 21:25:33 +0000204 // No splitting to do, but we want to replace the original type (e.g. [1 x
205 // double] -> double).
206 SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx),
Tim Northoverd9433542017-01-17 22:30:10 +0000207 OrigArg.Flags, OrigArg.IsFixed);
Tim Northoverb18ea162016-09-20 15:20:36 +0000208 return;
209 }
210
Tim Northover9a467182016-09-21 12:57:45 +0000211 unsigned FirstRegIdx = SplitArgs.size();
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000212 bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
213 OrigArg.Ty, CallConv, false);
Tim Northoverb18ea162016-09-20 15:20:36 +0000214 for (auto SplitVT : SplitVTs) {
215 Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
Tim Northover9a467182016-09-21 12:57:45 +0000216 SplitArgs.push_back(
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000217 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
218 SplitTy, OrigArg.Flags, OrigArg.IsFixed});
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000219 if (NeedsRegBlock)
220 SplitArgs.back().Flags.setInConsecutiveRegs();
Tim Northoverb18ea162016-09-20 15:20:36 +0000221 }
222
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000223 SplitArgs.back().Flags.setInConsecutiveRegsLast();
224
Tim Northoverc2c545b2017-03-06 23:50:28 +0000225 for (unsigned i = 0; i < Offsets.size(); ++i)
226 PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8);
Tim Northoverb18ea162016-09-20 15:20:36 +0000227}
228
229bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000230 const Value *Val,
231 ArrayRef<unsigned> VRegs) const {
Tim Northover05cc4852016-12-07 21:05:38 +0000232 auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000233 assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
234 "Return value without a vreg");
235
Tim Northover05cc4852016-12-07 21:05:38 +0000236 bool Success = true;
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000237 if (!VRegs.empty()) {
238 MachineFunction &MF = MIRBuilder.getMF();
239 const Function &F = MF.getFunction();
240
Amara Emerson5a3bb682018-06-01 13:20:32 +0000241 MachineRegisterInfo &MRI = MF.getRegInfo();
Tim Northoverb18ea162016-09-20 15:20:36 +0000242 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
243 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
Tim Northoverb18ea162016-09-20 15:20:36 +0000244 auto &DL = F.getParent()->getDataLayout();
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000245 LLVMContext &Ctx = Val->getType()->getContext();
Tim Northoverb18ea162016-09-20 15:20:36 +0000246
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000247 SmallVector<EVT, 4> SplitEVTs;
248 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
249 assert(VRegs.size() == SplitEVTs.size() &&
250 "For each split Type there should be exactly one VReg.");
Tim Northover9a467182016-09-21 12:57:45 +0000251
252 SmallVector<ArgInfo, 8> SplitArgs;
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000253 for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
254 // We zero-extend i1s to i8.
255 unsigned CurVReg = VRegs[i];
256 if (MRI.getType(VRegs[i]).getSizeInBits() == 1) {
257 CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg)
258 ->getOperand(0)
259 .getReg();
260 }
261
262 ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx)};
263 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
264 splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, F.getCallingConv(),
265 [&](unsigned Reg, uint64_t Offset) {
266 MIRBuilder.buildExtract(Reg, CurVReg, Offset);
267 });
268 }
Tim Northoverb18ea162016-09-20 15:20:36 +0000269
Tim Northoverd9433542017-01-17 22:30:10 +0000270 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn);
271 Success = handleAssignments(MIRBuilder, SplitArgs, Handler);
Tim Northoverb18ea162016-09-20 15:20:36 +0000272 }
Tim Northover05cc4852016-12-07 21:05:38 +0000273
274 MIRBuilder.insertInstr(MIB);
275 return Success;
Tim Northoverb18ea162016-09-20 15:20:36 +0000276}
277
Tim Northover862758ec2016-09-21 12:57:35 +0000278bool AArch64CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
279 const Function &F,
280 ArrayRef<unsigned> VRegs) const {
Tim Northover406024a2016-08-10 21:44:01 +0000281 MachineFunction &MF = MIRBuilder.getMF();
Tim Northoverb18ea162016-09-20 15:20:36 +0000282 MachineBasicBlock &MBB = MIRBuilder.getMBB();
283 MachineRegisterInfo &MRI = MF.getRegInfo();
Tim Northoverb18ea162016-09-20 15:20:36 +0000284 auto &DL = F.getParent()->getDataLayout();
Tim Northover406024a2016-08-10 21:44:01 +0000285
Tim Northover9a467182016-09-21 12:57:45 +0000286 SmallVector<ArgInfo, 8> SplitArgs;
Tim Northoverb18ea162016-09-20 15:20:36 +0000287 unsigned i = 0;
Reid Kleckner45707d42017-03-16 22:59:15 +0000288 for (auto &Arg : F.args()) {
Amara Emersond78d65c2017-11-30 20:06:02 +0000289 if (DL.getTypeStoreSize(Arg.getType()) == 0)
290 continue;
Tim Northover9a467182016-09-21 12:57:45 +0000291 ArgInfo OrigArg{VRegs[i], Arg.getType()};
Reid Klecknera0b45f42017-05-03 18:17:31 +0000292 setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F);
Tim Northoverc2c545b2017-03-06 23:50:28 +0000293 bool Split = false;
294 LLT Ty = MRI.getType(VRegs[i]);
295 unsigned Dst = VRegs[i];
296
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000297 splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv(),
Tim Northoverc2c545b2017-03-06 23:50:28 +0000298 [&](unsigned Reg, uint64_t Offset) {
299 if (!Split) {
300 Split = true;
301 Dst = MRI.createGenericVirtualRegister(Ty);
302 MIRBuilder.buildUndef(Dst);
303 }
304 unsigned Tmp = MRI.createGenericVirtualRegister(Ty);
305 MIRBuilder.buildInsert(Tmp, Dst, Reg, Offset);
306 Dst = Tmp;
Tim Northoverb18ea162016-09-20 15:20:36 +0000307 });
Tim Northoverc2c545b2017-03-06 23:50:28 +0000308
309 if (Dst != VRegs[i])
310 MIRBuilder.buildCopy(VRegs[i], Dst);
Tim Northoverb18ea162016-09-20 15:20:36 +0000311 ++i;
312 }
313
314 if (!MBB.empty())
315 MIRBuilder.setInstr(*MBB.begin());
Tim Northover406024a2016-08-10 21:44:01 +0000316
317 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
318 CCAssignFn *AssignFn =
319 TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
320
Tim Northoverd9433542017-01-17 22:30:10 +0000321 FormalArgHandler Handler(MIRBuilder, MRI, AssignFn);
322 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
Tim Northover9a467182016-09-21 12:57:45 +0000323 return false;
Tim Northoverb18ea162016-09-20 15:20:36 +0000324
Tim Northovere9600d82017-02-08 17:57:27 +0000325 if (F.isVarArg()) {
326 if (!MF.getSubtarget<AArch64Subtarget>().isTargetDarwin()) {
327 // FIXME: we need to reimplement saveVarArgsRegisters from
328 // AArch64ISelLowering.
329 return false;
330 }
331
332 // We currently pass all varargs at 8-byte alignment.
333 uint64_t StackOffset = alignTo(Handler.StackUsed, 8);
334
335 auto &MFI = MIRBuilder.getMF().getFrameInfo();
336 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
337 FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackOffset, true));
338 }
339
Tri Vo6c47c622018-09-22 22:17:50 +0000340 auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
341 if (Subtarget.hasCustomCallingConv())
342 Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
343
Tim Northoverb18ea162016-09-20 15:20:36 +0000344 // Move back to the end of the basic block.
345 MIRBuilder.setMBB(MBB);
346
Tim Northover9a467182016-09-21 12:57:45 +0000347 return true;
Tim Northover406024a2016-08-10 21:44:01 +0000348}
349
350bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
Diana Picusd79253a2017-03-20 14:40:18 +0000351 CallingConv::ID CallConv,
Tim Northover9a467182016-09-21 12:57:45 +0000352 const MachineOperand &Callee,
353 const ArgInfo &OrigRet,
354 ArrayRef<ArgInfo> OrigArgs) const {
Tim Northover406024a2016-08-10 21:44:01 +0000355 MachineFunction &MF = MIRBuilder.getMF();
Matthias Braunf1caa282017-12-15 22:22:58 +0000356 const Function &F = MF.getFunction();
Tim Northoverb18ea162016-09-20 15:20:36 +0000357 MachineRegisterInfo &MRI = MF.getRegInfo();
358 auto &DL = F.getParent()->getDataLayout();
359
Tim Northover9a467182016-09-21 12:57:45 +0000360 SmallVector<ArgInfo, 8> SplitArgs;
361 for (auto &OrigArg : OrigArgs) {
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000362 splitToValueTypes(OrigArg, SplitArgs, DL, MRI, CallConv,
Tim Northoverc2c545b2017-03-06 23:50:28 +0000363 [&](unsigned Reg, uint64_t Offset) {
364 MIRBuilder.buildExtract(Reg, OrigArg.Reg, Offset);
Tim Northoverb18ea162016-09-20 15:20:36 +0000365 });
Amara Emerson7a05d1c2019-03-08 22:17:00 +0000366 // AAPCS requires that we zero-extend i1 to 8 bits by the caller.
367 if (OrigArg.Ty->isIntegerTy(1))
368 SplitArgs.back().Flags.setZExt();
Tim Northoverb18ea162016-09-20 15:20:36 +0000369 }
Tim Northover406024a2016-08-10 21:44:01 +0000370
Tim Northover406024a2016-08-10 21:44:01 +0000371 // Find out which ABI gets to decide where things go.
372 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
Tim Northoverd9433542017-01-17 22:30:10 +0000373 CCAssignFn *AssignFnFixed =
Diana Picusd79253a2017-03-20 14:40:18 +0000374 TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
Tim Northoverd9433542017-01-17 22:30:10 +0000375 CCAssignFn *AssignFnVarArg =
Diana Picusd79253a2017-03-20 14:40:18 +0000376 TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/true);
Tim Northover406024a2016-08-10 21:44:01 +0000377
Tim Northover509091f2017-01-17 22:43:34 +0000378 auto CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
379
Tim Northovera5e38fa2016-09-22 13:49:25 +0000380 // Create a temporarily-floating call instruction so we can add the implicit
381 // uses of arg registers.
382 auto MIB = MIRBuilder.buildInstrNoInsert(Callee.isReg() ? AArch64::BLR
383 : AArch64::BL);
Diana Picus116bbab2017-01-13 09:58:52 +0000384 MIB.add(Callee);
Tim Northover406024a2016-08-10 21:44:01 +0000385
386 // Tell the call which registers are clobbered.
Nick Desaulniers287a3be2018-09-07 20:58:57 +0000387 auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
Tri Vo6c47c622018-09-22 22:17:50 +0000388 const uint32_t *Mask = TRI->getCallPreservedMask(MF, F.getCallingConv());
389 if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv())
390 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
391 MIB.addRegMask(Mask);
Tim Northover406024a2016-08-10 21:44:01 +0000392
Nick Desaulniers287a3be2018-09-07 20:58:57 +0000393 if (TRI->isAnyArgRegReserved(MF))
394 TRI->emitReservedArgRegCallError(MF);
395
Tim Northovera5e38fa2016-09-22 13:49:25 +0000396 // Do the actual argument marshalling.
397 SmallVector<unsigned, 8> PhysRegs;
Tim Northoverd9433542017-01-17 22:30:10 +0000398 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFnFixed,
399 AssignFnVarArg);
400 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
Tim Northovera5e38fa2016-09-22 13:49:25 +0000401 return false;
402
403 // Now we can add the actual call instruction to the correct basic block.
404 MIRBuilder.insertInstr(MIB);
Tim Northover406024a2016-08-10 21:44:01 +0000405
Quentin Colombetf38015e2016-12-22 21:56:31 +0000406 // If Callee is a reg, since it is used by a target specific
407 // instruction, it must have a register class matching the
408 // constraint of that instruction.
409 if (Callee.isReg())
410 MIB->getOperand(0).setReg(constrainOperandRegClass(
411 MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
Aditya Nandakumar59999052018-02-26 22:56:21 +0000412 *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(), Callee, 0));
Quentin Colombetf38015e2016-12-22 21:56:31 +0000413
Tim Northover406024a2016-08-10 21:44:01 +0000414 // Finally we can copy the returned value back into its virtual-register. In
415 // symmetry with the arugments, the physical register must be an
416 // implicit-define of the call instruction.
417 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
Tim Northover9a467182016-09-21 12:57:45 +0000418 if (OrigRet.Reg) {
419 SplitArgs.clear();
Tim Northoverb18ea162016-09-20 15:20:36 +0000420
421 SmallVector<uint64_t, 8> RegOffsets;
Tim Northover9a467182016-09-21 12:57:45 +0000422 SmallVector<unsigned, 8> SplitRegs;
Tim Northoveref1fc5a2017-08-21 21:56:11 +0000423 splitToValueTypes(OrigRet, SplitArgs, DL, MRI, F.getCallingConv(),
Tim Northoverc2c545b2017-03-06 23:50:28 +0000424 [&](unsigned Reg, uint64_t Offset) {
425 RegOffsets.push_back(Offset);
426 SplitRegs.push_back(Reg);
Tim Northoverb18ea162016-09-20 15:20:36 +0000427 });
428
Tim Northoverd9433542017-01-17 22:30:10 +0000429 CallReturnHandler Handler(MIRBuilder, MRI, MIB, RetAssignFn);
430 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
Tim Northover9a467182016-09-21 12:57:45 +0000431 return false;
Tim Northover406024a2016-08-10 21:44:01 +0000432
Tim Northoverb18ea162016-09-20 15:20:36 +0000433 if (!RegOffsets.empty())
Tim Northover9a467182016-09-21 12:57:45 +0000434 MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets);
Tim Northoverb18ea162016-09-20 15:20:36 +0000435 }
436
Serge Pavlovd526b132017-05-09 13:35:13 +0000437 CallSeqStart.addImm(Handler.StackSize).addImm(0);
Tim Northover509091f2017-01-17 22:43:34 +0000438 MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
439 .addImm(Handler.StackSize)
440 .addImm(0);
441
Tim Northover406024a2016-08-10 21:44:01 +0000442 return true;
443}