xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
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