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