blob: 648dec5428d4cc960bc37afd2261c253801f8217 [file] [log] [blame]
Petar Jovanovicfac93e22018-02-23 11:06:40 +00001//===- MipsCallLowering.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// This file implements the lowering of LLVM calls to machine code calls for
12/// GlobalISel.
13//
14//===----------------------------------------------------------------------===//
15
16#include "MipsCallLowering.h"
Petar Jovanovic366857a2018-04-11 15:12:32 +000017#include "MipsCCState.h"
Petar Jovanovic326ec322018-06-06 07:24:52 +000018#include "MipsTargetMachine.h"
Alexander Ivchenko49168f62018-08-02 08:33:31 +000019#include "llvm/CodeGen/Analysis.h"
Petar Jovanovicfac93e22018-02-23 11:06:40 +000020#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
21
22using namespace llvm;
23
24MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI)
25 : CallLowering(&TLI) {}
26
Petar Jovanovic65d463b2018-08-23 20:41:09 +000027bool MipsCallLowering::MipsHandler::assign(unsigned VReg,
28 const CCValAssign &VA) {
Petar Jovanovic366857a2018-04-11 15:12:32 +000029 if (VA.isRegLoc()) {
Petar Jovanovic65d463b2018-08-23 20:41:09 +000030 assignValueToReg(VReg, VA);
Petar Jovanovic226e6112018-07-03 09:31:48 +000031 } else if (VA.isMemLoc()) {
Petar Jovanovic65d463b2018-08-23 20:41:09 +000032 assignValueToAddress(VReg, VA);
Petar Jovanovic366857a2018-04-11 15:12:32 +000033 } else {
34 return false;
35 }
36 return true;
37}
38
39namespace {
40class IncomingValueHandler : public MipsCallLowering::MipsHandler {
41public:
42 IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
43 : MipsHandler(MIRBuilder, MRI) {}
44
45 bool handle(ArrayRef<CCValAssign> ArgLocs,
46 ArrayRef<CallLowering::ArgInfo> Args);
47
48private:
Petar Jovanovic65d463b2018-08-23 20:41:09 +000049 void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +000050
Petar Jovanovic65d463b2018-08-23 20:41:09 +000051 unsigned getStackAddress(const CCValAssign &VA,
52 MachineMemOperand *&MMO) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +000053
Petar Jovanovic65d463b2018-08-23 20:41:09 +000054 void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
Petar Jovanovic366857a2018-04-11 15:12:32 +000055
Petar Jovanovic326ec322018-06-06 07:24:52 +000056 virtual void markPhysRegUsed(unsigned PhysReg) {
Petar Jovanovic366857a2018-04-11 15:12:32 +000057 MIRBuilder.getMBB().addLiveIn(PhysReg);
58 }
Petar Jovanovic226e6112018-07-03 09:31:48 +000059
Petar Jovanovic65d463b2018-08-23 20:41:09 +000060 void buildLoad(unsigned Val, const CCValAssign &VA) {
61 MachineMemOperand *MMO;
62 unsigned Addr = getStackAddress(VA, MMO);
Petar Jovanovic226e6112018-07-03 09:31:48 +000063 MIRBuilder.buildLoad(Val, Addr, *MMO);
64 }
Petar Jovanovic366857a2018-04-11 15:12:32 +000065};
Petar Jovanovic326ec322018-06-06 07:24:52 +000066
67class CallReturnHandler : public IncomingValueHandler {
68public:
69 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
70 MachineInstrBuilder &MIB)
71 : IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
72
73private:
Petar Jovanovic226e6112018-07-03 09:31:48 +000074 void markPhysRegUsed(unsigned PhysReg) override {
Petar Jovanovic326ec322018-06-06 07:24:52 +000075 MIB.addDef(PhysReg, RegState::Implicit);
76 }
77
78 MachineInstrBuilder &MIB;
79};
80
Petar Jovanovic366857a2018-04-11 15:12:32 +000081} // end anonymous namespace
82
83void IncomingValueHandler::assignValueToReg(unsigned ValVReg,
Petar Jovanovic65d463b2018-08-23 20:41:09 +000084 const CCValAssign &VA) {
85 unsigned PhysReg = VA.getLocReg();
86 switch (VA.getLocInfo()) {
87 case CCValAssign::LocInfo::SExt:
88 case CCValAssign::LocInfo::ZExt:
89 case CCValAssign::LocInfo::AExt: {
90 auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
91 MIRBuilder.buildTrunc(ValVReg, Copy);
92 break;
93 }
94 default:
95 MIRBuilder.buildCopy(ValVReg, PhysReg);
96 break;
97 }
Petar Jovanovic366857a2018-04-11 15:12:32 +000098 markPhysRegUsed(PhysReg);
99}
100
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000101unsigned IncomingValueHandler::getStackAddress(const CCValAssign &VA,
102 MachineMemOperand *&MMO) {
103 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
104 unsigned Offset = VA.getLocMemOffset();
Petar Jovanovic226e6112018-07-03 09:31:48 +0000105 MachineFrameInfo &MFI = MIRBuilder.getMF().getFrameInfo();
106
107 int FI = MFI.CreateFixedObject(Size, Offset, true);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000108 MachinePointerInfo MPO =
109 MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
110 MMO = MIRBuilder.getMF().getMachineMemOperand(MPO, MachineMemOperand::MOLoad,
111 Size, /* Alignment */ 0);
Petar Jovanovic226e6112018-07-03 09:31:48 +0000112
113 unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
114 MIRBuilder.buildFrameIndex(AddrReg, FI);
115
116 return AddrReg;
117}
118
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000119void IncomingValueHandler::assignValueToAddress(unsigned ValVReg,
120 const CCValAssign &VA) {
121 if (VA.getLocInfo() == CCValAssign::SExt ||
122 VA.getLocInfo() == CCValAssign::ZExt ||
123 VA.getLocInfo() == CCValAssign::AExt) {
124 unsigned LoadReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
125 buildLoad(LoadReg, VA);
126 MIRBuilder.buildTrunc(ValVReg, LoadReg);
127 } else
128 buildLoad(ValVReg, VA);
Petar Jovanovic226e6112018-07-03 09:31:48 +0000129}
130
Petar Jovanovic366857a2018-04-11 15:12:32 +0000131bool IncomingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
132 ArrayRef<CallLowering::ArgInfo> Args) {
133 for (unsigned i = 0, ArgsSize = Args.size(); i < ArgsSize; ++i) {
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000134 if (!assign(Args[i].Reg, ArgLocs[i]))
Petar Jovanovic366857a2018-04-11 15:12:32 +0000135 return false;
136 }
137 return true;
138}
139
140namespace {
141class OutgoingValueHandler : public MipsCallLowering::MipsHandler {
142public:
143 OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
144 MachineInstrBuilder &MIB)
145 : MipsHandler(MIRBuilder, MRI), MIB(MIB) {}
146
147 bool handle(ArrayRef<CCValAssign> ArgLocs,
148 ArrayRef<CallLowering::ArgInfo> Args);
149
150private:
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000151 void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +0000152
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000153 unsigned getStackAddress(const CCValAssign &VA,
154 MachineMemOperand *&MMO) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +0000155
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000156 void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
157
158 unsigned extendRegister(unsigned ValReg, const CCValAssign &VA);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000159
160 MachineInstrBuilder &MIB;
161};
162} // end anonymous namespace
163
164void OutgoingValueHandler::assignValueToReg(unsigned ValVReg,
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000165 const CCValAssign &VA) {
166 unsigned PhysReg = VA.getLocReg();
167 unsigned ExtReg = extendRegister(ValVReg, VA);
168 MIRBuilder.buildCopy(PhysReg, ExtReg);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000169 MIB.addUse(PhysReg, RegState::Implicit);
170}
171
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000172unsigned OutgoingValueHandler::getStackAddress(const CCValAssign &VA,
173 MachineMemOperand *&MMO) {
Petar Jovanovic226e6112018-07-03 09:31:48 +0000174 LLT p0 = LLT::pointer(0, 32);
175 LLT s32 = LLT::scalar(32);
176 unsigned SPReg = MRI.createGenericVirtualRegister(p0);
177 MIRBuilder.buildCopy(SPReg, Mips::SP);
178
179 unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000180 unsigned Offset = VA.getLocMemOffset();
Petar Jovanovic226e6112018-07-03 09:31:48 +0000181 MIRBuilder.buildConstant(OffsetReg, Offset);
182
183 unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
184 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
185
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000186 MachinePointerInfo MPO =
187 MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
188 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
189 MMO = MIRBuilder.getMF().getMachineMemOperand(MPO, MachineMemOperand::MOStore,
190 Size, /* Alignment */ 0);
191
Petar Jovanovic226e6112018-07-03 09:31:48 +0000192 return AddrReg;
193}
194
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000195void OutgoingValueHandler::assignValueToAddress(unsigned ValVReg,
196 const CCValAssign &VA) {
197 MachineMemOperand *MMO;
198 unsigned Addr = getStackAddress(VA, MMO);
199 unsigned ExtReg = extendRegister(ValVReg, VA);
200 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
201}
202
203unsigned OutgoingValueHandler::extendRegister(unsigned ValReg,
204 const CCValAssign &VA) {
205 LLT LocTy{VA.getLocVT()};
206 switch (VA.getLocInfo()) {
207 case CCValAssign::SExt: {
208 unsigned ExtReg = MRI.createGenericVirtualRegister(LocTy);
209 MIRBuilder.buildSExt(ExtReg, ValReg);
210 return ExtReg;
211 }
212 case CCValAssign::ZExt: {
213 unsigned ExtReg = MRI.createGenericVirtualRegister(LocTy);
214 MIRBuilder.buildZExt(ExtReg, ValReg);
215 return ExtReg;
216 }
217 case CCValAssign::AExt: {
218 unsigned ExtReg = MRI.createGenericVirtualRegister(LocTy);
219 MIRBuilder.buildAnyExt(ExtReg, ValReg);
220 return ExtReg;
221 }
222 // TODO : handle upper extends
223 case CCValAssign::Full:
224 return ValReg;
225 default:
226 break;
227 }
228 llvm_unreachable("unable to extend register");
Petar Jovanovic226e6112018-07-03 09:31:48 +0000229}
230
Petar Jovanovic366857a2018-04-11 15:12:32 +0000231bool OutgoingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
232 ArrayRef<CallLowering::ArgInfo> Args) {
233 for (unsigned i = 0; i < Args.size(); ++i) {
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000234 if (!assign(Args[i].Reg, ArgLocs[i]))
Petar Jovanovic366857a2018-04-11 15:12:32 +0000235 return false;
236 }
237 return true;
238}
239
240static bool isSupportedType(Type *T) {
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000241 if (T->isIntegerTy() && T->getScalarSizeInBits() <= 32)
Petar Jovanovic366857a2018-04-11 15:12:32 +0000242 return true;
Petar Jovanovic58c02102018-07-25 12:35:01 +0000243 if (T->isPointerTy())
244 return true;
Petar Jovanovic366857a2018-04-11 15:12:32 +0000245 return false;
246}
247
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000248CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT,
249 const ISD::ArgFlagsTy &Flags) {
250 if (VT.getSizeInBits() == RegisterVT.getSizeInBits())
251 return CCValAssign::LocInfo::Full;
252 if (Flags.isSExt())
253 return CCValAssign::LocInfo::SExt;
254 if (Flags.isZExt())
255 return CCValAssign::LocInfo::ZExt;
256 return CCValAssign::LocInfo::AExt;
257}
258
259template <typename T>
260void setLocInfo(SmallVectorImpl<CCValAssign> &ArgLocs,
261 const SmallVectorImpl<T> &Arguments) {
262 for (unsigned i = 0; i < ArgLocs.size(); ++i) {
263 const CCValAssign &VA = ArgLocs[i];
264 CCValAssign::LocInfo LocInfo = determineLocInfo(
265 Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags);
266 if (VA.isMemLoc())
267 ArgLocs[i] =
268 CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
269 VA.getLocMemOffset(), VA.getLocVT(), LocInfo);
270 else
271 ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
272 VA.getLocReg(), VA.getLocVT(), LocInfo);
273 }
274}
275
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000276bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000277 const Value *Val,
278 ArrayRef<unsigned> VRegs) const {
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000279
280 MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
281
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000282 if (Val != nullptr && !isSupportedType(Val->getType()))
283 return false;
Petar Jovanovic366857a2018-04-11 15:12:32 +0000284
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000285 if (!VRegs.empty()) {
Petar Jovanovic366857a2018-04-11 15:12:32 +0000286 MachineFunction &MF = MIRBuilder.getMF();
287 const Function &F = MF.getFunction();
288 const DataLayout &DL = MF.getDataLayout();
289 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000290 LLVMContext &Ctx = Val->getType()->getContext();
291
292 SmallVector<EVT, 4> SplitEVTs;
293 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
294 assert(VRegs.size() == SplitEVTs.size() &&
295 "For each split Type there should be exactly one VReg.");
Petar Jovanovic366857a2018-04-11 15:12:32 +0000296
297 SmallVector<ArgInfo, 8> RetInfos;
298 SmallVector<unsigned, 8> OrigArgIndices;
299
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000300 for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
301 ArgInfo CurArgInfo = ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)};
302 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
303 splitToValueTypes(CurArgInfo, 0, RetInfos, OrigArgIndices);
304 }
Petar Jovanovic366857a2018-04-11 15:12:32 +0000305
306 SmallVector<ISD::OutputArg, 8> Outs;
307 subTargetRegTypeForCallingConv(
308 MIRBuilder, RetInfos, OrigArgIndices,
309 [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
310 unsigned origIdx, unsigned partOffs) {
311 Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
312 });
313
314 SmallVector<CCValAssign, 16> ArgLocs;
315 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
316 F.getContext());
317 CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn());
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000318 setLocInfo(ArgLocs, Outs);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000319
320 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
321 if (!RetHandler.handle(ArgLocs, RetInfos)) {
322 return false;
323 }
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000324 }
325 MIRBuilder.insertInstr(Ret);
326 return true;
327}
328
329bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
330 const Function &F,
331 ArrayRef<unsigned> VRegs) const {
332
333 // Quick exit if there aren't any args.
334 if (F.arg_empty())
335 return true;
336
Petar Jovanovic366857a2018-04-11 15:12:32 +0000337 if (F.isVarArg()) {
338 return false;
339 }
340
341 for (auto &Arg : F.args()) {
342 if (!isSupportedType(Arg.getType()))
343 return false;
344 }
345
346 MachineFunction &MF = MIRBuilder.getMF();
347 const DataLayout &DL = MF.getDataLayout();
348 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
349
350 SmallVector<ArgInfo, 8> ArgInfos;
351 SmallVector<unsigned, 8> OrigArgIndices;
352 unsigned i = 0;
353 for (auto &Arg : F.args()) {
354 ArgInfo AInfo(VRegs[i], Arg.getType());
355 setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
356 splitToValueTypes(AInfo, i, ArgInfos, OrigArgIndices);
357 ++i;
358 }
359
360 SmallVector<ISD::InputArg, 8> Ins;
361 subTargetRegTypeForCallingConv(
362 MIRBuilder, ArgInfos, OrigArgIndices,
363 [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
364 unsigned partOffs) {
365 Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
366 });
367
368 SmallVector<CCValAssign, 16> ArgLocs;
369 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
370 F.getContext());
371
Petar Jovanovic226e6112018-07-03 09:31:48 +0000372 const MipsTargetMachine &TM =
373 static_cast<const MipsTargetMachine &>(MF.getTarget());
374 const MipsABIInfo &ABI = TM.getABI();
375 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
376 1);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000377 CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000378 setLocInfo(ArgLocs, Ins);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000379
Petar Jovanovic667e2132018-04-12 17:01:46 +0000380 IncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
Petar Jovanovic366857a2018-04-11 15:12:32 +0000381 if (!Handler.handle(ArgLocs, ArgInfos))
382 return false;
383
384 return true;
385}
386
Petar Jovanovic326ec322018-06-06 07:24:52 +0000387bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
388 CallingConv::ID CallConv,
389 const MachineOperand &Callee,
390 const ArgInfo &OrigRet,
391 ArrayRef<ArgInfo> OrigArgs) const {
392
393 if (CallConv != CallingConv::C)
394 return false;
395
396 for (auto &Arg : OrigArgs) {
397 if (!isSupportedType(Arg.Ty))
398 return false;
399 if (Arg.Flags.isByVal() || Arg.Flags.isSRet())
400 return false;
401 }
402 if (OrigRet.Reg && !isSupportedType(OrigRet.Ty))
403 return false;
404
405 MachineFunction &MF = MIRBuilder.getMF();
406 const Function &F = MF.getFunction();
407 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
408 const MipsTargetMachine &TM =
409 static_cast<const MipsTargetMachine &>(MF.getTarget());
410 const MipsABIInfo &ABI = TM.getABI();
411
412 MachineInstrBuilder CallSeqStart =
413 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
414
415 // FIXME: Add support for pic calling sequences, long call sequences for O32,
416 // N32 and N64. First handle the case when Callee.isReg().
417 if (Callee.isReg())
418 return false;
419
420 MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(Mips::JAL);
421 MIB.addDef(Mips::SP, RegState::Implicit);
422 MIB.add(Callee);
423 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
424 MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
425
426 TargetLowering::ArgListTy FuncOrigArgs;
427 FuncOrigArgs.reserve(OrigArgs.size());
428
429 SmallVector<ArgInfo, 8> ArgInfos;
430 SmallVector<unsigned, 8> OrigArgIndices;
431 unsigned i = 0;
432 for (auto &Arg : OrigArgs) {
433
434 TargetLowering::ArgListEntry Entry;
435 Entry.Ty = Arg.Ty;
436 FuncOrigArgs.push_back(Entry);
437
438 splitToValueTypes(Arg, i, ArgInfos, OrigArgIndices);
439 ++i;
440 }
441
442 SmallVector<ISD::OutputArg, 8> Outs;
443 subTargetRegTypeForCallingConv(
444 MIRBuilder, ArgInfos, OrigArgIndices,
445 [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
446 unsigned partOffs) {
447 Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
448 });
449
450 SmallVector<CCValAssign, 8> ArgLocs;
451 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
452 F.getContext());
453
Petar Jovanovic226e6112018-07-03 09:31:48 +0000454 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000455 const char *Call = Callee.isSymbol() ? Callee.getSymbolName() : nullptr;
456 CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000457 setLocInfo(ArgLocs, Outs);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000458
459 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
460 if (!RetHandler.handle(ArgLocs, ArgInfos)) {
461 return false;
462 }
463
Petar Jovanovic226e6112018-07-03 09:31:48 +0000464 unsigned NextStackOffset = CCInfo.getNextStackOffset();
465 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
466 unsigned StackAlignment = TFL->getStackAlignment();
467 NextStackOffset = alignTo(NextStackOffset, StackAlignment);
468 CallSeqStart.addImm(NextStackOffset).addImm(0);
469
Petar Jovanovic326ec322018-06-06 07:24:52 +0000470 MIRBuilder.insertInstr(MIB);
471
472 if (OrigRet.Reg) {
473
474 ArgInfos.clear();
475 SmallVector<unsigned, 8> OrigRetIndices;
476
477 splitToValueTypes(OrigRet, 0, ArgInfos, OrigRetIndices);
478
479 SmallVector<ISD::InputArg, 8> Ins;
480 subTargetRegTypeForCallingConv(
481 MIRBuilder, ArgInfos, OrigRetIndices,
482 [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
483 unsigned origIdx, unsigned partOffs) {
484 Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
485 });
486
487 SmallVector<CCValAssign, 8> ArgLocs;
488 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
489 F.getContext());
490
491 CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), OrigRet.Ty, Call);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000492 setLocInfo(ArgLocs, Ins);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000493
494 CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB);
495 if (!Handler.handle(ArgLocs, ArgInfos))
496 return false;
497 }
498
Petar Jovanovic226e6112018-07-03 09:31:48 +0000499 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000500
501 return true;
502}
503
Petar Jovanovic366857a2018-04-11 15:12:32 +0000504void MipsCallLowering::subTargetRegTypeForCallingConv(
505 MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
506 ArrayRef<unsigned> OrigArgIndices, const FunTy &PushBack) const {
507 MachineFunction &MF = MIRBuilder.getMF();
508 const Function &F = MF.getFunction();
509 const DataLayout &DL = F.getParent()->getDataLayout();
510 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
511
512 unsigned ArgNo = 0;
513 for (auto &Arg : Args) {
514
515 EVT VT = TLI.getValueType(DL, Arg.Ty);
Matt Arsenault81920b02018-07-28 13:25:19 +0000516 MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
517 F.getCallingConv(), VT);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000518
519 ISD::ArgFlagsTy Flags = Arg.Flags;
520 Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
521
522 PushBack(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo], 0);
523
524 ++ArgNo;
525 }
526}
527
528void MipsCallLowering::splitToValueTypes(
529 const ArgInfo &OrigArg, unsigned OriginalIndex,
530 SmallVectorImpl<ArgInfo> &SplitArgs,
531 SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const {
532
533 // TODO : perform structure and array split. For now we only deal with
534 // types that pass isSupportedType check.
535 SplitArgs.push_back(OrigArg);
536 SplitArgsOrigIndices.push_back(OriginalIndex);
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000537}