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