1*04eeddc0SDimitry Andric //===-- M68kCallLowering.cpp - Call lowering --------------------*- C++ -*-===// 2349cc55cSDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6349cc55cSDimitry Andric // 7349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8349cc55cSDimitry Andric // 9349cc55cSDimitry Andric /// \file 10349cc55cSDimitry Andric /// This file implements the lowering of LLVM calls to machine code calls for 11349cc55cSDimitry Andric /// GlobalISel. 12349cc55cSDimitry Andric // 13349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 14349cc55cSDimitry Andric 15349cc55cSDimitry Andric #include "M68kCallLowering.h" 16349cc55cSDimitry Andric #include "M68kISelLowering.h" 17349cc55cSDimitry Andric #include "M68kInstrInfo.h" 18349cc55cSDimitry Andric #include "M68kSubtarget.h" 19349cc55cSDimitry Andric #include "M68kTargetMachine.h" 20349cc55cSDimitry Andric #include "llvm/CodeGen/CallingConvLower.h" 21349cc55cSDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h" 22349cc55cSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 23349cc55cSDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h" 24349cc55cSDimitry Andric 25349cc55cSDimitry Andric using namespace llvm; 26349cc55cSDimitry Andric 27349cc55cSDimitry Andric M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI) 28349cc55cSDimitry Andric : CallLowering(&TLI) {} 29349cc55cSDimitry Andric 30349cc55cSDimitry Andric struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { 31349cc55cSDimitry Andric OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 32349cc55cSDimitry Andric MachineInstrBuilder MIB) 33349cc55cSDimitry Andric : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {} 34349cc55cSDimitry Andric 35349cc55cSDimitry Andric void assignValueToReg(Register ValVReg, Register PhysReg, 36349cc55cSDimitry Andric CCValAssign VA) override { 37349cc55cSDimitry Andric MIB.addUse(PhysReg, RegState::Implicit); 38349cc55cSDimitry Andric Register ExtReg = extendRegister(ValVReg, VA); 39349cc55cSDimitry Andric MIRBuilder.buildCopy(PhysReg, ExtReg); 40349cc55cSDimitry Andric } 41349cc55cSDimitry Andric 42349cc55cSDimitry Andric void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, 43349cc55cSDimitry Andric MachinePointerInfo &MPO, CCValAssign &VA) override { 44349cc55cSDimitry Andric llvm_unreachable("unimplemented"); 45349cc55cSDimitry Andric } 46349cc55cSDimitry Andric 47349cc55cSDimitry Andric Register getStackAddress(uint64_t Size, int64_t Offset, 48349cc55cSDimitry Andric MachinePointerInfo &MPO, 49349cc55cSDimitry Andric ISD::ArgFlagsTy Flags) override { 50349cc55cSDimitry Andric llvm_unreachable("unimplemented"); 51349cc55cSDimitry Andric } 52349cc55cSDimitry Andric 53349cc55cSDimitry Andric MachineInstrBuilder MIB; 54349cc55cSDimitry Andric }; 55349cc55cSDimitry Andric bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 56349cc55cSDimitry Andric const Value *Val, ArrayRef<Register> VRegs, 57349cc55cSDimitry Andric FunctionLoweringInfo &FLI, 58349cc55cSDimitry Andric Register SwiftErrorVReg) const { 59349cc55cSDimitry Andric 60349cc55cSDimitry Andric auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS); 61349cc55cSDimitry Andric bool Success = true; 62349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 63349cc55cSDimitry Andric const Function &F = MF.getFunction(); 64349cc55cSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 65349cc55cSDimitry Andric const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>(); 66349cc55cSDimitry Andric CCAssignFn *AssignFn = 67349cc55cSDimitry Andric TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg()); 68349cc55cSDimitry Andric auto &DL = F.getParent()->getDataLayout(); 69349cc55cSDimitry Andric if (!VRegs.empty()) { 70349cc55cSDimitry Andric SmallVector<ArgInfo, 8> SplitArgs; 71349cc55cSDimitry Andric ArgInfo OrigArg{VRegs, Val->getType(), 0}; 72349cc55cSDimitry Andric setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 73349cc55cSDimitry Andric splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 74349cc55cSDimitry Andric OutgoingValueAssigner ArgAssigner(AssignFn); 75349cc55cSDimitry Andric OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB); 76349cc55cSDimitry Andric Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 77349cc55cSDimitry Andric MIRBuilder, F.getCallingConv(), 78349cc55cSDimitry Andric F.isVarArg()); 79349cc55cSDimitry Andric } 80349cc55cSDimitry Andric MIRBuilder.insertInstr(MIB); 81349cc55cSDimitry Andric return Success; 82349cc55cSDimitry Andric } 83349cc55cSDimitry Andric 84349cc55cSDimitry Andric bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 85349cc55cSDimitry Andric const Function &F, 86349cc55cSDimitry Andric ArrayRef<ArrayRef<Register>> VRegs, 87349cc55cSDimitry Andric FunctionLoweringInfo &FLI) const { 88349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 89349cc55cSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 90349cc55cSDimitry Andric const auto &DL = F.getParent()->getDataLayout(); 91349cc55cSDimitry Andric auto &TLI = *getTLI<M68kTargetLowering>(); 92349cc55cSDimitry Andric 93349cc55cSDimitry Andric SmallVector<ArgInfo, 8> SplitArgs; 94349cc55cSDimitry Andric unsigned I = 0; 95349cc55cSDimitry Andric for (const auto &Arg : F.args()) { 96349cc55cSDimitry Andric ArgInfo OrigArg{VRegs[I], Arg.getType(), I}; 97349cc55cSDimitry Andric setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); 98349cc55cSDimitry Andric splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 99349cc55cSDimitry Andric ++I; 100349cc55cSDimitry Andric } 101349cc55cSDimitry Andric 102349cc55cSDimitry Andric CCAssignFn *AssignFn = 103349cc55cSDimitry Andric TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg()); 104349cc55cSDimitry Andric IncomingValueAssigner ArgAssigner(AssignFn); 105349cc55cSDimitry Andric FormalArgHandler ArgHandler(MIRBuilder, MRI); 106349cc55cSDimitry Andric return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 107349cc55cSDimitry Andric MIRBuilder, F.getCallingConv(), 108349cc55cSDimitry Andric F.isVarArg()); 109349cc55cSDimitry Andric } 110349cc55cSDimitry Andric 111349cc55cSDimitry Andric void M68kIncomingValueHandler::assignValueToReg(Register ValVReg, 112349cc55cSDimitry Andric Register PhysReg, 113349cc55cSDimitry Andric CCValAssign VA) { 114349cc55cSDimitry Andric MIRBuilder.getMRI()->addLiveIn(PhysReg); 115349cc55cSDimitry Andric MIRBuilder.getMBB().addLiveIn(PhysReg); 116349cc55cSDimitry Andric IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 117349cc55cSDimitry Andric } 118349cc55cSDimitry Andric 119349cc55cSDimitry Andric void M68kIncomingValueHandler::assignValueToAddress(Register ValVReg, 120349cc55cSDimitry Andric Register Addr, 121349cc55cSDimitry Andric LLT MemTy, 122349cc55cSDimitry Andric MachinePointerInfo &MPO, 123349cc55cSDimitry Andric CCValAssign &VA) { 124349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 125349cc55cSDimitry Andric auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, 126349cc55cSDimitry Andric inferAlignFromPtrInfo(MF, MPO)); 127349cc55cSDimitry Andric MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 128349cc55cSDimitry Andric } 129349cc55cSDimitry Andric 130349cc55cSDimitry Andric Register M68kIncomingValueHandler::getStackAddress(uint64_t Size, 131349cc55cSDimitry Andric int64_t Offset, 132349cc55cSDimitry Andric MachinePointerInfo &MPO, 133349cc55cSDimitry Andric ISD::ArgFlagsTy Flags) { 134349cc55cSDimitry Andric auto &MFI = MIRBuilder.getMF().getFrameInfo(); 135349cc55cSDimitry Andric const bool IsImmutable = !Flags.isByVal(); 136349cc55cSDimitry Andric int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); 137349cc55cSDimitry Andric MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 138349cc55cSDimitry Andric 139349cc55cSDimitry Andric // Build Frame Index 140349cc55cSDimitry Andric llvm::LLT FramePtr = LLT::pointer( 141349cc55cSDimitry Andric 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits()); 142349cc55cSDimitry Andric MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI); 143349cc55cSDimitry Andric StackUsed = std::max(StackUsed, Size + Offset); 144349cc55cSDimitry Andric return AddrReg.getReg(0); 145349cc55cSDimitry Andric } 146349cc55cSDimitry Andric 147349cc55cSDimitry Andric bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 148349cc55cSDimitry Andric CallLoweringInfo &Info) const { 149349cc55cSDimitry Andric return false; 150349cc55cSDimitry Andric } 151349cc55cSDimitry Andric 152349cc55cSDimitry Andric bool M68kCallLowering::enableBigEndian() const { return true; } 153