xref: /llvm-project/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp (revision f71cb9dbb739bb58ce7e52e49fe384ff2ff11687)
1009cd4e4SKit Barton //===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
2009cd4e4SKit Barton //
3009cd4e4SKit Barton // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4009cd4e4SKit Barton // See https://llvm.org/LICENSE.txt for license information.
5009cd4e4SKit Barton // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009cd4e4SKit Barton //
7009cd4e4SKit Barton //===----------------------------------------------------------------------===//
8009cd4e4SKit Barton ///
9009cd4e4SKit Barton /// \file
10009cd4e4SKit Barton /// This file implements the lowering of LLVM calls to machine code calls for
11009cd4e4SKit Barton /// GlobalISel.
12009cd4e4SKit Barton ///
13009cd4e4SKit Barton //===----------------------------------------------------------------------===//
14009cd4e4SKit Barton 
15009cd4e4SKit Barton #include "PPCCallLowering.h"
16be4a1dfbSKai Nacke #include "PPCCallingConv.h"
171c5ff0b0SAnshil Gandhi #include "PPCISelLowering.h"
181c5ff0b0SAnshil Gandhi #include "llvm/CodeGen/CallingConvLower.h"
191c5ff0b0SAnshil Gandhi #include "llvm/CodeGen/GlobalISel/CallLowering.h"
20009cd4e4SKit Barton #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
21989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFrameInfo.h"
221c5ff0b0SAnshil Gandhi #include "llvm/CodeGen/TargetCallingConv.h"
23009cd4e4SKit Barton 
24009cd4e4SKit Barton #define DEBUG_TYPE "ppc-call-lowering"
25009cd4e4SKit Barton 
26009cd4e4SKit Barton using namespace llvm;
27009cd4e4SKit Barton 
28be4a1dfbSKai Nacke namespace {
29be4a1dfbSKai Nacke 
30be4a1dfbSKai Nacke struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
31be4a1dfbSKai Nacke   OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
32be4a1dfbSKai Nacke                      MachineInstrBuilder MIB)
33be4a1dfbSKai Nacke       : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
34be4a1dfbSKai Nacke 
35be4a1dfbSKai Nacke   void assignValueToReg(Register ValVReg, Register PhysReg,
362f4328e6SCraig Topper                         const CCValAssign &VA) override;
37be4a1dfbSKai Nacke   void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
389f592cbcSCraig Topper                             const MachinePointerInfo &MPO,
399f592cbcSCraig Topper                             const CCValAssign &VA) override;
40be4a1dfbSKai Nacke   Register getStackAddress(uint64_t Size, int64_t Offset,
41be4a1dfbSKai Nacke                            MachinePointerInfo &MPO,
42be4a1dfbSKai Nacke                            ISD::ArgFlagsTy Flags) override;
43be4a1dfbSKai Nacke 
44be4a1dfbSKai Nacke   MachineInstrBuilder MIB;
45be4a1dfbSKai Nacke };
46be4a1dfbSKai Nacke } // namespace
47be4a1dfbSKai Nacke 
48be4a1dfbSKai Nacke void OutgoingArgHandler::assignValueToReg(Register ValVReg, Register PhysReg,
492f4328e6SCraig Topper                                           const CCValAssign &VA) {
50be4a1dfbSKai Nacke   MIB.addUse(PhysReg, RegState::Implicit);
51be4a1dfbSKai Nacke   Register ExtReg = extendRegister(ValVReg, VA);
52be4a1dfbSKai Nacke   MIRBuilder.buildCopy(PhysReg, ExtReg);
53be4a1dfbSKai Nacke }
54be4a1dfbSKai Nacke 
55be4a1dfbSKai Nacke void OutgoingArgHandler::assignValueToAddress(Register ValVReg, Register Addr,
56be4a1dfbSKai Nacke                                               LLT MemTy,
579f592cbcSCraig Topper                                               const MachinePointerInfo &MPO,
589f592cbcSCraig Topper                                               const CCValAssign &VA) {
59be4a1dfbSKai Nacke   llvm_unreachable("unimplemented");
60be4a1dfbSKai Nacke }
61be4a1dfbSKai Nacke 
62be4a1dfbSKai Nacke Register OutgoingArgHandler::getStackAddress(uint64_t Size, int64_t Offset,
63be4a1dfbSKai Nacke                                              MachinePointerInfo &MPO,
64be4a1dfbSKai Nacke                                              ISD::ArgFlagsTy Flags) {
65be4a1dfbSKai Nacke   llvm_unreachable("unimplemented");
66be4a1dfbSKai Nacke }
67be4a1dfbSKai Nacke 
68009cd4e4SKit Barton PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
69009cd4e4SKit Barton     : CallLowering(&TLI) {}
70009cd4e4SKit Barton 
71009cd4e4SKit Barton bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
72009cd4e4SKit Barton                                   const Value *Val, ArrayRef<Register> VRegs,
73d68458bdSChristudasan Devadasan                                   FunctionLoweringInfo &FLI,
74009cd4e4SKit Barton                                   Register SwiftErrorVReg) const {
75be4a1dfbSKai Nacke   auto MIB = MIRBuilder.buildInstrNoInsert(PPC::BLR8);
76be4a1dfbSKai Nacke   bool Success = true;
77be4a1dfbSKai Nacke   MachineFunction &MF = MIRBuilder.getMF();
78be4a1dfbSKai Nacke   const Function &F = MF.getFunction();
79be4a1dfbSKai Nacke   MachineRegisterInfo &MRI = MF.getRegInfo();
80*9df71d76SNikita Popov   auto &DL = F.getDataLayout();
81be4a1dfbSKai Nacke   if (!VRegs.empty()) {
82be4a1dfbSKai Nacke     // Setup the information about the return value.
83be4a1dfbSKai Nacke     ArgInfo OrigArg{VRegs, Val->getType(), 0};
84be4a1dfbSKai Nacke     setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
85009cd4e4SKit Barton 
86be4a1dfbSKai Nacke     // Split the return value into consecutive registers if needed.
87be4a1dfbSKai Nacke     SmallVector<ArgInfo, 8> SplitArgs;
88be4a1dfbSKai Nacke     splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
89be4a1dfbSKai Nacke 
90be4a1dfbSKai Nacke     // Use the calling convention callback to determine type and location of
91be4a1dfbSKai Nacke     // return value.
92be4a1dfbSKai Nacke     OutgoingValueAssigner ArgAssigner(RetCC_PPC);
93be4a1dfbSKai Nacke 
94be4a1dfbSKai Nacke     // Handler to move the return value into the correct location.
95be4a1dfbSKai Nacke     OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
96be4a1dfbSKai Nacke 
97be4a1dfbSKai Nacke     // Iterate over all return values, and move them to the assigned location.
98be4a1dfbSKai Nacke     Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
99be4a1dfbSKai Nacke                                             MIRBuilder, F.getCallingConv(),
100be4a1dfbSKai Nacke                                             F.isVarArg());
101be4a1dfbSKai Nacke   }
102be4a1dfbSKai Nacke   MIRBuilder.insertInstr(MIB);
103be4a1dfbSKai Nacke   return Success;
104009cd4e4SKit Barton }
105009cd4e4SKit Barton 
1061c5ff0b0SAnshil Gandhi bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
1071c5ff0b0SAnshil Gandhi                                 CallLoweringInfo &Info) const {
1081c5ff0b0SAnshil Gandhi   return false;
1091c5ff0b0SAnshil Gandhi }
1101c5ff0b0SAnshil Gandhi 
111d68458bdSChristudasan Devadasan bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
112d68458bdSChristudasan Devadasan                                            const Function &F,
113d68458bdSChristudasan Devadasan                                            ArrayRef<ArrayRef<Register>> VRegs,
114d68458bdSChristudasan Devadasan                                            FunctionLoweringInfo &FLI) const {
1151c5ff0b0SAnshil Gandhi   MachineFunction &MF = MIRBuilder.getMF();
1161c5ff0b0SAnshil Gandhi   MachineRegisterInfo &MRI = MF.getRegInfo();
117*9df71d76SNikita Popov   const auto &DL = F.getDataLayout();
1181c5ff0b0SAnshil Gandhi   auto &TLI = *getTLI<PPCTargetLowering>();
119009cd4e4SKit Barton 
1201c5ff0b0SAnshil Gandhi   // Loop over each arg, set flags and split to single value types
1211c5ff0b0SAnshil Gandhi   SmallVector<ArgInfo, 8> SplitArgs;
1221c5ff0b0SAnshil Gandhi   unsigned I = 0;
1231c5ff0b0SAnshil Gandhi   for (const auto &Arg : F.args()) {
1241c5ff0b0SAnshil Gandhi     if (DL.getTypeStoreSize(Arg.getType()).isZero())
1251c5ff0b0SAnshil Gandhi       continue;
1261c5ff0b0SAnshil Gandhi 
1279b057f64SMatt Arsenault     ArgInfo OrigArg{VRegs[I], Arg, I};
1281c5ff0b0SAnshil Gandhi     setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
1291c5ff0b0SAnshil Gandhi     splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
1301c5ff0b0SAnshil Gandhi     ++I;
131009cd4e4SKit Barton   }
132009cd4e4SKit Barton 
1331c5ff0b0SAnshil Gandhi   CCAssignFn *AssignFn =
1341c5ff0b0SAnshil Gandhi       TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg());
1351c5ff0b0SAnshil Gandhi   IncomingValueAssigner ArgAssigner(AssignFn);
1361c5ff0b0SAnshil Gandhi   FormalArgHandler ArgHandler(MIRBuilder, MRI);
1371c5ff0b0SAnshil Gandhi   return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
1381c5ff0b0SAnshil Gandhi                                        MIRBuilder, F.getCallingConv(),
1391c5ff0b0SAnshil Gandhi                                        F.isVarArg());
1401c5ff0b0SAnshil Gandhi }
1411c5ff0b0SAnshil Gandhi 
1421c5ff0b0SAnshil Gandhi void PPCIncomingValueHandler::assignValueToReg(Register ValVReg,
1431c5ff0b0SAnshil Gandhi                                                Register PhysReg,
1442f4328e6SCraig Topper                                                const CCValAssign &VA) {
1451c5ff0b0SAnshil Gandhi   markPhysRegUsed(PhysReg);
1461c5ff0b0SAnshil Gandhi   IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
1471c5ff0b0SAnshil Gandhi }
1481c5ff0b0SAnshil Gandhi 
1499f592cbcSCraig Topper void PPCIncomingValueHandler::assignValueToAddress(
1509f592cbcSCraig Topper     Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
1519f592cbcSCraig Topper     const CCValAssign &VA) {
1521c5ff0b0SAnshil Gandhi   // define a lambda expression to load value
1539f592cbcSCraig Topper   auto BuildLoad = [](MachineIRBuilder &MIRBuilder,
1549f592cbcSCraig Topper                       const MachinePointerInfo &MPO, LLT MemTy,
1559f592cbcSCraig Topper                       const DstOp &Res, Register Addr) {
1561c5ff0b0SAnshil Gandhi     MachineFunction &MF = MIRBuilder.getMF();
15799c7e918SMatt Arsenault     auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
1581c5ff0b0SAnshil Gandhi                                         inferAlignFromPtrInfo(MF, MPO));
1591c5ff0b0SAnshil Gandhi     return MIRBuilder.buildLoad(Res, Addr, *MMO);
1601c5ff0b0SAnshil Gandhi   };
1611c5ff0b0SAnshil Gandhi 
16299c7e918SMatt Arsenault   BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr);
1631c5ff0b0SAnshil Gandhi }
1641c5ff0b0SAnshil Gandhi 
1651c5ff0b0SAnshil Gandhi Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
1661c5ff0b0SAnshil Gandhi                                                   MachinePointerInfo &MPO,
1671c5ff0b0SAnshil Gandhi                                                   ISD::ArgFlagsTy Flags) {
1681c5ff0b0SAnshil Gandhi   auto &MFI = MIRBuilder.getMF().getFrameInfo();
1691c5ff0b0SAnshil Gandhi   const bool IsImmutable = !Flags.isByVal();
1701c5ff0b0SAnshil Gandhi   int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
1711c5ff0b0SAnshil Gandhi   MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
1721c5ff0b0SAnshil Gandhi 
1731c5ff0b0SAnshil Gandhi   // Build Frame Index based on whether the machine is 32-bit or 64-bit
1741c5ff0b0SAnshil Gandhi   llvm::LLT FramePtr = LLT::pointer(
1751c5ff0b0SAnshil Gandhi       0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());
1761c5ff0b0SAnshil Gandhi   MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);
1771c5ff0b0SAnshil Gandhi   StackUsed = std::max(StackUsed, Size + Offset);
1781c5ff0b0SAnshil Gandhi   return AddrReg.getReg(0);
1791c5ff0b0SAnshil Gandhi }
1801c5ff0b0SAnshil Gandhi 
1811c5ff0b0SAnshil Gandhi void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) {
1821c5ff0b0SAnshil Gandhi   MIRBuilder.getMRI()->addLiveIn(PhysReg);
1831c5ff0b0SAnshil Gandhi   MIRBuilder.getMBB().addLiveIn(PhysReg);
184009cd4e4SKit Barton }
185