blob: 9cd959012e6f971535fb2e952994363b2eb68ba1 [file] [log] [blame]
//===-- M68kCallLowering.cpp - Call lowering -------------------*- 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 "M68kCallLowering.h"
#include "M68kISelLowering.h"
#include "M68kInstrInfo.h"
#include "M68kSubtarget.h"
#include "M68kTargetMachine.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/TargetCallingConv.h"
using namespace llvm;
M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI)
: CallLowering(&TLI) {}
struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstrBuilder MIB)
: OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
void assignValueToReg(Register ValVReg, Register PhysReg,
CCValAssign VA) override {
MIB.addUse(PhysReg, RegState::Implicit);
Register ExtReg = extendRegister(ValVReg, VA);
MIRBuilder.buildCopy(PhysReg, ExtReg);
}
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
MachinePointerInfo &MPO, CCValAssign &VA) override {
llvm_unreachable("unimplemented");
}
Register getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO,
ISD::ArgFlagsTy Flags) override {
llvm_unreachable("unimplemented");
}
MachineInstrBuilder MIB;
};
bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val, ArrayRef<Register> VRegs,
FunctionLoweringInfo &FLI,
Register SwiftErrorVReg) const {
auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);
bool Success = true;
MachineFunction &MF = MIRBuilder.getMF();
const Function &F = MF.getFunction();
MachineRegisterInfo &MRI = MF.getRegInfo();
const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();
CCAssignFn *AssignFn =
TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());
auto &DL = F.getParent()->getDataLayout();
if (!VRegs.empty()) {
SmallVector<ArgInfo, 8> SplitArgs;
ArgInfo OrigArg{VRegs, Val->getType(), 0};
setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
OutgoingValueAssigner ArgAssigner(AssignFn);
OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
MIRBuilder, F.getCallingConv(),
F.isVarArg());
}
MIRBuilder.insertInstr(MIB);
return Success;
}
bool M68kCallLowering::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<M68kTargetLowering>();
SmallVector<ArgInfo, 8> SplitArgs;
unsigned I = 0;
for (const auto &Arg : F.args()) {
ArgInfo OrigArg{VRegs[I], Arg.getType(), I};
setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
++I;
}
CCAssignFn *AssignFn =
TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());
IncomingValueAssigner ArgAssigner(AssignFn);
FormalArgHandler ArgHandler(MIRBuilder, MRI);
return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
MIRBuilder, F.getCallingConv(),
F.isVarArg());
}
void M68kIncomingValueHandler::assignValueToReg(Register ValVReg,
Register PhysReg,
CCValAssign VA) {
MIRBuilder.getMRI()->addLiveIn(PhysReg);
MIRBuilder.getMBB().addLiveIn(PhysReg);
IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
}
void M68kIncomingValueHandler::assignValueToAddress(Register ValVReg,
Register Addr,
LLT MemTy,
MachinePointerInfo &MPO,
CCValAssign &VA) {
MachineFunction &MF = MIRBuilder.getMF();
auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
inferAlignFromPtrInfo(MF, MPO));
MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
}
Register M68kIncomingValueHandler::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
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);
}
bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
CallLoweringInfo &Info) const {
return false;
}
bool M68kCallLowering::enableBigEndian() const { return true; }