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/MachineFrameInfo.h" 23 #include "llvm/CodeGen/TargetCallingConv.h" 24 #include "llvm/Support/Debug.h" 25 26 #define DEBUG_TYPE "ppc-call-lowering" 27 28 using namespace llvm; 29 30 PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI) 31 : CallLowering(&TLI) {} 32 33 bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 34 const Value *Val, ArrayRef<Register> VRegs, 35 FunctionLoweringInfo &FLI, 36 Register SwiftErrorVReg) const { 37 assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && 38 "Return value without a vreg"); 39 if (VRegs.size() > 0) 40 return false; 41 42 MIRBuilder.buildInstr(PPC::BLR8); 43 return true; 44 } 45 46 bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 47 CallLoweringInfo &Info) const { 48 return false; 49 } 50 51 bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 52 const Function &F, 53 ArrayRef<ArrayRef<Register>> VRegs, 54 FunctionLoweringInfo &FLI) const { 55 MachineFunction &MF = MIRBuilder.getMF(); 56 MachineRegisterInfo &MRI = MF.getRegInfo(); 57 const auto &DL = F.getParent()->getDataLayout(); 58 auto &TLI = *getTLI<PPCTargetLowering>(); 59 60 // Loop over each arg, set flags and split to single value types 61 SmallVector<ArgInfo, 8> SplitArgs; 62 unsigned I = 0; 63 for (const auto &Arg : F.args()) { 64 if (DL.getTypeStoreSize(Arg.getType()).isZero()) 65 continue; 66 67 ArgInfo OrigArg{VRegs[I], Arg, I}; 68 setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); 69 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 70 ++I; 71 } 72 73 CCAssignFn *AssignFn = 74 TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg()); 75 IncomingValueAssigner ArgAssigner(AssignFn); 76 FormalArgHandler ArgHandler(MIRBuilder, MRI); 77 return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 78 MIRBuilder, F.getCallingConv(), 79 F.isVarArg()); 80 } 81 82 void PPCIncomingValueHandler::assignValueToReg(Register ValVReg, 83 Register PhysReg, 84 CCValAssign VA) { 85 markPhysRegUsed(PhysReg); 86 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 87 } 88 89 void PPCIncomingValueHandler::assignValueToAddress(Register ValVReg, 90 Register Addr, LLT MemTy, 91 MachinePointerInfo &MPO, 92 CCValAssign &VA) { 93 // define a lambda expression to load value 94 auto BuildLoad = [](MachineIRBuilder &MIRBuilder, MachinePointerInfo &MPO, 95 LLT MemTy, const DstOp &Res, Register Addr) { 96 MachineFunction &MF = MIRBuilder.getMF(); 97 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, 98 inferAlignFromPtrInfo(MF, MPO)); 99 return MIRBuilder.buildLoad(Res, Addr, *MMO); 100 }; 101 102 BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr); 103 } 104 105 Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset, 106 MachinePointerInfo &MPO, 107 ISD::ArgFlagsTy Flags) { 108 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 109 const bool IsImmutable = !Flags.isByVal(); 110 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); 111 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 112 113 // Build Frame Index based on whether the machine is 32-bit or 64-bit 114 llvm::LLT FramePtr = LLT::pointer( 115 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits()); 116 MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI); 117 StackUsed = std::max(StackUsed, Size + Offset); 118 return AddrReg.getReg(0); 119 } 120 121 void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) { 122 MIRBuilder.getMRI()->addLiveIn(PhysReg); 123 MIRBuilder.getMBB().addLiveIn(PhysReg); 124 } 125