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