Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp
35294 views
//===-- M68kCallLowering.cpp - Call lowering --------------------*- 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 "M68kCallLowering.h"15#include "M68kISelLowering.h"16#include "M68kInstrInfo.h"17#include "M68kSubtarget.h"18#include "M68kTargetMachine.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"2425using namespace llvm;2627namespace {2829struct M68kFormalArgHandler : public M68kIncomingValueHandler {30M68kFormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)31: M68kIncomingValueHandler(MIRBuilder, MRI) {}32};3334struct CallReturnHandler : public M68kIncomingValueHandler {35CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,36MachineInstrBuilder &MIB)37: M68kIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}3839private:40void assignValueToReg(Register ValVReg, Register PhysReg,41const CCValAssign &VA) override;4243MachineInstrBuilder &MIB;44};4546} // end anonymous namespace4748M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI)49: CallLowering(&TLI) {}5051struct M68kOutgoingArgHandler : public CallLowering::OutgoingValueHandler {52M68kOutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,53MachineInstrBuilder MIB)54: OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB),55DL(MIRBuilder.getMF().getDataLayout()),56STI(MIRBuilder.getMF().getSubtarget<M68kSubtarget>()) {}5758void assignValueToReg(Register ValVReg, Register PhysReg,59const CCValAssign &VA) override {60MIB.addUse(PhysReg, RegState::Implicit);61Register ExtReg = extendRegister(ValVReg, VA);62MIRBuilder.buildCopy(PhysReg, ExtReg);63}6465void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,66const MachinePointerInfo &MPO,67const CCValAssign &VA) override {68MachineFunction &MF = MIRBuilder.getMF();69Register ExtReg = extendRegister(ValVReg, VA);7071auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,72inferAlignFromPtrInfo(MF, MPO));73MIRBuilder.buildStore(ExtReg, Addr, *MMO);74}7576Register getStackAddress(uint64_t Size, int64_t Offset,77MachinePointerInfo &MPO,78ISD::ArgFlagsTy Flags) override {79LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0));80LLT SType = LLT::scalar(DL.getPointerSizeInBits(0));81Register StackReg = STI.getRegisterInfo()->getStackRegister();82auto SPReg = MIRBuilder.buildCopy(p0, StackReg).getReg(0);83auto OffsetReg = MIRBuilder.buildConstant(SType, Offset);84auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);85MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);86return AddrReg.getReg(0);87}88MachineInstrBuilder MIB;89const DataLayout &DL;90const M68kSubtarget &STI;91};92bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,93const Value *Val, ArrayRef<Register> VRegs,94FunctionLoweringInfo &FLI,95Register SwiftErrorVReg) const {9697auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);98bool Success = true;99MachineFunction &MF = MIRBuilder.getMF();100const Function &F = MF.getFunction();101MachineRegisterInfo &MRI = MF.getRegInfo();102const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();103CCAssignFn *AssignFn =104TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());105auto &DL = F.getDataLayout();106if (!VRegs.empty()) {107SmallVector<ArgInfo, 8> SplitArgs;108ArgInfo OrigArg{VRegs, Val->getType(), 0};109setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);110splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());111OutgoingValueAssigner ArgAssigner(AssignFn);112M68kOutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);113Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,114MIRBuilder, F.getCallingConv(),115F.isVarArg());116}117MIRBuilder.insertInstr(MIB);118return Success;119}120121bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,122const Function &F,123ArrayRef<ArrayRef<Register>> VRegs,124FunctionLoweringInfo &FLI) const {125MachineFunction &MF = MIRBuilder.getMF();126MachineRegisterInfo &MRI = MF.getRegInfo();127const auto &DL = F.getDataLayout();128auto &TLI = *getTLI<M68kTargetLowering>();129130SmallVector<ArgInfo, 8> SplitArgs;131unsigned I = 0;132for (const auto &Arg : F.args()) {133ArgInfo OrigArg{VRegs[I], Arg.getType(), I};134setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);135splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());136++I;137}138139CCAssignFn *AssignFn =140TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());141IncomingValueAssigner ArgAssigner(AssignFn);142M68kFormalArgHandler ArgHandler(MIRBuilder, MRI);143return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,144MIRBuilder, F.getCallingConv(),145F.isVarArg());146}147148void M68kIncomingValueHandler::assignValueToReg(Register ValVReg,149Register PhysReg,150const CCValAssign &VA) {151MIRBuilder.getMRI()->addLiveIn(PhysReg);152MIRBuilder.getMBB().addLiveIn(PhysReg);153IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);154}155156void M68kIncomingValueHandler::assignValueToAddress(157Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,158const CCValAssign &VA) {159MachineFunction &MF = MIRBuilder.getMF();160auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,161inferAlignFromPtrInfo(MF, MPO));162MIRBuilder.buildLoad(ValVReg, Addr, *MMO);163}164165Register M68kIncomingValueHandler::getStackAddress(uint64_t Size,166int64_t Offset,167MachinePointerInfo &MPO,168ISD::ArgFlagsTy Flags) {169auto &MFI = MIRBuilder.getMF().getFrameInfo();170const bool IsImmutable = !Flags.isByVal();171int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);172MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);173174// Build Frame Index175llvm::LLT FramePtr = LLT::pointer(1760, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());177MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);178StackUsed = std::max(StackUsed, Size + Offset);179return AddrReg.getReg(0);180}181182void CallReturnHandler::assignValueToReg(Register ValVReg, Register PhysReg,183const CCValAssign &VA) {184MIB.addDef(PhysReg, RegState::Implicit);185MIRBuilder.buildCopy(ValVReg, PhysReg);186}187188bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,189CallLoweringInfo &Info) const {190MachineFunction &MF = MIRBuilder.getMF();191Function &F = MF.getFunction();192MachineRegisterInfo &MRI = MF.getRegInfo();193auto &DL = F.getDataLayout();194const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();195const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();196const TargetInstrInfo &TII = *STI.getInstrInfo();197const M68kRegisterInfo *TRI = STI.getRegisterInfo();198199SmallVector<ArgInfo, 8> OutArgs;200for (auto &OrigArg : Info.OrigArgs)201splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);202203SmallVector<ArgInfo, 8> InArgs;204if (!Info.OrigRet.Ty->isVoidTy())205splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);206207unsigned AdjStackDown = TII.getCallFrameSetupOpcode();208auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown);209210unsigned Opc = TLI.getTargetMachine().isPositionIndependent() ? M68k::CALLq211: Info.Callee.isReg() ? M68k::CALLj212: M68k::CALLb;213214auto MIB = MIRBuilder.buildInstrNoInsert(Opc)215.add(Info.Callee)216.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));217218CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg);219OutgoingValueAssigner Assigner(AssignFn);220M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB);221if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,222Info.CallConv, Info.IsVarArg))223return false;224225if (Info.Callee.isReg())226constrainOperandRegClass(MF, *TRI, MRI, *STI.getInstrInfo(),227*STI.getRegBankInfo(), *MIB, MIB->getDesc(),228Info.Callee, 0);229230MIRBuilder.insertInstr(MIB);231232if (!Info.OrigRet.Ty->isVoidTy()) {233CCAssignFn *RetAssignFn =234TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg);235236OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn);237CallReturnHandler Handler(MIRBuilder, MRI, MIB);238if (!determineAndHandleAssignments(Handler, Assigner, InArgs, MIRBuilder,239Info.CallConv, Info.IsVarArg))240return false;241}242243CallSeqStart.addImm(Assigner.StackSize).addImm(0);244245unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();246MIRBuilder.buildInstr(AdjStackUp).addImm(Assigner.StackSize).addImm(0);247248return true;249}250251bool M68kCallLowering::enableBigEndian() const { return true; }252253254