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 "PPCCallingConv.h" 17 #include "PPCISelLowering.h" 18 #include "llvm/CodeGen/CallingConvLower.h" 19 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 20 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/TargetCallingConv.h" 23 24 #define DEBUG_TYPE "ppc-call-lowering" 25 26 using namespace llvm; 27 28 namespace { 29 30 struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { 31 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 32 MachineInstrBuilder MIB) 33 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {} 34 35 void assignValueToReg(Register ValVReg, Register PhysReg, 36 const CCValAssign &VA) override; 37 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, 38 const MachinePointerInfo &MPO, 39 const CCValAssign &VA) override; 40 Register getStackAddress(uint64_t Size, int64_t Offset, 41 MachinePointerInfo &MPO, 42 ISD::ArgFlagsTy Flags) override; 43 44 MachineInstrBuilder MIB; 45 }; 46 } // namespace 47 48 void OutgoingArgHandler::assignValueToReg(Register ValVReg, Register PhysReg, 49 const CCValAssign &VA) { 50 MIB.addUse(PhysReg, RegState::Implicit); 51 Register ExtReg = extendRegister(ValVReg, VA); 52 MIRBuilder.buildCopy(PhysReg, ExtReg); 53 } 54 55 void OutgoingArgHandler::assignValueToAddress(Register ValVReg, Register Addr, 56 LLT MemTy, 57 const MachinePointerInfo &MPO, 58 const CCValAssign &VA) { 59 llvm_unreachable("unimplemented"); 60 } 61 62 Register OutgoingArgHandler::getStackAddress(uint64_t Size, int64_t Offset, 63 MachinePointerInfo &MPO, 64 ISD::ArgFlagsTy Flags) { 65 llvm_unreachable("unimplemented"); 66 } 67 68 PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI) 69 : CallLowering(&TLI) {} 70 71 bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 72 const Value *Val, ArrayRef<Register> VRegs, 73 FunctionLoweringInfo &FLI, 74 Register SwiftErrorVReg) const { 75 auto MIB = MIRBuilder.buildInstrNoInsert(PPC::BLR8); 76 bool Success = true; 77 MachineFunction &MF = MIRBuilder.getMF(); 78 const Function &F = MF.getFunction(); 79 MachineRegisterInfo &MRI = MF.getRegInfo(); 80 auto &DL = F.getDataLayout(); 81 if (!VRegs.empty()) { 82 // Setup the information about the return value. 83 ArgInfo OrigArg{VRegs, Val->getType(), 0}; 84 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 85 86 // Split the return value into consecutive registers if needed. 87 SmallVector<ArgInfo, 8> SplitArgs; 88 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 89 90 // Use the calling convention callback to determine type and location of 91 // return value. 92 OutgoingValueAssigner ArgAssigner(RetCC_PPC); 93 94 // Handler to move the return value into the correct location. 95 OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB); 96 97 // Iterate over all return values, and move them to the assigned location. 98 Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 99 MIRBuilder, F.getCallingConv(), 100 F.isVarArg()); 101 } 102 MIRBuilder.insertInstr(MIB); 103 return Success; 104 } 105 106 bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 107 CallLoweringInfo &Info) const { 108 return false; 109 } 110 111 bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 112 const Function &F, 113 ArrayRef<ArrayRef<Register>> VRegs, 114 FunctionLoweringInfo &FLI) const { 115 MachineFunction &MF = MIRBuilder.getMF(); 116 MachineRegisterInfo &MRI = MF.getRegInfo(); 117 const auto &DL = F.getDataLayout(); 118 auto &TLI = *getTLI<PPCTargetLowering>(); 119 120 // Loop over each arg, set flags and split to single value types 121 SmallVector<ArgInfo, 8> SplitArgs; 122 unsigned I = 0; 123 for (const auto &Arg : F.args()) { 124 if (DL.getTypeStoreSize(Arg.getType()).isZero()) 125 continue; 126 127 ArgInfo OrigArg{VRegs[I], Arg, I}; 128 setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); 129 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 130 ++I; 131 } 132 133 CCAssignFn *AssignFn = 134 TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg()); 135 IncomingValueAssigner ArgAssigner(AssignFn); 136 FormalArgHandler ArgHandler(MIRBuilder, MRI); 137 return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 138 MIRBuilder, F.getCallingConv(), 139 F.isVarArg()); 140 } 141 142 void PPCIncomingValueHandler::assignValueToReg(Register ValVReg, 143 Register PhysReg, 144 const CCValAssign &VA) { 145 markPhysRegUsed(PhysReg); 146 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 147 } 148 149 void PPCIncomingValueHandler::assignValueToAddress( 150 Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO, 151 const CCValAssign &VA) { 152 // define a lambda expression to load value 153 auto BuildLoad = [](MachineIRBuilder &MIRBuilder, 154 const MachinePointerInfo &MPO, LLT MemTy, 155 const DstOp &Res, Register Addr) { 156 MachineFunction &MF = MIRBuilder.getMF(); 157 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, 158 inferAlignFromPtrInfo(MF, MPO)); 159 return MIRBuilder.buildLoad(Res, Addr, *MMO); 160 }; 161 162 BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr); 163 } 164 165 Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset, 166 MachinePointerInfo &MPO, 167 ISD::ArgFlagsTy Flags) { 168 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 169 const bool IsImmutable = !Flags.isByVal(); 170 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); 171 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 172 173 // Build Frame Index based on whether the machine is 32-bit or 64-bit 174 llvm::LLT FramePtr = LLT::pointer( 175 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits()); 176 MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI); 177 StackUsed = std::max(StackUsed, Size + Offset); 178 return AddrReg.getReg(0); 179 } 180 181 void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) { 182 MIRBuilder.getMRI()->addLiveIn(PhysReg); 183 MIRBuilder.getMBB().addLiveIn(PhysReg); 184 } 185