blob: 4d070f9f523af6ef37daf921fe374d052845d7b9 [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
Petar Jovanovicff1bc622018-09-28 13:28:47 +000039bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<unsigned> VRegs,
40 ArrayRef<CCValAssign> ArgLocs,
41 unsigned ArgLocsStartIndex) {
42 for (unsigned i = 0; i < VRegs.size(); ++i)
43 if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i]))
44 return false;
45 return true;
46}
47
48void MipsCallLowering::MipsHandler::setMostSignificantFirst(
49 SmallVectorImpl<unsigned> &VRegs) {
50 if (MIRBuilder.getMF().getDataLayout().isLittleEndian())
51 std::reverse(VRegs.begin(), VRegs.end());
52}
53
54bool MipsCallLowering::MipsHandler::handle(
55 ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) {
56 SmallVector<unsigned, 4> VRegs;
57 unsigned SplitLength;
58 const Function &F = MIRBuilder.getMF().getFunction();
59 const DataLayout &DL = F.getParent()->getDataLayout();
60 const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>(
61 MIRBuilder.getMF().getSubtarget().getTargetLowering());
62
63 for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size();
64 ++ArgsIndex, ArgLocsIndex += SplitLength) {
65 EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty);
66 SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(),
67 F.getCallingConv(), VT);
68 if (SplitLength > 1) {
69 VRegs.clear();
70 MVT RegisterVT = TLI.getRegisterTypeForCallingConv(
71 F.getContext(), F.getCallingConv(), VT);
72 for (unsigned i = 0; i < SplitLength; ++i)
73 VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT}));
74
75 if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg))
76 return false;
77 } else {
78 if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex]))
79 return false;
80 }
81 }
82 return true;
83}
84
Petar Jovanovic366857a2018-04-11 15:12:32 +000085namespace {
86class IncomingValueHandler : public MipsCallLowering::MipsHandler {
87public:
88 IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
89 : MipsHandler(MIRBuilder, MRI) {}
90
Petar Jovanovic366857a2018-04-11 15:12:32 +000091private:
Petar Jovanovic65d463b2018-08-23 20:41:09 +000092 void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +000093
Petar Jovanovic65d463b2018-08-23 20:41:09 +000094 unsigned getStackAddress(const CCValAssign &VA,
95 MachineMemOperand *&MMO) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +000096
Petar Jovanovic65d463b2018-08-23 20:41:09 +000097 void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
Petar Jovanovic366857a2018-04-11 15:12:32 +000098
Petar Jovanovicff1bc622018-09-28 13:28:47 +000099 bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
100 ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
101 unsigned ArgsReg) override;
102
Petar Jovanovic326ec322018-06-06 07:24:52 +0000103 virtual void markPhysRegUsed(unsigned PhysReg) {
Petar Jovanovic366857a2018-04-11 15:12:32 +0000104 MIRBuilder.getMBB().addLiveIn(PhysReg);
105 }
Petar Jovanovic226e6112018-07-03 09:31:48 +0000106
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000107 void buildLoad(unsigned Val, const CCValAssign &VA) {
108 MachineMemOperand *MMO;
109 unsigned Addr = getStackAddress(VA, MMO);
Petar Jovanovic226e6112018-07-03 09:31:48 +0000110 MIRBuilder.buildLoad(Val, Addr, *MMO);
111 }
Petar Jovanovic366857a2018-04-11 15:12:32 +0000112};
Petar Jovanovic326ec322018-06-06 07:24:52 +0000113
114class CallReturnHandler : public IncomingValueHandler {
115public:
116 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
117 MachineInstrBuilder &MIB)
118 : IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
119
120private:
Petar Jovanovic226e6112018-07-03 09:31:48 +0000121 void markPhysRegUsed(unsigned PhysReg) override {
Petar Jovanovic326ec322018-06-06 07:24:52 +0000122 MIB.addDef(PhysReg, RegState::Implicit);
123 }
124
125 MachineInstrBuilder &MIB;
126};
127
Petar Jovanovic366857a2018-04-11 15:12:32 +0000128} // end anonymous namespace
129
130void IncomingValueHandler::assignValueToReg(unsigned ValVReg,
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000131 const CCValAssign &VA) {
132 unsigned PhysReg = VA.getLocReg();
133 switch (VA.getLocInfo()) {
134 case CCValAssign::LocInfo::SExt:
135 case CCValAssign::LocInfo::ZExt:
136 case CCValAssign::LocInfo::AExt: {
137 auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
138 MIRBuilder.buildTrunc(ValVReg, Copy);
139 break;
140 }
141 default:
142 MIRBuilder.buildCopy(ValVReg, PhysReg);
143 break;
144 }
Petar Jovanovic366857a2018-04-11 15:12:32 +0000145 markPhysRegUsed(PhysReg);
146}
147
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000148unsigned IncomingValueHandler::getStackAddress(const CCValAssign &VA,
149 MachineMemOperand *&MMO) {
150 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
151 unsigned Offset = VA.getLocMemOffset();
Petar Jovanovic226e6112018-07-03 09:31:48 +0000152 MachineFrameInfo &MFI = MIRBuilder.getMF().getFrameInfo();
153
154 int FI = MFI.CreateFixedObject(Size, Offset, true);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000155 MachinePointerInfo MPO =
156 MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
157 MMO = MIRBuilder.getMF().getMachineMemOperand(MPO, MachineMemOperand::MOLoad,
158 Size, /* Alignment */ 0);
Petar Jovanovic226e6112018-07-03 09:31:48 +0000159
160 unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
161 MIRBuilder.buildFrameIndex(AddrReg, FI);
162
163 return AddrReg;
164}
165
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000166void IncomingValueHandler::assignValueToAddress(unsigned ValVReg,
167 const CCValAssign &VA) {
168 if (VA.getLocInfo() == CCValAssign::SExt ||
169 VA.getLocInfo() == CCValAssign::ZExt ||
170 VA.getLocInfo() == CCValAssign::AExt) {
171 unsigned LoadReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
172 buildLoad(LoadReg, VA);
173 MIRBuilder.buildTrunc(ValVReg, LoadReg);
174 } else
175 buildLoad(ValVReg, VA);
Petar Jovanovic226e6112018-07-03 09:31:48 +0000176}
177
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000178bool IncomingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs,
179 ArrayRef<CCValAssign> ArgLocs,
180 unsigned ArgLocsStartIndex,
181 unsigned ArgsReg) {
182 if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex))
183 return false;
184 setMostSignificantFirst(VRegs);
185 MIRBuilder.buildMerge(ArgsReg, VRegs);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000186 return true;
187}
188
189namespace {
190class OutgoingValueHandler : public MipsCallLowering::MipsHandler {
191public:
192 OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
193 MachineInstrBuilder &MIB)
194 : MipsHandler(MIRBuilder, MRI), MIB(MIB) {}
195
Petar Jovanovic366857a2018-04-11 15:12:32 +0000196private:
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000197 void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +0000198
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000199 unsigned getStackAddress(const CCValAssign &VA,
200 MachineMemOperand *&MMO) override;
Petar Jovanovic226e6112018-07-03 09:31:48 +0000201
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000202 void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
203
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000204 bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
205 ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
206 unsigned ArgsReg) override;
207
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000208 unsigned extendRegister(unsigned ValReg, const CCValAssign &VA);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000209
210 MachineInstrBuilder &MIB;
211};
212} // end anonymous namespace
213
214void OutgoingValueHandler::assignValueToReg(unsigned ValVReg,
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000215 const CCValAssign &VA) {
216 unsigned PhysReg = VA.getLocReg();
217 unsigned ExtReg = extendRegister(ValVReg, VA);
218 MIRBuilder.buildCopy(PhysReg, ExtReg);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000219 MIB.addUse(PhysReg, RegState::Implicit);
220}
221
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000222unsigned OutgoingValueHandler::getStackAddress(const CCValAssign &VA,
223 MachineMemOperand *&MMO) {
Petar Jovanovic226e6112018-07-03 09:31:48 +0000224 LLT p0 = LLT::pointer(0, 32);
225 LLT s32 = LLT::scalar(32);
226 unsigned SPReg = MRI.createGenericVirtualRegister(p0);
227 MIRBuilder.buildCopy(SPReg, Mips::SP);
228
229 unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000230 unsigned Offset = VA.getLocMemOffset();
Petar Jovanovic226e6112018-07-03 09:31:48 +0000231 MIRBuilder.buildConstant(OffsetReg, Offset);
232
233 unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
234 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
235
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000236 MachinePointerInfo MPO =
237 MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
238 unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
239 MMO = MIRBuilder.getMF().getMachineMemOperand(MPO, MachineMemOperand::MOStore,
240 Size, /* Alignment */ 0);
241
Petar Jovanovic226e6112018-07-03 09:31:48 +0000242 return AddrReg;
243}
244
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000245void OutgoingValueHandler::assignValueToAddress(unsigned ValVReg,
246 const CCValAssign &VA) {
247 MachineMemOperand *MMO;
248 unsigned Addr = getStackAddress(VA, MMO);
249 unsigned ExtReg = extendRegister(ValVReg, VA);
250 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
251}
252
253unsigned OutgoingValueHandler::extendRegister(unsigned ValReg,
254 const CCValAssign &VA) {
255 LLT LocTy{VA.getLocVT()};
256 switch (VA.getLocInfo()) {
257 case CCValAssign::SExt: {
258 unsigned ExtReg = MRI.createGenericVirtualRegister(LocTy);
259 MIRBuilder.buildSExt(ExtReg, ValReg);
260 return ExtReg;
261 }
262 case CCValAssign::ZExt: {
263 unsigned ExtReg = MRI.createGenericVirtualRegister(LocTy);
264 MIRBuilder.buildZExt(ExtReg, ValReg);
265 return ExtReg;
266 }
267 case CCValAssign::AExt: {
268 unsigned ExtReg = MRI.createGenericVirtualRegister(LocTy);
269 MIRBuilder.buildAnyExt(ExtReg, ValReg);
270 return ExtReg;
271 }
272 // TODO : handle upper extends
273 case CCValAssign::Full:
274 return ValReg;
275 default:
276 break;
277 }
278 llvm_unreachable("unable to extend register");
Petar Jovanovic226e6112018-07-03 09:31:48 +0000279}
280
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000281bool OutgoingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs,
282 ArrayRef<CCValAssign> ArgLocs,
283 unsigned ArgLocsStartIndex,
284 unsigned ArgsReg) {
285 MIRBuilder.buildUnmerge(VRegs, ArgsReg);
286 setMostSignificantFirst(VRegs);
287 if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex))
288 return false;
289
Petar Jovanovic366857a2018-04-11 15:12:32 +0000290 return true;
291}
292
293static bool isSupportedType(Type *T) {
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000294 if (T->isIntegerTy())
Petar Jovanovic366857a2018-04-11 15:12:32 +0000295 return true;
Petar Jovanovic58c02102018-07-25 12:35:01 +0000296 if (T->isPointerTy())
297 return true;
Petar Jovanovic366857a2018-04-11 15:12:32 +0000298 return false;
299}
300
Benjamin Kramerc55e9972018-10-13 22:18:22 +0000301static CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT,
302 const ISD::ArgFlagsTy &Flags) {
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000303 // > does not mean loss of information as type RegisterVT can't hold type VT,
304 // it means that type VT is split into multiple registers of type RegisterVT
305 if (VT.getSizeInBits() >= RegisterVT.getSizeInBits())
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000306 return CCValAssign::LocInfo::Full;
307 if (Flags.isSExt())
308 return CCValAssign::LocInfo::SExt;
309 if (Flags.isZExt())
310 return CCValAssign::LocInfo::ZExt;
311 return CCValAssign::LocInfo::AExt;
312}
313
314template <typename T>
Benjamin Kramerc55e9972018-10-13 22:18:22 +0000315static void setLocInfo(SmallVectorImpl<CCValAssign> &ArgLocs,
316 const SmallVectorImpl<T> &Arguments) {
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000317 for (unsigned i = 0; i < ArgLocs.size(); ++i) {
318 const CCValAssign &VA = ArgLocs[i];
319 CCValAssign::LocInfo LocInfo = determineLocInfo(
320 Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags);
321 if (VA.isMemLoc())
322 ArgLocs[i] =
323 CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
324 VA.getLocMemOffset(), VA.getLocVT(), LocInfo);
325 else
326 ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
327 VA.getLocReg(), VA.getLocVT(), LocInfo);
328 }
329}
330
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000331bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000332 const Value *Val,
333 ArrayRef<unsigned> VRegs) const {
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000334
335 MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
336
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000337 if (Val != nullptr && !isSupportedType(Val->getType()))
338 return false;
Petar Jovanovic366857a2018-04-11 15:12:32 +0000339
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000340 if (!VRegs.empty()) {
Petar Jovanovic366857a2018-04-11 15:12:32 +0000341 MachineFunction &MF = MIRBuilder.getMF();
342 const Function &F = MF.getFunction();
343 const DataLayout &DL = MF.getDataLayout();
344 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000345 LLVMContext &Ctx = Val->getType()->getContext();
346
347 SmallVector<EVT, 4> SplitEVTs;
348 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
349 assert(VRegs.size() == SplitEVTs.size() &&
350 "For each split Type there should be exactly one VReg.");
Petar Jovanovic366857a2018-04-11 15:12:32 +0000351
352 SmallVector<ArgInfo, 8> RetInfos;
353 SmallVector<unsigned, 8> OrigArgIndices;
354
Alexander Ivchenko49168f62018-08-02 08:33:31 +0000355 for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
356 ArgInfo CurArgInfo = ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)};
357 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
358 splitToValueTypes(CurArgInfo, 0, RetInfos, OrigArgIndices);
359 }
Petar Jovanovic366857a2018-04-11 15:12:32 +0000360
361 SmallVector<ISD::OutputArg, 8> Outs;
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000362 subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000363
364 SmallVector<CCValAssign, 16> ArgLocs;
365 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
366 F.getContext());
367 CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn());
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000368 setLocInfo(ArgLocs, Outs);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000369
370 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
371 if (!RetHandler.handle(ArgLocs, RetInfos)) {
372 return false;
373 }
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000374 }
375 MIRBuilder.insertInstr(Ret);
376 return true;
377}
378
379bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
380 const Function &F,
381 ArrayRef<unsigned> VRegs) const {
382
383 // Quick exit if there aren't any args.
384 if (F.arg_empty())
385 return true;
386
Petar Jovanovic366857a2018-04-11 15:12:32 +0000387 if (F.isVarArg()) {
388 return false;
389 }
390
391 for (auto &Arg : F.args()) {
392 if (!isSupportedType(Arg.getType()))
393 return false;
394 }
395
396 MachineFunction &MF = MIRBuilder.getMF();
397 const DataLayout &DL = MF.getDataLayout();
398 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
399
400 SmallVector<ArgInfo, 8> ArgInfos;
401 SmallVector<unsigned, 8> OrigArgIndices;
402 unsigned i = 0;
403 for (auto &Arg : F.args()) {
404 ArgInfo AInfo(VRegs[i], Arg.getType());
405 setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
406 splitToValueTypes(AInfo, i, ArgInfos, OrigArgIndices);
407 ++i;
408 }
409
410 SmallVector<ISD::InputArg, 8> Ins;
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000411 subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000412
413 SmallVector<CCValAssign, 16> ArgLocs;
414 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
415 F.getContext());
416
Petar Jovanovic226e6112018-07-03 09:31:48 +0000417 const MipsTargetMachine &TM =
418 static_cast<const MipsTargetMachine &>(MF.getTarget());
419 const MipsABIInfo &ABI = TM.getABI();
420 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
421 1);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000422 CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000423 setLocInfo(ArgLocs, Ins);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000424
Petar Jovanovic667e2132018-04-12 17:01:46 +0000425 IncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
Petar Jovanovic366857a2018-04-11 15:12:32 +0000426 if (!Handler.handle(ArgLocs, ArgInfos))
427 return false;
428
429 return true;
430}
431
Petar Jovanovic326ec322018-06-06 07:24:52 +0000432bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
433 CallingConv::ID CallConv,
434 const MachineOperand &Callee,
435 const ArgInfo &OrigRet,
436 ArrayRef<ArgInfo> OrigArgs) const {
437
438 if (CallConv != CallingConv::C)
439 return false;
440
441 for (auto &Arg : OrigArgs) {
442 if (!isSupportedType(Arg.Ty))
443 return false;
444 if (Arg.Flags.isByVal() || Arg.Flags.isSRet())
445 return false;
446 }
447 if (OrigRet.Reg && !isSupportedType(OrigRet.Ty))
448 return false;
449
450 MachineFunction &MF = MIRBuilder.getMF();
451 const Function &F = MF.getFunction();
452 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
453 const MipsTargetMachine &TM =
454 static_cast<const MipsTargetMachine &>(MF.getTarget());
455 const MipsABIInfo &ABI = TM.getABI();
456
457 MachineInstrBuilder CallSeqStart =
458 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
459
460 // FIXME: Add support for pic calling sequences, long call sequences for O32,
461 // N32 and N64. First handle the case when Callee.isReg().
462 if (Callee.isReg())
463 return false;
464
465 MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(Mips::JAL);
466 MIB.addDef(Mips::SP, RegState::Implicit);
467 MIB.add(Callee);
468 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
469 MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
470
471 TargetLowering::ArgListTy FuncOrigArgs;
472 FuncOrigArgs.reserve(OrigArgs.size());
473
474 SmallVector<ArgInfo, 8> ArgInfos;
475 SmallVector<unsigned, 8> OrigArgIndices;
476 unsigned i = 0;
477 for (auto &Arg : OrigArgs) {
478
479 TargetLowering::ArgListEntry Entry;
480 Entry.Ty = Arg.Ty;
481 FuncOrigArgs.push_back(Entry);
482
483 splitToValueTypes(Arg, i, ArgInfos, OrigArgIndices);
484 ++i;
485 }
486
487 SmallVector<ISD::OutputArg, 8> Outs;
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000488 subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000489
490 SmallVector<CCValAssign, 8> ArgLocs;
491 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
492 F.getContext());
493
Petar Jovanovic226e6112018-07-03 09:31:48 +0000494 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000495 const char *Call = Callee.isSymbol() ? Callee.getSymbolName() : nullptr;
496 CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000497 setLocInfo(ArgLocs, Outs);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000498
499 OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
500 if (!RetHandler.handle(ArgLocs, ArgInfos)) {
501 return false;
502 }
503
Petar Jovanovic226e6112018-07-03 09:31:48 +0000504 unsigned NextStackOffset = CCInfo.getNextStackOffset();
505 const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
506 unsigned StackAlignment = TFL->getStackAlignment();
507 NextStackOffset = alignTo(NextStackOffset, StackAlignment);
508 CallSeqStart.addImm(NextStackOffset).addImm(0);
509
Petar Jovanovic326ec322018-06-06 07:24:52 +0000510 MIRBuilder.insertInstr(MIB);
511
512 if (OrigRet.Reg) {
513
514 ArgInfos.clear();
515 SmallVector<unsigned, 8> OrigRetIndices;
516
517 splitToValueTypes(OrigRet, 0, ArgInfos, OrigRetIndices);
518
519 SmallVector<ISD::InputArg, 8> Ins;
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000520 subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000521
522 SmallVector<CCValAssign, 8> ArgLocs;
523 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
524 F.getContext());
525
526 CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), OrigRet.Ty, Call);
Petar Jovanovic65d463b2018-08-23 20:41:09 +0000527 setLocInfo(ArgLocs, Ins);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000528
529 CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB);
530 if (!Handler.handle(ArgLocs, ArgInfos))
531 return false;
532 }
533
Petar Jovanovic226e6112018-07-03 09:31:48 +0000534 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0);
Petar Jovanovic326ec322018-06-06 07:24:52 +0000535
536 return true;
537}
538
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000539template <typename T>
Petar Jovanovic366857a2018-04-11 15:12:32 +0000540void MipsCallLowering::subTargetRegTypeForCallingConv(
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000541 const Function &F, ArrayRef<ArgInfo> Args,
542 ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
Petar Jovanovic366857a2018-04-11 15:12:32 +0000543 const DataLayout &DL = F.getParent()->getDataLayout();
544 const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
545
546 unsigned ArgNo = 0;
547 for (auto &Arg : Args) {
548
549 EVT VT = TLI.getValueType(DL, Arg.Ty);
Matt Arsenault81920b02018-07-28 13:25:19 +0000550 MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
551 F.getCallingConv(), VT);
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000552 unsigned NumRegs = TLI.getNumRegistersForCallingConv(
553 F.getContext(), F.getCallingConv(), VT);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000554
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000555 for (unsigned i = 0; i < NumRegs; ++i) {
556 ISD::ArgFlagsTy Flags = Arg.Flags;
Petar Jovanovic366857a2018-04-11 15:12:32 +0000557
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000558 if (i == 0)
559 Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
560 else
561 Flags.setOrigAlign(1);
Petar Jovanovic366857a2018-04-11 15:12:32 +0000562
Petar Jovanovicff1bc622018-09-28 13:28:47 +0000563 ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
564 0);
565 }
Petar Jovanovic366857a2018-04-11 15:12:32 +0000566 ++ArgNo;
567 }
568}
569
570void MipsCallLowering::splitToValueTypes(
571 const ArgInfo &OrigArg, unsigned OriginalIndex,
572 SmallVectorImpl<ArgInfo> &SplitArgs,
573 SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const {
574
575 // TODO : perform structure and array split. For now we only deal with
576 // types that pass isSupportedType check.
577 SplitArgs.push_back(OrigArg);
578 SplitArgsOrigIndices.push_back(OriginalIndex);
Petar Jovanovicfac93e22018-02-23 11:06:40 +0000579}