1*349cc55cSDimitry Andric //===-- M68kCallLowering.cpp - Call lowering -------------------*- C++ -*-===// 2*349cc55cSDimitry Andric // 3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*349cc55cSDimitry Andric // 7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8*349cc55cSDimitry Andric // 9*349cc55cSDimitry Andric /// \file 10*349cc55cSDimitry Andric /// This file implements the lowering of LLVM calls to machine code calls for 11*349cc55cSDimitry Andric /// GlobalISel. 12*349cc55cSDimitry Andric // 13*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 14*349cc55cSDimitry Andric 15*349cc55cSDimitry Andric #include "M68kCallLowering.h" 16*349cc55cSDimitry Andric #include "M68kISelLowering.h" 17*349cc55cSDimitry Andric #include "M68kInstrInfo.h" 18*349cc55cSDimitry Andric #include "M68kSubtarget.h" 19*349cc55cSDimitry Andric #include "M68kTargetMachine.h" 20*349cc55cSDimitry Andric #include "llvm/CodeGen/CallingConvLower.h" 21*349cc55cSDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h" 22*349cc55cSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 23*349cc55cSDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h" 24*349cc55cSDimitry Andric 25*349cc55cSDimitry Andric using namespace llvm; 26*349cc55cSDimitry Andric 27*349cc55cSDimitry Andric M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI) 28*349cc55cSDimitry Andric : CallLowering(&TLI) {} 29*349cc55cSDimitry Andric 30*349cc55cSDimitry Andric struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { 31*349cc55cSDimitry Andric OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 32*349cc55cSDimitry Andric MachineInstrBuilder MIB) 33*349cc55cSDimitry Andric : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {} 34*349cc55cSDimitry Andric 35*349cc55cSDimitry Andric void assignValueToReg(Register ValVReg, Register PhysReg, 36*349cc55cSDimitry Andric CCValAssign VA) override { 37*349cc55cSDimitry Andric MIB.addUse(PhysReg, RegState::Implicit); 38*349cc55cSDimitry Andric Register ExtReg = extendRegister(ValVReg, VA); 39*349cc55cSDimitry Andric MIRBuilder.buildCopy(PhysReg, ExtReg); 40*349cc55cSDimitry Andric } 41*349cc55cSDimitry Andric 42*349cc55cSDimitry Andric void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, 43*349cc55cSDimitry Andric MachinePointerInfo &MPO, CCValAssign &VA) override { 44*349cc55cSDimitry Andric llvm_unreachable("unimplemented"); 45*349cc55cSDimitry Andric } 46*349cc55cSDimitry Andric 47*349cc55cSDimitry Andric Register getStackAddress(uint64_t Size, int64_t Offset, 48*349cc55cSDimitry Andric MachinePointerInfo &MPO, 49*349cc55cSDimitry Andric ISD::ArgFlagsTy Flags) override { 50*349cc55cSDimitry Andric llvm_unreachable("unimplemented"); 51*349cc55cSDimitry Andric } 52*349cc55cSDimitry Andric 53*349cc55cSDimitry Andric MachineInstrBuilder MIB; 54*349cc55cSDimitry Andric }; 55*349cc55cSDimitry Andric bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 56*349cc55cSDimitry Andric const Value *Val, ArrayRef<Register> VRegs, 57*349cc55cSDimitry Andric FunctionLoweringInfo &FLI, 58*349cc55cSDimitry Andric Register SwiftErrorVReg) const { 59*349cc55cSDimitry Andric 60*349cc55cSDimitry Andric auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS); 61*349cc55cSDimitry Andric bool Success = true; 62*349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 63*349cc55cSDimitry Andric const Function &F = MF.getFunction(); 64*349cc55cSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 65*349cc55cSDimitry Andric const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>(); 66*349cc55cSDimitry Andric CCAssignFn *AssignFn = 67*349cc55cSDimitry Andric TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg()); 68*349cc55cSDimitry Andric auto &DL = F.getParent()->getDataLayout(); 69*349cc55cSDimitry Andric if (!VRegs.empty()) { 70*349cc55cSDimitry Andric SmallVector<ArgInfo, 8> SplitArgs; 71*349cc55cSDimitry Andric ArgInfo OrigArg{VRegs, Val->getType(), 0}; 72*349cc55cSDimitry Andric setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 73*349cc55cSDimitry Andric splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 74*349cc55cSDimitry Andric OutgoingValueAssigner ArgAssigner(AssignFn); 75*349cc55cSDimitry Andric OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB); 76*349cc55cSDimitry Andric Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 77*349cc55cSDimitry Andric MIRBuilder, F.getCallingConv(), 78*349cc55cSDimitry Andric F.isVarArg()); 79*349cc55cSDimitry Andric } 80*349cc55cSDimitry Andric MIRBuilder.insertInstr(MIB); 81*349cc55cSDimitry Andric return Success; 82*349cc55cSDimitry Andric } 83*349cc55cSDimitry Andric 84*349cc55cSDimitry Andric bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 85*349cc55cSDimitry Andric const Function &F, 86*349cc55cSDimitry Andric ArrayRef<ArrayRef<Register>> VRegs, 87*349cc55cSDimitry Andric FunctionLoweringInfo &FLI) const { 88*349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 89*349cc55cSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 90*349cc55cSDimitry Andric const auto &DL = F.getParent()->getDataLayout(); 91*349cc55cSDimitry Andric auto &TLI = *getTLI<M68kTargetLowering>(); 92*349cc55cSDimitry Andric 93*349cc55cSDimitry Andric SmallVector<ArgInfo, 8> SplitArgs; 94*349cc55cSDimitry Andric unsigned I = 0; 95*349cc55cSDimitry Andric for (const auto &Arg : F.args()) { 96*349cc55cSDimitry Andric ArgInfo OrigArg{VRegs[I], Arg.getType(), I}; 97*349cc55cSDimitry Andric setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); 98*349cc55cSDimitry Andric splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 99*349cc55cSDimitry Andric ++I; 100*349cc55cSDimitry Andric } 101*349cc55cSDimitry Andric 102*349cc55cSDimitry Andric CCAssignFn *AssignFn = 103*349cc55cSDimitry Andric TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg()); 104*349cc55cSDimitry Andric IncomingValueAssigner ArgAssigner(AssignFn); 105*349cc55cSDimitry Andric FormalArgHandler ArgHandler(MIRBuilder, MRI); 106*349cc55cSDimitry Andric return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 107*349cc55cSDimitry Andric MIRBuilder, F.getCallingConv(), 108*349cc55cSDimitry Andric F.isVarArg()); 109*349cc55cSDimitry Andric } 110*349cc55cSDimitry Andric 111*349cc55cSDimitry Andric void M68kIncomingValueHandler::assignValueToReg(Register ValVReg, 112*349cc55cSDimitry Andric Register PhysReg, 113*349cc55cSDimitry Andric CCValAssign VA) { 114*349cc55cSDimitry Andric MIRBuilder.getMRI()->addLiveIn(PhysReg); 115*349cc55cSDimitry Andric MIRBuilder.getMBB().addLiveIn(PhysReg); 116*349cc55cSDimitry Andric IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 117*349cc55cSDimitry Andric } 118*349cc55cSDimitry Andric 119*349cc55cSDimitry Andric void M68kIncomingValueHandler::assignValueToAddress(Register ValVReg, 120*349cc55cSDimitry Andric Register Addr, 121*349cc55cSDimitry Andric LLT MemTy, 122*349cc55cSDimitry Andric MachinePointerInfo &MPO, 123*349cc55cSDimitry Andric CCValAssign &VA) { 124*349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 125*349cc55cSDimitry Andric auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, 126*349cc55cSDimitry Andric inferAlignFromPtrInfo(MF, MPO)); 127*349cc55cSDimitry Andric MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 128*349cc55cSDimitry Andric } 129*349cc55cSDimitry Andric 130*349cc55cSDimitry Andric Register M68kIncomingValueHandler::getStackAddress(uint64_t Size, 131*349cc55cSDimitry Andric int64_t Offset, 132*349cc55cSDimitry Andric MachinePointerInfo &MPO, 133*349cc55cSDimitry Andric ISD::ArgFlagsTy Flags) { 134*349cc55cSDimitry Andric auto &MFI = MIRBuilder.getMF().getFrameInfo(); 135*349cc55cSDimitry Andric const bool IsImmutable = !Flags.isByVal(); 136*349cc55cSDimitry Andric int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); 137*349cc55cSDimitry Andric MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 138*349cc55cSDimitry Andric 139*349cc55cSDimitry Andric // Build Frame Index 140*349cc55cSDimitry Andric llvm::LLT FramePtr = LLT::pointer( 141*349cc55cSDimitry Andric 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits()); 142*349cc55cSDimitry Andric MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI); 143*349cc55cSDimitry Andric StackUsed = std::max(StackUsed, Size + Offset); 144*349cc55cSDimitry Andric return AddrReg.getReg(0); 145*349cc55cSDimitry Andric } 146*349cc55cSDimitry Andric 147*349cc55cSDimitry Andric bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 148*349cc55cSDimitry Andric CallLoweringInfo &Info) const { 149*349cc55cSDimitry Andric return false; 150*349cc55cSDimitry Andric } 151*349cc55cSDimitry Andric 152*349cc55cSDimitry Andric bool M68kCallLowering::enableBigEndian() const { return true; } 153