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