Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp
35294 views
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/MachineFrameInfo.h"
24
#include "llvm/CodeGen/TargetCallingConv.h"
25
26
using namespace llvm;
27
28
namespace {
29
30
struct M68kFormalArgHandler : public M68kIncomingValueHandler {
31
M68kFormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
32
: M68kIncomingValueHandler(MIRBuilder, MRI) {}
33
};
34
35
struct CallReturnHandler : public M68kIncomingValueHandler {
36
CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
37
MachineInstrBuilder &MIB)
38
: M68kIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
39
40
private:
41
void assignValueToReg(Register ValVReg, Register PhysReg,
42
const CCValAssign &VA) override;
43
44
MachineInstrBuilder &MIB;
45
};
46
47
} // end anonymous namespace
48
49
M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI)
50
: CallLowering(&TLI) {}
51
52
struct M68kOutgoingArgHandler : public CallLowering::OutgoingValueHandler {
53
M68kOutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
54
MachineInstrBuilder MIB)
55
: OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB),
56
DL(MIRBuilder.getMF().getDataLayout()),
57
STI(MIRBuilder.getMF().getSubtarget<M68kSubtarget>()) {}
58
59
void assignValueToReg(Register ValVReg, Register PhysReg,
60
const CCValAssign &VA) override {
61
MIB.addUse(PhysReg, RegState::Implicit);
62
Register ExtReg = extendRegister(ValVReg, VA);
63
MIRBuilder.buildCopy(PhysReg, ExtReg);
64
}
65
66
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
67
const MachinePointerInfo &MPO,
68
const CCValAssign &VA) override {
69
MachineFunction &MF = MIRBuilder.getMF();
70
Register ExtReg = extendRegister(ValVReg, VA);
71
72
auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,
73
inferAlignFromPtrInfo(MF, MPO));
74
MIRBuilder.buildStore(ExtReg, Addr, *MMO);
75
}
76
77
Register getStackAddress(uint64_t Size, int64_t Offset,
78
MachinePointerInfo &MPO,
79
ISD::ArgFlagsTy Flags) override {
80
LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0));
81
LLT SType = LLT::scalar(DL.getPointerSizeInBits(0));
82
Register StackReg = STI.getRegisterInfo()->getStackRegister();
83
auto SPReg = MIRBuilder.buildCopy(p0, StackReg).getReg(0);
84
auto OffsetReg = MIRBuilder.buildConstant(SType, Offset);
85
auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
86
MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
87
return AddrReg.getReg(0);
88
}
89
MachineInstrBuilder MIB;
90
const DataLayout &DL;
91
const M68kSubtarget &STI;
92
};
93
bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
94
const Value *Val, ArrayRef<Register> VRegs,
95
FunctionLoweringInfo &FLI,
96
Register SwiftErrorVReg) const {
97
98
auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);
99
bool Success = true;
100
MachineFunction &MF = MIRBuilder.getMF();
101
const Function &F = MF.getFunction();
102
MachineRegisterInfo &MRI = MF.getRegInfo();
103
const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();
104
CCAssignFn *AssignFn =
105
TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());
106
auto &DL = F.getDataLayout();
107
if (!VRegs.empty()) {
108
SmallVector<ArgInfo, 8> SplitArgs;
109
ArgInfo OrigArg{VRegs, Val->getType(), 0};
110
setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
111
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
112
OutgoingValueAssigner ArgAssigner(AssignFn);
113
M68kOutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
114
Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
115
MIRBuilder, F.getCallingConv(),
116
F.isVarArg());
117
}
118
MIRBuilder.insertInstr(MIB);
119
return Success;
120
}
121
122
bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
123
const Function &F,
124
ArrayRef<ArrayRef<Register>> VRegs,
125
FunctionLoweringInfo &FLI) const {
126
MachineFunction &MF = MIRBuilder.getMF();
127
MachineRegisterInfo &MRI = MF.getRegInfo();
128
const auto &DL = F.getDataLayout();
129
auto &TLI = *getTLI<M68kTargetLowering>();
130
131
SmallVector<ArgInfo, 8> SplitArgs;
132
unsigned I = 0;
133
for (const auto &Arg : F.args()) {
134
ArgInfo OrigArg{VRegs[I], Arg.getType(), I};
135
setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
136
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
137
++I;
138
}
139
140
CCAssignFn *AssignFn =
141
TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());
142
IncomingValueAssigner ArgAssigner(AssignFn);
143
M68kFormalArgHandler ArgHandler(MIRBuilder, MRI);
144
return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
145
MIRBuilder, F.getCallingConv(),
146
F.isVarArg());
147
}
148
149
void M68kIncomingValueHandler::assignValueToReg(Register ValVReg,
150
Register PhysReg,
151
const CCValAssign &VA) {
152
MIRBuilder.getMRI()->addLiveIn(PhysReg);
153
MIRBuilder.getMBB().addLiveIn(PhysReg);
154
IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
155
}
156
157
void M68kIncomingValueHandler::assignValueToAddress(
158
Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
159
const CCValAssign &VA) {
160
MachineFunction &MF = MIRBuilder.getMF();
161
auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
162
inferAlignFromPtrInfo(MF, MPO));
163
MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
164
}
165
166
Register M68kIncomingValueHandler::getStackAddress(uint64_t Size,
167
int64_t Offset,
168
MachinePointerInfo &MPO,
169
ISD::ArgFlagsTy Flags) {
170
auto &MFI = MIRBuilder.getMF().getFrameInfo();
171
const bool IsImmutable = !Flags.isByVal();
172
int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
173
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
174
175
// Build Frame Index
176
llvm::LLT FramePtr = LLT::pointer(
177
0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());
178
MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);
179
StackUsed = std::max(StackUsed, Size + Offset);
180
return AddrReg.getReg(0);
181
}
182
183
void CallReturnHandler::assignValueToReg(Register ValVReg, Register PhysReg,
184
const CCValAssign &VA) {
185
MIB.addDef(PhysReg, RegState::Implicit);
186
MIRBuilder.buildCopy(ValVReg, PhysReg);
187
}
188
189
bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
190
CallLoweringInfo &Info) const {
191
MachineFunction &MF = MIRBuilder.getMF();
192
Function &F = MF.getFunction();
193
MachineRegisterInfo &MRI = MF.getRegInfo();
194
auto &DL = F.getDataLayout();
195
const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();
196
const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
197
const TargetInstrInfo &TII = *STI.getInstrInfo();
198
const M68kRegisterInfo *TRI = STI.getRegisterInfo();
199
200
SmallVector<ArgInfo, 8> OutArgs;
201
for (auto &OrigArg : Info.OrigArgs)
202
splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);
203
204
SmallVector<ArgInfo, 8> InArgs;
205
if (!Info.OrigRet.Ty->isVoidTy())
206
splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
207
208
unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
209
auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown);
210
211
unsigned Opc = TLI.getTargetMachine().isPositionIndependent() ? M68k::CALLq
212
: Info.Callee.isReg() ? M68k::CALLj
213
: M68k::CALLb;
214
215
auto MIB = MIRBuilder.buildInstrNoInsert(Opc)
216
.add(Info.Callee)
217
.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
218
219
CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg);
220
OutgoingValueAssigner Assigner(AssignFn);
221
M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
222
if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
223
Info.CallConv, Info.IsVarArg))
224
return false;
225
226
if (Info.Callee.isReg())
227
constrainOperandRegClass(MF, *TRI, MRI, *STI.getInstrInfo(),
228
*STI.getRegBankInfo(), *MIB, MIB->getDesc(),
229
Info.Callee, 0);
230
231
MIRBuilder.insertInstr(MIB);
232
233
if (!Info.OrigRet.Ty->isVoidTy()) {
234
CCAssignFn *RetAssignFn =
235
TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg);
236
237
OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn);
238
CallReturnHandler Handler(MIRBuilder, MRI, MIB);
239
if (!determineAndHandleAssignments(Handler, Assigner, InArgs, MIRBuilder,
240
Info.CallConv, Info.IsVarArg))
241
return false;
242
}
243
244
CallSeqStart.addImm(Assigner.StackSize).addImm(0);
245
246
unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
247
MIRBuilder.buildInstr(AdjStackUp).addImm(Assigner.StackSize).addImm(0);
248
249
return true;
250
}
251
252
bool M68kCallLowering::enableBigEndian() const { return true; }
253
254