Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
35294 views
//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file implements the lowering of LLVM calls to machine code calls for10/// GlobalISel.11///12//===----------------------------------------------------------------------===//1314#include "PPCCallLowering.h"15#include "PPCCallingConv.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"2526#define DEBUG_TYPE "ppc-call-lowering"2728using namespace llvm;2930namespace {3132struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {33OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,34MachineInstrBuilder MIB)35: OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}3637void assignValueToReg(Register ValVReg, Register PhysReg,38const CCValAssign &VA) override;39void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,40const MachinePointerInfo &MPO,41const CCValAssign &VA) override;42Register getStackAddress(uint64_t Size, int64_t Offset,43MachinePointerInfo &MPO,44ISD::ArgFlagsTy Flags) override;4546MachineInstrBuilder MIB;47};48} // namespace4950void OutgoingArgHandler::assignValueToReg(Register ValVReg, Register PhysReg,51const CCValAssign &VA) {52MIB.addUse(PhysReg, RegState::Implicit);53Register ExtReg = extendRegister(ValVReg, VA);54MIRBuilder.buildCopy(PhysReg, ExtReg);55}5657void OutgoingArgHandler::assignValueToAddress(Register ValVReg, Register Addr,58LLT MemTy,59const MachinePointerInfo &MPO,60const CCValAssign &VA) {61llvm_unreachable("unimplemented");62}6364Register OutgoingArgHandler::getStackAddress(uint64_t Size, int64_t Offset,65MachinePointerInfo &MPO,66ISD::ArgFlagsTy Flags) {67llvm_unreachable("unimplemented");68}6970PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)71: CallLowering(&TLI) {}7273bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,74const Value *Val, ArrayRef<Register> VRegs,75FunctionLoweringInfo &FLI,76Register SwiftErrorVReg) const {77auto MIB = MIRBuilder.buildInstrNoInsert(PPC::BLR8);78bool Success = true;79MachineFunction &MF = MIRBuilder.getMF();80const Function &F = MF.getFunction();81MachineRegisterInfo &MRI = MF.getRegInfo();82auto &DL = F.getDataLayout();83if (!VRegs.empty()) {84// Setup the information about the return value.85ArgInfo OrigArg{VRegs, Val->getType(), 0};86setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);8788// Split the return value into consecutive registers if needed.89SmallVector<ArgInfo, 8> SplitArgs;90splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());9192// Use the calling convention callback to determine type and location of93// return value.94OutgoingValueAssigner ArgAssigner(RetCC_PPC);9596// Handler to move the return value into the correct location.97OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);9899// Iterate over all return values, and move them to the assigned location.100Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,101MIRBuilder, F.getCallingConv(),102F.isVarArg());103}104MIRBuilder.insertInstr(MIB);105return Success;106}107108bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,109CallLoweringInfo &Info) const {110return false;111}112113bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,114const Function &F,115ArrayRef<ArrayRef<Register>> VRegs,116FunctionLoweringInfo &FLI) const {117MachineFunction &MF = MIRBuilder.getMF();118MachineRegisterInfo &MRI = MF.getRegInfo();119const auto &DL = F.getDataLayout();120auto &TLI = *getTLI<PPCTargetLowering>();121122// Loop over each arg, set flags and split to single value types123SmallVector<ArgInfo, 8> SplitArgs;124unsigned I = 0;125for (const auto &Arg : F.args()) {126if (DL.getTypeStoreSize(Arg.getType()).isZero())127continue;128129ArgInfo OrigArg{VRegs[I], Arg, I};130setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);131splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());132++I;133}134135CCAssignFn *AssignFn =136TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg());137IncomingValueAssigner ArgAssigner(AssignFn);138FormalArgHandler ArgHandler(MIRBuilder, MRI);139return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,140MIRBuilder, F.getCallingConv(),141F.isVarArg());142}143144void PPCIncomingValueHandler::assignValueToReg(Register ValVReg,145Register PhysReg,146const CCValAssign &VA) {147markPhysRegUsed(PhysReg);148IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);149}150151void PPCIncomingValueHandler::assignValueToAddress(152Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,153const CCValAssign &VA) {154// define a lambda expression to load value155auto BuildLoad = [](MachineIRBuilder &MIRBuilder,156const MachinePointerInfo &MPO, LLT MemTy,157const DstOp &Res, Register Addr) {158MachineFunction &MF = MIRBuilder.getMF();159auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,160inferAlignFromPtrInfo(MF, MPO));161return MIRBuilder.buildLoad(Res, Addr, *MMO);162};163164BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr);165}166167Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,168MachinePointerInfo &MPO,169ISD::ArgFlagsTy Flags) {170auto &MFI = MIRBuilder.getMF().getFrameInfo();171const bool IsImmutable = !Flags.isByVal();172int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);173MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);174175// Build Frame Index based on whether the machine is 32-bit or 64-bit176llvm::LLT FramePtr = LLT::pointer(1770, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());178MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);179StackUsed = std::max(StackUsed, Size + Offset);180return AddrReg.getReg(0);181}182183void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) {184MIRBuilder.getMRI()->addLiveIn(PhysReg);185MIRBuilder.getMBB().addLiveIn(PhysReg);186}187188189