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