xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1e8d8bef9SDimitry Andric //===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
2e8d8bef9SDimitry Andric //
3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric ///
9e8d8bef9SDimitry Andric /// \file
10e8d8bef9SDimitry Andric /// This file implements the lowering of LLVM calls to machine code calls for
11e8d8bef9SDimitry Andric /// GlobalISel.
12e8d8bef9SDimitry Andric ///
13e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
14e8d8bef9SDimitry Andric 
15e8d8bef9SDimitry Andric #include "PPCCallLowering.h"
16fe6060f1SDimitry Andric #include "PPCISelLowering.h"
17fe6060f1SDimitry Andric #include "PPCSubtarget.h"
18fe6060f1SDimitry Andric #include "PPCTargetMachine.h"
19fe6060f1SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
20fe6060f1SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h"
21e8d8bef9SDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
23fe6060f1SDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h"
24e8d8bef9SDimitry Andric #include "llvm/Support/Debug.h"
25e8d8bef9SDimitry Andric 
26e8d8bef9SDimitry Andric #define DEBUG_TYPE "ppc-call-lowering"
27e8d8bef9SDimitry Andric 
28e8d8bef9SDimitry Andric using namespace llvm;
29e8d8bef9SDimitry Andric 
30e8d8bef9SDimitry Andric PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
31e8d8bef9SDimitry Andric     : CallLowering(&TLI) {}
32e8d8bef9SDimitry Andric 
33e8d8bef9SDimitry Andric bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
34e8d8bef9SDimitry Andric                                   const Value *Val, ArrayRef<Register> VRegs,
35e8d8bef9SDimitry Andric                                   FunctionLoweringInfo &FLI,
36e8d8bef9SDimitry Andric                                   Register SwiftErrorVReg) const {
37e8d8bef9SDimitry Andric   assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
38e8d8bef9SDimitry Andric          "Return value without a vreg");
39e8d8bef9SDimitry Andric   if (VRegs.size() > 0)
40e8d8bef9SDimitry Andric     return false;
41e8d8bef9SDimitry Andric 
42e8d8bef9SDimitry Andric   MIRBuilder.buildInstr(PPC::BLR8);
43e8d8bef9SDimitry Andric   return true;
44e8d8bef9SDimitry Andric }
45e8d8bef9SDimitry Andric 
46fe6060f1SDimitry Andric bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
47fe6060f1SDimitry Andric                                 CallLoweringInfo &Info) const {
48fe6060f1SDimitry Andric   return false;
49fe6060f1SDimitry Andric }
50fe6060f1SDimitry Andric 
51e8d8bef9SDimitry Andric bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
52e8d8bef9SDimitry Andric                                            const Function &F,
53e8d8bef9SDimitry Andric                                            ArrayRef<ArrayRef<Register>> VRegs,
54e8d8bef9SDimitry Andric                                            FunctionLoweringInfo &FLI) const {
55fe6060f1SDimitry Andric   MachineFunction &MF = MIRBuilder.getMF();
56fe6060f1SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
57fe6060f1SDimitry Andric   const auto &DL = F.getParent()->getDataLayout();
58fe6060f1SDimitry Andric   auto &TLI = *getTLI<PPCTargetLowering>();
59e8d8bef9SDimitry Andric 
60fe6060f1SDimitry Andric   // Loop over each arg, set flags and split to single value types
61fe6060f1SDimitry Andric   SmallVector<ArgInfo, 8> SplitArgs;
62fe6060f1SDimitry Andric   unsigned I = 0;
63fe6060f1SDimitry Andric   for (const auto &Arg : F.args()) {
64fe6060f1SDimitry Andric     if (DL.getTypeStoreSize(Arg.getType()).isZero())
65fe6060f1SDimitry Andric       continue;
66fe6060f1SDimitry Andric 
67fe6060f1SDimitry Andric     ArgInfo OrigArg{VRegs[I], Arg, I};
68fe6060f1SDimitry Andric     setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
69fe6060f1SDimitry Andric     splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
70fe6060f1SDimitry Andric     ++I;
71e8d8bef9SDimitry Andric   }
72e8d8bef9SDimitry Andric 
73fe6060f1SDimitry Andric   CCAssignFn *AssignFn =
74fe6060f1SDimitry Andric       TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg());
75fe6060f1SDimitry Andric   IncomingValueAssigner ArgAssigner(AssignFn);
76fe6060f1SDimitry Andric   FormalArgHandler ArgHandler(MIRBuilder, MRI);
77fe6060f1SDimitry Andric   return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
78fe6060f1SDimitry Andric                                        MIRBuilder, F.getCallingConv(),
79fe6060f1SDimitry Andric                                        F.isVarArg());
80fe6060f1SDimitry Andric }
81fe6060f1SDimitry Andric 
82fe6060f1SDimitry Andric void PPCIncomingValueHandler::assignValueToReg(Register ValVReg,
83fe6060f1SDimitry Andric                                                Register PhysReg,
84349cc55cSDimitry Andric                                                CCValAssign VA) {
85fe6060f1SDimitry Andric   markPhysRegUsed(PhysReg);
86fe6060f1SDimitry Andric   IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
87fe6060f1SDimitry Andric }
88fe6060f1SDimitry Andric 
89fe6060f1SDimitry Andric void PPCIncomingValueHandler::assignValueToAddress(Register ValVReg,
90fe6060f1SDimitry Andric                                                    Register Addr, LLT MemTy,
91fe6060f1SDimitry Andric                                                    MachinePointerInfo &MPO,
92fe6060f1SDimitry Andric                                                    CCValAssign &VA) {
93fe6060f1SDimitry Andric   // define a lambda expression to load value
94fe6060f1SDimitry Andric   auto BuildLoad = [](MachineIRBuilder &MIRBuilder, MachinePointerInfo &MPO,
95fe6060f1SDimitry Andric                       LLT MemTy, const DstOp &Res, Register Addr) {
96fe6060f1SDimitry Andric     MachineFunction &MF = MIRBuilder.getMF();
97fe6060f1SDimitry Andric     auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
98fe6060f1SDimitry Andric                                         inferAlignFromPtrInfo(MF, MPO));
99fe6060f1SDimitry Andric     return MIRBuilder.buildLoad(Res, Addr, *MMO);
100fe6060f1SDimitry Andric   };
101fe6060f1SDimitry Andric 
102fe6060f1SDimitry Andric   BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr);
103fe6060f1SDimitry Andric }
104fe6060f1SDimitry Andric 
105fe6060f1SDimitry Andric Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
106fe6060f1SDimitry Andric                                                   MachinePointerInfo &MPO,
107fe6060f1SDimitry Andric                                                   ISD::ArgFlagsTy Flags) {
108fe6060f1SDimitry Andric   auto &MFI = MIRBuilder.getMF().getFrameInfo();
109fe6060f1SDimitry Andric   const bool IsImmutable = !Flags.isByVal();
110fe6060f1SDimitry Andric   int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
111fe6060f1SDimitry Andric   MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
112fe6060f1SDimitry Andric 
113fe6060f1SDimitry Andric   // Build Frame Index based on whether the machine is 32-bit or 64-bit
114fe6060f1SDimitry Andric   llvm::LLT FramePtr = LLT::pointer(
115fe6060f1SDimitry Andric       0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());
116fe6060f1SDimitry Andric   MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);
117fe6060f1SDimitry Andric   StackUsed = std::max(StackUsed, Size + Offset);
118fe6060f1SDimitry Andric   return AddrReg.getReg(0);
119fe6060f1SDimitry Andric }
120fe6060f1SDimitry Andric 
121fe6060f1SDimitry Andric void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) {
122fe6060f1SDimitry Andric   MIRBuilder.getMRI()->addLiveIn(PhysReg);
123fe6060f1SDimitry Andric   MIRBuilder.getMBB().addLiveIn(PhysReg);
124e8d8bef9SDimitry Andric }
125