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