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 29 PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI) 30 : CallLowering(&TLI) {} 31 32 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 45 bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 46 CallLoweringInfo &Info) const { 47 return false; 48 } 49 50 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 81 void PPCIncomingValueHandler::assignValueToReg(Register ValVReg, 82 Register PhysReg, 83 CCValAssign &VA) { 84 markPhysRegUsed(PhysReg); 85 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 86 } 87 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 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 120 void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) { 121 MIRBuilder.getMRI()->addLiveIn(PhysReg); 122 MIRBuilder.getMBB().addLiveIn(PhysReg); 123 } 124