104eeddc0SDimitry 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" 23*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 24349cc55cSDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h" 25349cc55cSDimitry Andric 26349cc55cSDimitry Andric using namespace llvm; 27349cc55cSDimitry Andric 28349cc55cSDimitry Andric M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI) 29349cc55cSDimitry Andric : CallLowering(&TLI) {} 30349cc55cSDimitry Andric 31*81ad6265SDimitry Andric struct M68kOutgoingArgHandler : public CallLowering::OutgoingValueHandler { 32*81ad6265SDimitry Andric M68kOutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 33349cc55cSDimitry Andric MachineInstrBuilder MIB) 34*81ad6265SDimitry Andric : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), 35*81ad6265SDimitry Andric DL(MIRBuilder.getMF().getDataLayout()), 36*81ad6265SDimitry Andric STI(MIRBuilder.getMF().getSubtarget<M68kSubtarget>()) {} 37349cc55cSDimitry Andric 38349cc55cSDimitry Andric void assignValueToReg(Register ValVReg, Register PhysReg, 39349cc55cSDimitry Andric CCValAssign VA) override { 40349cc55cSDimitry Andric MIB.addUse(PhysReg, RegState::Implicit); 41349cc55cSDimitry Andric Register ExtReg = extendRegister(ValVReg, VA); 42349cc55cSDimitry Andric MIRBuilder.buildCopy(PhysReg, ExtReg); 43349cc55cSDimitry Andric } 44349cc55cSDimitry Andric 45349cc55cSDimitry Andric void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, 46349cc55cSDimitry Andric MachinePointerInfo &MPO, CCValAssign &VA) override { 47*81ad6265SDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 48*81ad6265SDimitry Andric Register ExtReg = extendRegister(ValVReg, VA); 49*81ad6265SDimitry Andric 50*81ad6265SDimitry Andric auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy, 51*81ad6265SDimitry Andric inferAlignFromPtrInfo(MF, MPO)); 52*81ad6265SDimitry Andric MIRBuilder.buildStore(ExtReg, Addr, *MMO); 53349cc55cSDimitry Andric } 54349cc55cSDimitry Andric 55349cc55cSDimitry Andric Register getStackAddress(uint64_t Size, int64_t Offset, 56349cc55cSDimitry Andric MachinePointerInfo &MPO, 57349cc55cSDimitry Andric ISD::ArgFlagsTy Flags) override { 58*81ad6265SDimitry Andric LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0)); 59*81ad6265SDimitry Andric LLT SType = LLT::scalar(DL.getPointerSizeInBits(0)); 60*81ad6265SDimitry Andric Register StackReg = STI.getRegisterInfo()->getStackRegister(); 61*81ad6265SDimitry Andric auto SPReg = MIRBuilder.buildCopy(p0, StackReg).getReg(0); 62*81ad6265SDimitry Andric auto OffsetReg = MIRBuilder.buildConstant(SType, Offset); 63*81ad6265SDimitry Andric auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg); 64*81ad6265SDimitry Andric MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset); 65*81ad6265SDimitry Andric return AddrReg.getReg(0); 66349cc55cSDimitry Andric } 67349cc55cSDimitry Andric MachineInstrBuilder MIB; 68*81ad6265SDimitry Andric const DataLayout &DL; 69*81ad6265SDimitry Andric const M68kSubtarget &STI; 70349cc55cSDimitry Andric }; 71349cc55cSDimitry Andric bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 72349cc55cSDimitry Andric const Value *Val, ArrayRef<Register> VRegs, 73349cc55cSDimitry Andric FunctionLoweringInfo &FLI, 74349cc55cSDimitry Andric Register SwiftErrorVReg) const { 75349cc55cSDimitry Andric 76349cc55cSDimitry Andric auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS); 77349cc55cSDimitry Andric bool Success = true; 78349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 79349cc55cSDimitry Andric const Function &F = MF.getFunction(); 80349cc55cSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 81349cc55cSDimitry Andric const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>(); 82349cc55cSDimitry Andric CCAssignFn *AssignFn = 83349cc55cSDimitry Andric TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg()); 84349cc55cSDimitry Andric auto &DL = F.getParent()->getDataLayout(); 85349cc55cSDimitry Andric if (!VRegs.empty()) { 86349cc55cSDimitry Andric SmallVector<ArgInfo, 8> SplitArgs; 87349cc55cSDimitry Andric ArgInfo OrigArg{VRegs, Val->getType(), 0}; 88349cc55cSDimitry Andric setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 89349cc55cSDimitry Andric splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 90349cc55cSDimitry Andric OutgoingValueAssigner ArgAssigner(AssignFn); 91*81ad6265SDimitry Andric M68kOutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB); 92349cc55cSDimitry Andric Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 93349cc55cSDimitry Andric MIRBuilder, F.getCallingConv(), 94349cc55cSDimitry Andric F.isVarArg()); 95349cc55cSDimitry Andric } 96349cc55cSDimitry Andric MIRBuilder.insertInstr(MIB); 97349cc55cSDimitry Andric return Success; 98349cc55cSDimitry Andric } 99349cc55cSDimitry Andric 100349cc55cSDimitry Andric bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 101349cc55cSDimitry Andric const Function &F, 102349cc55cSDimitry Andric ArrayRef<ArrayRef<Register>> VRegs, 103349cc55cSDimitry Andric FunctionLoweringInfo &FLI) const { 104349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 105349cc55cSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 106349cc55cSDimitry Andric const auto &DL = F.getParent()->getDataLayout(); 107349cc55cSDimitry Andric auto &TLI = *getTLI<M68kTargetLowering>(); 108349cc55cSDimitry Andric 109349cc55cSDimitry Andric SmallVector<ArgInfo, 8> SplitArgs; 110349cc55cSDimitry Andric unsigned I = 0; 111349cc55cSDimitry Andric for (const auto &Arg : F.args()) { 112349cc55cSDimitry Andric ArgInfo OrigArg{VRegs[I], Arg.getType(), I}; 113349cc55cSDimitry Andric setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); 114349cc55cSDimitry Andric splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 115349cc55cSDimitry Andric ++I; 116349cc55cSDimitry Andric } 117349cc55cSDimitry Andric 118349cc55cSDimitry Andric CCAssignFn *AssignFn = 119349cc55cSDimitry Andric TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg()); 120349cc55cSDimitry Andric IncomingValueAssigner ArgAssigner(AssignFn); 121349cc55cSDimitry Andric FormalArgHandler ArgHandler(MIRBuilder, MRI); 122349cc55cSDimitry Andric return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 123349cc55cSDimitry Andric MIRBuilder, F.getCallingConv(), 124349cc55cSDimitry Andric F.isVarArg()); 125349cc55cSDimitry Andric } 126349cc55cSDimitry Andric 127349cc55cSDimitry Andric void M68kIncomingValueHandler::assignValueToReg(Register ValVReg, 128349cc55cSDimitry Andric Register PhysReg, 129349cc55cSDimitry Andric CCValAssign VA) { 130349cc55cSDimitry Andric MIRBuilder.getMRI()->addLiveIn(PhysReg); 131349cc55cSDimitry Andric MIRBuilder.getMBB().addLiveIn(PhysReg); 132349cc55cSDimitry Andric IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 133349cc55cSDimitry Andric } 134349cc55cSDimitry Andric 135349cc55cSDimitry Andric void M68kIncomingValueHandler::assignValueToAddress(Register ValVReg, 136349cc55cSDimitry Andric Register Addr, 137349cc55cSDimitry Andric LLT MemTy, 138349cc55cSDimitry Andric MachinePointerInfo &MPO, 139349cc55cSDimitry Andric CCValAssign &VA) { 140349cc55cSDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 141349cc55cSDimitry Andric auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, 142349cc55cSDimitry Andric inferAlignFromPtrInfo(MF, MPO)); 143349cc55cSDimitry Andric MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 144349cc55cSDimitry Andric } 145349cc55cSDimitry Andric 146349cc55cSDimitry Andric Register M68kIncomingValueHandler::getStackAddress(uint64_t Size, 147349cc55cSDimitry Andric int64_t Offset, 148349cc55cSDimitry Andric MachinePointerInfo &MPO, 149349cc55cSDimitry Andric ISD::ArgFlagsTy Flags) { 150349cc55cSDimitry Andric auto &MFI = MIRBuilder.getMF().getFrameInfo(); 151349cc55cSDimitry Andric const bool IsImmutable = !Flags.isByVal(); 152349cc55cSDimitry Andric int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); 153349cc55cSDimitry Andric MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 154349cc55cSDimitry Andric 155349cc55cSDimitry Andric // Build Frame Index 156349cc55cSDimitry Andric llvm::LLT FramePtr = LLT::pointer( 157349cc55cSDimitry Andric 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits()); 158349cc55cSDimitry Andric MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI); 159349cc55cSDimitry Andric StackUsed = std::max(StackUsed, Size + Offset); 160349cc55cSDimitry Andric return AddrReg.getReg(0); 161349cc55cSDimitry Andric } 162349cc55cSDimitry Andric 163*81ad6265SDimitry Andric void CallReturnHandler::assignValueToReg(Register ValVReg, Register PhysReg, 164*81ad6265SDimitry Andric CCValAssign VA) { 165*81ad6265SDimitry Andric MIB.addDef(PhysReg, RegState::Implicit); 166*81ad6265SDimitry Andric MIRBuilder.buildCopy(ValVReg, PhysReg); 167*81ad6265SDimitry Andric } 168*81ad6265SDimitry Andric 169349cc55cSDimitry Andric bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 170349cc55cSDimitry Andric CallLoweringInfo &Info) const { 171*81ad6265SDimitry Andric MachineFunction &MF = MIRBuilder.getMF(); 172*81ad6265SDimitry Andric Function &F = MF.getFunction(); 173*81ad6265SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 174*81ad6265SDimitry Andric auto &DL = F.getParent()->getDataLayout(); 175*81ad6265SDimitry Andric const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>(); 176*81ad6265SDimitry Andric const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>(); 177*81ad6265SDimitry Andric const TargetInstrInfo &TII = *STI.getInstrInfo(); 178*81ad6265SDimitry Andric const M68kRegisterInfo *TRI = STI.getRegisterInfo(); 179*81ad6265SDimitry Andric 180*81ad6265SDimitry Andric SmallVector<ArgInfo, 8> OutArgs; 181*81ad6265SDimitry Andric for (auto &OrigArg : Info.OrigArgs) 182*81ad6265SDimitry Andric splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv); 183*81ad6265SDimitry Andric 184*81ad6265SDimitry Andric SmallVector<ArgInfo, 8> InArgs; 185*81ad6265SDimitry Andric if (!Info.OrigRet.Ty->isVoidTy()) 186*81ad6265SDimitry Andric splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv); 187*81ad6265SDimitry Andric 188*81ad6265SDimitry Andric unsigned AdjStackDown = TII.getCallFrameSetupOpcode(); 189*81ad6265SDimitry Andric auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown); 190*81ad6265SDimitry Andric 191*81ad6265SDimitry Andric unsigned Opc = TLI.getTargetMachine().isPositionIndependent() ? M68k::CALLq 192*81ad6265SDimitry Andric : Info.Callee.isReg() ? M68k::CALLj 193*81ad6265SDimitry Andric : M68k::CALLb; 194*81ad6265SDimitry Andric 195*81ad6265SDimitry Andric auto MIB = MIRBuilder.buildInstrNoInsert(Opc) 196*81ad6265SDimitry Andric .add(Info.Callee) 197*81ad6265SDimitry Andric .addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv)); 198*81ad6265SDimitry Andric 199*81ad6265SDimitry Andric CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg); 200*81ad6265SDimitry Andric OutgoingValueAssigner Assigner(AssignFn); 201*81ad6265SDimitry Andric M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB); 202*81ad6265SDimitry Andric if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder, 203*81ad6265SDimitry Andric Info.CallConv, Info.IsVarArg)) 204349cc55cSDimitry Andric return false; 205*81ad6265SDimitry Andric 206*81ad6265SDimitry Andric if (Info.Callee.isReg()) 207*81ad6265SDimitry Andric constrainOperandRegClass(MF, *TRI, MRI, *STI.getInstrInfo(), 208*81ad6265SDimitry Andric *STI.getRegBankInfo(), *MIB, MIB->getDesc(), 209*81ad6265SDimitry Andric Info.Callee, 0); 210*81ad6265SDimitry Andric 211*81ad6265SDimitry Andric MIRBuilder.insertInstr(MIB); 212*81ad6265SDimitry Andric 213*81ad6265SDimitry Andric if (!Info.OrigRet.Ty->isVoidTy()) { 214*81ad6265SDimitry Andric CCAssignFn *RetAssignFn = 215*81ad6265SDimitry Andric TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg); 216*81ad6265SDimitry Andric 217*81ad6265SDimitry Andric OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn); 218*81ad6265SDimitry Andric CallReturnHandler Handler(MIRBuilder, MRI, MIB); 219*81ad6265SDimitry Andric if (!determineAndHandleAssignments(Handler, Assigner, InArgs, MIRBuilder, 220*81ad6265SDimitry Andric Info.CallConv, Info.IsVarArg)) 221*81ad6265SDimitry Andric return false; 222*81ad6265SDimitry Andric } 223*81ad6265SDimitry Andric 224*81ad6265SDimitry Andric CallSeqStart.addImm(Assigner.StackOffset).addImm(0); 225*81ad6265SDimitry Andric 226*81ad6265SDimitry Andric unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); 227*81ad6265SDimitry Andric MIRBuilder.buildInstr(AdjStackUp).addImm(Assigner.StackOffset).addImm(0); 228*81ad6265SDimitry Andric 229*81ad6265SDimitry Andric return true; 230349cc55cSDimitry Andric } 231349cc55cSDimitry Andric 232349cc55cSDimitry Andric bool M68kCallLowering::enableBigEndian() const { return true; } 233