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