124 lines
4.9 KiB
C++
124 lines
4.9 KiB
C++
//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file implements the lowering of LLVM calls to machine code calls for
|
|
/// GlobalISel.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "PPCCallLowering.h"
|
|
#include "PPCISelLowering.h"
|
|
#include "PPCSubtarget.h"
|
|
#include "PPCTargetMachine.h"
|
|
#include "llvm/CodeGen/CallingConvLower.h"
|
|
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
|
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
|
#include "llvm/CodeGen/TargetCallingConv.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#define DEBUG_TYPE "ppc-call-lowering"
|
|
|
|
using namespace llvm;
|
|
|
|
PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
|
|
: CallLowering(&TLI) {}
|
|
|
|
bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
|
|
const Value *Val, ArrayRef<Register> VRegs,
|
|
FunctionLoweringInfo &FLI,
|
|
Register SwiftErrorVReg) const {
|
|
assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
|
|
"Return value without a vreg");
|
|
if (VRegs.size() > 0)
|
|
return false;
|
|
|
|
MIRBuilder.buildInstr(PPC::BLR8);
|
|
return true;
|
|
}
|
|
|
|
bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
|
CallLoweringInfo &Info) const {
|
|
return false;
|
|
}
|
|
|
|
bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
|
|
const Function &F,
|
|
ArrayRef<ArrayRef<Register>> VRegs,
|
|
FunctionLoweringInfo &FLI) const {
|
|
MachineFunction &MF = MIRBuilder.getMF();
|
|
MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
const auto &DL = F.getParent()->getDataLayout();
|
|
auto &TLI = *getTLI<PPCTargetLowering>();
|
|
|
|
// Loop over each arg, set flags and split to single value types
|
|
SmallVector<ArgInfo, 8> SplitArgs;
|
|
unsigned I = 0;
|
|
for (const auto &Arg : F.args()) {
|
|
if (DL.getTypeStoreSize(Arg.getType()).isZero())
|
|
continue;
|
|
|
|
ArgInfo OrigArg{VRegs[I], Arg, I};
|
|
setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
|
|
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
|
|
++I;
|
|
}
|
|
|
|
CCAssignFn *AssignFn =
|
|
TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg());
|
|
IncomingValueAssigner ArgAssigner(AssignFn);
|
|
FormalArgHandler ArgHandler(MIRBuilder, MRI);
|
|
return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
|
|
MIRBuilder, F.getCallingConv(),
|
|
F.isVarArg());
|
|
}
|
|
|
|
void PPCIncomingValueHandler::assignValueToReg(Register ValVReg,
|
|
Register PhysReg,
|
|
CCValAssign &VA) {
|
|
markPhysRegUsed(PhysReg);
|
|
IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
|
|
}
|
|
|
|
void PPCIncomingValueHandler::assignValueToAddress(Register ValVReg,
|
|
Register Addr, LLT MemTy,
|
|
MachinePointerInfo &MPO,
|
|
CCValAssign &VA) {
|
|
// define a lambda expression to load value
|
|
auto BuildLoad = [](MachineIRBuilder &MIRBuilder, MachinePointerInfo &MPO,
|
|
LLT MemTy, const DstOp &Res, Register Addr) {
|
|
MachineFunction &MF = MIRBuilder.getMF();
|
|
auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
|
|
inferAlignFromPtrInfo(MF, MPO));
|
|
return MIRBuilder.buildLoad(Res, Addr, *MMO);
|
|
};
|
|
|
|
BuildLoad(MIRBuilder, MPO, MemTy, ValVReg, Addr);
|
|
}
|
|
|
|
Register PPCIncomingValueHandler::getStackAddress(uint64_t Size, int64_t Offset,
|
|
MachinePointerInfo &MPO,
|
|
ISD::ArgFlagsTy Flags) {
|
|
auto &MFI = MIRBuilder.getMF().getFrameInfo();
|
|
const bool IsImmutable = !Flags.isByVal();
|
|
int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
|
|
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
|
|
|
|
// Build Frame Index based on whether the machine is 32-bit or 64-bit
|
|
llvm::LLT FramePtr = LLT::pointer(
|
|
0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());
|
|
MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);
|
|
StackUsed = std::max(StackUsed, Size + Offset);
|
|
return AddrReg.getReg(0);
|
|
}
|
|
|
|
void FormalArgHandler::markPhysRegUsed(unsigned PhysReg) {
|
|
MIRBuilder.getMRI()->addLiveIn(PhysReg);
|
|
MIRBuilder.getMBB().addLiveIn(PhysReg);
|
|
}
|