summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsCallLowering.cpp
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-23 08:11:41 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-23 08:11:41 +0000
commitc063b0b0d3346d2a50e2ef28ec0147d6d53f399d (patch)
tree2a4206617dc800788ca4c826037ce7a2e8a0b9e4 /llvm/lib/Target/Mips/MipsCallLowering.cpp
parent0e490ae0a93c8b6ec48366ac7d46da442542b902 (diff)
downloadbcm5719-llvm-c063b0b0d3346d2a50e2ef28ec0147d6d53f399d.tar.gz
bcm5719-llvm-c063b0b0d3346d2a50e2ef28ec0147d6d53f399d.zip
[MIPS GlobalISel] VarArg argument lowering, select G_VASTART and vacopy
CC_Mips doesn't accept vararg functions for O32, so we have to explicitly use CC_Mips_FixedArg. For lowerCall we now properly figure out whether callee function is vararg or not, this has no effect for O32 since we always use CC_Mips_FixedArg. For lower formal arguments we need to copy arguments in register to stack and save pointer to start for argument list into MipsMachineFunction object so that G_VASTART could use it during instruction select. For vacopy we need to copy content from one vreg to another, load and store are used for that purpose. Differential Revision: https://reviews.llvm.org/D67756 llvm-svn: 372555
Diffstat (limited to 'llvm/lib/Target/Mips/MipsCallLowering.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp45
1 files changed, 40 insertions, 5 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index aac29967f59..646c4785458 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -454,10 +454,6 @@ bool MipsCallLowering::lowerFormalArguments(
if (F.arg_empty())
return true;
- if (F.isVarArg()) {
- return false;
- }
-
for (auto &Arg : F.args()) {
if (!isSupportedType(Arg.getType()))
return false;
@@ -496,6 +492,40 @@ bool MipsCallLowering::lowerFormalArguments(
if (!Handler.handle(ArgLocs, ArgInfos))
return false;
+ if (F.isVarArg()) {
+ ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
+ unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
+
+ int VaArgOffset;
+ unsigned RegSize = 4;
+ if (ArgRegs.size() == Idx)
+ VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize);
+ else {
+ VaArgOffset =
+ (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
+ (int)(RegSize * (ArgRegs.size() - Idx));
+ }
+
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
+ MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
+
+ for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
+ MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
+
+ MachineInstrBuilder Copy =
+ MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I]));
+ FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
+ MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI);
+ MachineInstrBuilder FrameIndex =
+ MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI);
+ MachineMemOperand *MMO =
+ MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, RegSize,
+ /* Alignment */ RegSize);
+ MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
+ }
+ }
+
return true;
}
@@ -566,7 +596,12 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
SmallVector<CCValAssign, 8> ArgLocs;
- MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
+ bool IsCalleeVarArg = false;
+ if (Info.Callee.isGlobal()) {
+ const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
+ IsCalleeVarArg = CF->isVarArg();
+ }
+ MipsCCState CCInfo(F.getCallingConv(), IsCalleeVarArg, MF, ArgLocs,
F.getContext());
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), 1);
OpenPOWER on IntegriCloud