Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Mips/MipsCallLowering.cpp
35269 views
1
//===- MipsCallLowering.cpp -------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
/// \file
10
/// This file implements the lowering of LLVM calls to machine code calls for
11
/// GlobalISel.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "MipsCallLowering.h"
16
#include "MipsCCState.h"
17
#include "MipsMachineFunction.h"
18
#include "MipsTargetMachine.h"
19
#include "llvm/CodeGen/Analysis.h"
20
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
21
#include "llvm/CodeGen/MachineFrameInfo.h"
22
23
using namespace llvm;
24
25
MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI)
26
: CallLowering(&TLI) {}
27
28
namespace {
29
struct MipsOutgoingValueAssigner : public CallLowering::OutgoingValueAssigner {
30
/// This is the name of the function being called
31
/// FIXME: Relying on this is unsound
32
const char *Func = nullptr;
33
34
/// Is this a return value, or an outgoing call operand.
35
bool IsReturn;
36
37
MipsOutgoingValueAssigner(CCAssignFn *AssignFn_, const char *Func,
38
bool IsReturn)
39
: OutgoingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {}
40
41
bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
42
CCValAssign::LocInfo LocInfo,
43
const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
44
CCState &State_) override {
45
MipsCCState &State = static_cast<MipsCCState &>(State_);
46
47
if (IsReturn)
48
State.PreAnalyzeReturnValue(EVT::getEVT(Info.Ty));
49
else
50
State.PreAnalyzeCallOperand(Info.Ty, Info.IsFixed, Func);
51
52
return CallLowering::OutgoingValueAssigner::assignArg(
53
ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State);
54
}
55
};
56
57
struct MipsIncomingValueAssigner : public CallLowering::IncomingValueAssigner {
58
/// This is the name of the function being called
59
/// FIXME: Relying on this is unsound
60
const char *Func = nullptr;
61
62
/// Is this a call return value, or an incoming function argument.
63
bool IsReturn;
64
65
MipsIncomingValueAssigner(CCAssignFn *AssignFn_, const char *Func,
66
bool IsReturn)
67
: IncomingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {}
68
69
bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
70
CCValAssign::LocInfo LocInfo,
71
const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
72
CCState &State_) override {
73
MipsCCState &State = static_cast<MipsCCState &>(State_);
74
75
if (IsReturn)
76
State.PreAnalyzeCallResult(Info.Ty, Func);
77
else
78
State.PreAnalyzeFormalArgument(Info.Ty, Flags);
79
80
return CallLowering::IncomingValueAssigner::assignArg(
81
ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State);
82
}
83
};
84
85
class MipsIncomingValueHandler : public CallLowering::IncomingValueHandler {
86
const MipsSubtarget &STI;
87
88
public:
89
MipsIncomingValueHandler(MachineIRBuilder &MIRBuilder,
90
MachineRegisterInfo &MRI)
91
: IncomingValueHandler(MIRBuilder, MRI),
92
STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()) {}
93
94
private:
95
void assignValueToReg(Register ValVReg, Register PhysReg,
96
const CCValAssign &VA) override;
97
98
Register getStackAddress(uint64_t Size, int64_t Offset,
99
MachinePointerInfo &MPO,
100
ISD::ArgFlagsTy Flags) override;
101
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
102
const MachinePointerInfo &MPO,
103
const CCValAssign &VA) override;
104
105
unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
106
ArrayRef<CCValAssign> VAs,
107
std::function<void()> *Thunk = nullptr) override;
108
109
virtual void markPhysRegUsed(unsigned PhysReg) {
110
MIRBuilder.getMRI()->addLiveIn(PhysReg);
111
MIRBuilder.getMBB().addLiveIn(PhysReg);
112
}
113
};
114
115
class CallReturnHandler : public MipsIncomingValueHandler {
116
public:
117
CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
118
MachineInstrBuilder &MIB)
119
: MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
120
121
private:
122
void markPhysRegUsed(unsigned PhysReg) override {
123
MIB.addDef(PhysReg, RegState::Implicit);
124
}
125
126
MachineInstrBuilder &MIB;
127
};
128
129
} // end anonymous namespace
130
131
void MipsIncomingValueHandler::assignValueToReg(Register ValVReg,
132
Register PhysReg,
133
const CCValAssign &VA) {
134
markPhysRegUsed(PhysReg);
135
IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
136
}
137
138
Register MipsIncomingValueHandler::getStackAddress(uint64_t Size,
139
int64_t Offset,
140
MachinePointerInfo &MPO,
141
ISD::ArgFlagsTy Flags) {
142
143
MachineFunction &MF = MIRBuilder.getMF();
144
MachineFrameInfo &MFI = MF.getFrameInfo();
145
146
// FIXME: This should only be immutable for non-byval memory arguments.
147
int FI = MFI.CreateFixedObject(Size, Offset, true);
148
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
149
150
return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0);
151
}
152
153
void MipsIncomingValueHandler::assignValueToAddress(
154
Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
155
const CCValAssign &VA) {
156
MachineFunction &MF = MIRBuilder.getMF();
157
auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
158
inferAlignFromPtrInfo(MF, MPO));
159
MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
160
}
161
162
/// Handle cases when f64 is split into 2 32-bit GPRs. This is a custom
163
/// assignment because generic code assumes getNumRegistersForCallingConv is
164
/// accurate. In this case it is not because the type/number are context
165
/// dependent on other arguments.
166
unsigned
167
MipsIncomingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
168
ArrayRef<CCValAssign> VAs,
169
std::function<void()> *Thunk) {
170
const CCValAssign &VALo = VAs[0];
171
const CCValAssign &VAHi = VAs[1];
172
173
assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
174
VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
175
"unexpected custom value");
176
177
auto CopyLo = MIRBuilder.buildCopy(LLT::scalar(32), VALo.getLocReg());
178
auto CopyHi = MIRBuilder.buildCopy(LLT::scalar(32), VAHi.getLocReg());
179
if (!STI.isLittle())
180
std::swap(CopyLo, CopyHi);
181
182
Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
183
Arg.Regs = { CopyLo.getReg(0), CopyHi.getReg(0) };
184
MIRBuilder.buildMergeLikeInstr(Arg.OrigRegs[0], {CopyLo, CopyHi});
185
186
markPhysRegUsed(VALo.getLocReg());
187
markPhysRegUsed(VAHi.getLocReg());
188
return 2;
189
}
190
191
namespace {
192
class MipsOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
193
const MipsSubtarget &STI;
194
195
public:
196
MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
197
MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)
198
: OutgoingValueHandler(MIRBuilder, MRI),
199
STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()), MIB(MIB) {}
200
201
private:
202
void assignValueToReg(Register ValVReg, Register PhysReg,
203
const CCValAssign &VA) override;
204
205
Register getStackAddress(uint64_t Size, int64_t Offset,
206
MachinePointerInfo &MPO,
207
ISD::ArgFlagsTy Flags) override;
208
209
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
210
const MachinePointerInfo &MPO,
211
const CCValAssign &VA) override;
212
unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
213
ArrayRef<CCValAssign> VAs,
214
std::function<void()> *Thunk) override;
215
216
MachineInstrBuilder &MIB;
217
};
218
} // end anonymous namespace
219
220
void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg,
221
Register PhysReg,
222
const CCValAssign &VA) {
223
Register ExtReg = extendRegister(ValVReg, VA);
224
MIRBuilder.buildCopy(PhysReg, ExtReg);
225
MIB.addUse(PhysReg, RegState::Implicit);
226
}
227
228
Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size,
229
int64_t Offset,
230
MachinePointerInfo &MPO,
231
ISD::ArgFlagsTy Flags) {
232
MachineFunction &MF = MIRBuilder.getMF();
233
MPO = MachinePointerInfo::getStack(MF, Offset);
234
235
LLT p0 = LLT::pointer(0, 32);
236
LLT s32 = LLT::scalar(32);
237
auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP));
238
239
auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);
240
auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
241
return AddrReg.getReg(0);
242
}
243
244
void MipsOutgoingValueHandler::assignValueToAddress(
245
Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
246
const CCValAssign &VA) {
247
MachineFunction &MF = MIRBuilder.getMF();
248
uint64_t LocMemOffset = VA.getLocMemOffset();
249
250
auto MMO = MF.getMachineMemOperand(
251
MPO, MachineMemOperand::MOStore, MemTy,
252
commonAlignment(STI.getStackAlignment(), LocMemOffset));
253
254
Register ExtReg = extendRegister(ValVReg, VA);
255
MIRBuilder.buildStore(ExtReg, Addr, *MMO);
256
}
257
258
unsigned
259
MipsOutgoingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
260
ArrayRef<CCValAssign> VAs,
261
std::function<void()> *Thunk) {
262
const CCValAssign &VALo = VAs[0];
263
const CCValAssign &VAHi = VAs[1];
264
265
assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
266
VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
267
"unexpected custom value");
268
269
auto Unmerge =
270
MIRBuilder.buildUnmerge({LLT::scalar(32), LLT::scalar(32)}, Arg.Regs[0]);
271
Register Lo = Unmerge.getReg(0);
272
Register Hi = Unmerge.getReg(1);
273
274
Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
275
Arg.Regs = { Lo, Hi };
276
if (!STI.isLittle())
277
std::swap(Lo, Hi);
278
279
// If we can return a thunk, just include the register copies. The unmerge can
280
// be emitted earlier.
281
if (Thunk) {
282
*Thunk = [=]() {
283
MIRBuilder.buildCopy(VALo.getLocReg(), Lo);
284
MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);
285
};
286
return 2;
287
}
288
MIRBuilder.buildCopy(VALo.getLocReg(), Lo);
289
MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);
290
return 2;
291
}
292
293
static bool isSupportedArgumentType(Type *T) {
294
if (T->isIntegerTy())
295
return true;
296
if (T->isPointerTy())
297
return true;
298
if (T->isFloatingPointTy())
299
return true;
300
return false;
301
}
302
303
static bool isSupportedReturnType(Type *T) {
304
if (T->isIntegerTy())
305
return true;
306
if (T->isPointerTy())
307
return true;
308
if (T->isFloatingPointTy())
309
return true;
310
if (T->isAggregateType())
311
return true;
312
return false;
313
}
314
315
bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
316
const Value *Val, ArrayRef<Register> VRegs,
317
FunctionLoweringInfo &FLI) const {
318
319
MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
320
321
if (Val != nullptr && !isSupportedReturnType(Val->getType()))
322
return false;
323
324
if (!VRegs.empty()) {
325
MachineFunction &MF = MIRBuilder.getMF();
326
const Function &F = MF.getFunction();
327
const DataLayout &DL = MF.getDataLayout();
328
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
329
330
SmallVector<ArgInfo, 8> RetInfos;
331
332
ArgInfo ArgRetInfo(VRegs, *Val, 0);
333
setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);
334
splitToValueTypes(ArgRetInfo, RetInfos, DL, F.getCallingConv());
335
336
SmallVector<CCValAssign, 16> ArgLocs;
337
SmallVector<ISD::OutputArg, 8> Outs;
338
339
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
340
F.getContext());
341
342
MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
343
std::string FuncName = F.getName().str();
344
MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForReturn(),
345
FuncName.c_str(), /*IsReturn*/ true);
346
347
if (!determineAssignments(Assigner, RetInfos, CCInfo))
348
return false;
349
350
if (!handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder))
351
return false;
352
}
353
354
MIRBuilder.insertInstr(Ret);
355
return true;
356
}
357
358
bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
359
const Function &F,
360
ArrayRef<ArrayRef<Register>> VRegs,
361
FunctionLoweringInfo &FLI) const {
362
363
// Quick exit if there aren't any args.
364
if (F.arg_empty())
365
return true;
366
367
for (auto &Arg : F.args()) {
368
if (!isSupportedArgumentType(Arg.getType()))
369
return false;
370
}
371
372
MachineFunction &MF = MIRBuilder.getMF();
373
const DataLayout &DL = MF.getDataLayout();
374
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
375
376
SmallVector<ArgInfo, 8> ArgInfos;
377
unsigned i = 0;
378
for (auto &Arg : F.args()) {
379
ArgInfo AInfo(VRegs[i], Arg, i);
380
setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
381
382
splitToValueTypes(AInfo, ArgInfos, DL, F.getCallingConv());
383
++i;
384
}
385
386
SmallVector<ISD::InputArg, 8> Ins;
387
388
SmallVector<CCValAssign, 16> ArgLocs;
389
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
390
F.getContext());
391
392
const MipsTargetMachine &TM =
393
static_cast<const MipsTargetMachine &>(MF.getTarget());
394
const MipsABIInfo &ABI = TM.getABI();
395
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
396
Align(1));
397
398
const std::string FuncName = F.getName().str();
399
MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForCall(), FuncName.c_str(),
400
/*IsReturn*/ false);
401
if (!determineAssignments(Assigner, ArgInfos, CCInfo))
402
return false;
403
404
MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
405
if (!handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
406
return false;
407
408
if (F.isVarArg()) {
409
ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
410
unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
411
412
int VaArgOffset;
413
unsigned RegSize = 4;
414
if (ArgRegs.size() == Idx)
415
VaArgOffset = alignTo(CCInfo.getStackSize(), RegSize);
416
else {
417
VaArgOffset =
418
(int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
419
(int)(RegSize * (ArgRegs.size() - Idx));
420
}
421
422
MachineFrameInfo &MFI = MF.getFrameInfo();
423
int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
424
MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
425
426
for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
427
MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
428
LLT RegTy = LLT::scalar(RegSize * 8);
429
MachineInstrBuilder Copy =
430
MIRBuilder.buildCopy(RegTy, Register(ArgRegs[I]));
431
FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
432
MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI);
433
434
const LLT PtrTy = LLT::pointer(MPO.getAddrSpace(), 32);
435
auto FrameIndex = MIRBuilder.buildFrameIndex(PtrTy, FI);
436
MachineMemOperand *MMO = MF.getMachineMemOperand(
437
MPO, MachineMemOperand::MOStore, RegTy, Align(RegSize));
438
MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
439
}
440
}
441
442
return true;
443
}
444
445
bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
446
CallLoweringInfo &Info) const {
447
448
if (Info.CallConv != CallingConv::C)
449
return false;
450
451
for (auto &Arg : Info.OrigArgs) {
452
if (!isSupportedArgumentType(Arg.Ty))
453
return false;
454
if (Arg.Flags[0].isByVal())
455
return false;
456
if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy())
457
return false;
458
}
459
460
if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty))
461
return false;
462
463
MachineFunction &MF = MIRBuilder.getMF();
464
const Function &F = MF.getFunction();
465
const DataLayout &DL = MF.getDataLayout();
466
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
467
const MipsTargetMachine &TM =
468
static_cast<const MipsTargetMachine &>(MF.getTarget());
469
const MipsABIInfo &ABI = TM.getABI();
470
471
MachineInstrBuilder CallSeqStart =
472
MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
473
474
const bool IsCalleeGlobalPIC =
475
Info.Callee.isGlobal() && TM.isPositionIndependent();
476
477
MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(
478
Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL);
479
MIB.addDef(Mips::SP, RegState::Implicit);
480
if (IsCalleeGlobalPIC) {
481
Register CalleeReg =
482
MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32));
483
MachineInstr *CalleeGlobalValue =
484
MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal());
485
if (!Info.Callee.getGlobal()->hasLocalLinkage())
486
CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL);
487
MIB.addUse(CalleeReg);
488
} else
489
MIB.add(Info.Callee);
490
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
491
MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
492
493
TargetLowering::ArgListTy FuncOrigArgs;
494
FuncOrigArgs.reserve(Info.OrigArgs.size());
495
496
SmallVector<ArgInfo, 8> ArgInfos;
497
for (auto &Arg : Info.OrigArgs)
498
splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
499
500
SmallVector<CCValAssign, 8> ArgLocs;
501
bool IsCalleeVarArg = false;
502
if (Info.Callee.isGlobal()) {
503
const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
504
IsCalleeVarArg = CF->isVarArg();
505
}
506
507
// FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it
508
// depends on looking directly at the call target.
509
MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs,
510
F.getContext());
511
512
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv),
513
Align(1));
514
515
const char *Call =
516
Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr;
517
518
MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForCall(), Call,
519
/*IsReturn*/ false);
520
if (!determineAssignments(Assigner, ArgInfos, CCInfo))
521
return false;
522
523
MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB);
524
if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
525
return false;
526
527
unsigned StackSize = CCInfo.getStackSize();
528
unsigned StackAlignment = F.getParent()->getOverrideStackAlignment();
529
if (!StackAlignment) {
530
const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
531
StackAlignment = TFL->getStackAlignment();
532
}
533
StackSize = alignTo(StackSize, StackAlignment);
534
CallSeqStart.addImm(StackSize).addImm(0);
535
536
if (IsCalleeGlobalPIC) {
537
MIRBuilder.buildCopy(
538
Register(Mips::GP),
539
MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel(MF));
540
MIB.addDef(Mips::GP, RegState::Implicit);
541
}
542
MIRBuilder.insertInstr(MIB);
543
if (MIB->getOpcode() == Mips::JALRPseudo) {
544
const MipsSubtarget &STI = MIRBuilder.getMF().getSubtarget<MipsSubtarget>();
545
MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
546
*STI.getRegBankInfo());
547
}
548
549
if (!Info.OrigRet.Ty->isVoidTy()) {
550
ArgInfos.clear();
551
552
CallLowering::splitToValueTypes(Info.OrigRet, ArgInfos, DL,
553
F.getCallingConv());
554
555
const std::string FuncName = F.getName().str();
556
SmallVector<ISD::InputArg, 8> Ins;
557
SmallVector<CCValAssign, 8> ArgLocs;
558
MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForReturn(),
559
FuncName.c_str(),
560
/*IsReturn*/ true);
561
CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
562
563
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
564
F.getContext());
565
566
if (!determineAssignments(Assigner, ArgInfos, CCInfo))
567
return false;
568
569
if (!handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
570
return false;
571
}
572
573
MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(StackSize).addImm(0);
574
575
return true;
576
}
577
578