LLVM 23.0.0git
M68kCallLowering.cpp
Go to the documentation of this file.
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"
25
26using namespace llvm;
27
28namespace {
29
30struct M68kFormalArgHandler : public M68kIncomingValueHandler {
31 M68kFormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
32 : M68kIncomingValueHandler(MIRBuilder, MRI) {}
33};
34
35struct CallReturnHandler : public M68kIncomingValueHandler {
36 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
37 MachineInstrBuilder &MIB)
38 : M68kIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
39
40private:
41 void assignValueToReg(Register ValVReg, Register PhysReg,
42 const CCValAssign &VA,
43 ISD::ArgFlagsTy Flags = {}) override;
44
45 MachineInstrBuilder &MIB;
46};
47
48} // end anonymous namespace
49
52
59
60 void assignValueToReg(Register ValVReg, Register PhysReg,
61 const CCValAssign &VA,
62 ISD::ArgFlagsTy Flags = {}) override {
63 MIB.addUse(PhysReg, RegState::Implicit);
64 Register ExtReg = extendRegister(ValVReg, VA);
65 MIRBuilder.buildCopy(PhysReg, ExtReg);
66 }
67
68 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
69 const MachinePointerInfo &MPO,
70 const CCValAssign &VA) override {
71 MachineFunction &MF = MIRBuilder.getMF();
72 Register ExtReg = extendRegister(ValVReg, VA);
73
74 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,
75 inferAlignFromPtrInfo(MF, MPO));
76 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
77 }
78
81 ISD::ArgFlagsTy Flags) override {
82 LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0));
83 LLT SType = LLT::scalar(DL.getPointerSizeInBits(0));
84 Register StackReg = STI.getRegisterInfo()->getStackRegister();
85 auto SPReg = MIRBuilder.buildCopy(p0, StackReg).getReg(0);
86 auto OffsetReg = MIRBuilder.buildConstant(SType, Offset);
87 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
89 return AddrReg.getReg(0);
90 }
92 const DataLayout &DL;
94};
96 const Value *Val, ArrayRef<Register> VRegs,
98 Register SwiftErrorVReg) const {
99
100 auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);
101 bool Success = true;
102 MachineFunction &MF = MIRBuilder.getMF();
103 const Function &F = MF.getFunction();
106 CCAssignFn *AssignFn =
107 TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());
108 auto &DL = F.getDataLayout();
109 if (!VRegs.empty()) {
110 SmallVector<ArgInfo, 8> SplitArgs;
111 ArgInfo OrigArg{VRegs, Val->getType(), 0};
112 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
113 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
114 OutgoingValueAssigner ArgAssigner(AssignFn);
115 M68kOutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
116 Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
117 MIRBuilder, F.getCallingConv(),
118 F.isVarArg());
119 }
120 MIRBuilder.insertInstr(MIB);
121 return Success;
122}
123
125 const Function &F,
127 FunctionLoweringInfo &FLI) const {
128 MachineFunction &MF = MIRBuilder.getMF();
130 const auto &DL = F.getDataLayout();
131 auto &TLI = *getTLI<M68kTargetLowering>();
132
133 SmallVector<ArgInfo, 8> SplitArgs;
134 unsigned I = 0;
135 for (const auto &Arg : F.args()) {
136 ArgInfo OrigArg{VRegs[I], Arg.getType(), I};
137 setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);
138 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
139 ++I;
140 }
141
142 CCAssignFn *AssignFn =
143 TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());
144 IncomingValueAssigner ArgAssigner(AssignFn);
145 M68kFormalArgHandler ArgHandler(MIRBuilder, MRI);
146 return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
147 MIRBuilder, F.getCallingConv(),
148 F.isVarArg());
149}
150
151void M68kIncomingValueHandler::assignValueToReg(Register ValVReg,
152 Register PhysReg,
153 const CCValAssign &VA,
154 ISD::ArgFlagsTy Flags) {
155 MIRBuilder.getMRI()->addLiveIn(PhysReg);
156 MIRBuilder.getMBB().addLiveIn(PhysReg);
157 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
158}
159
160void M68kIncomingValueHandler::assignValueToAddress(
161 Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
162 const CCValAssign &VA) {
164 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
165 inferAlignFromPtrInfo(MF, MPO));
166 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
167}
168
169Register M68kIncomingValueHandler::getStackAddress(uint64_t Size,
170 int64_t Offset,
172 ISD::ArgFlagsTy Flags) {
173 auto &MFI = MIRBuilder.getMF().getFrameInfo();
174 const bool IsImmutable = !Flags.isByVal();
175 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
177
178 // Build Frame Index
179 llvm::LLT FramePtr = LLT::pointer(
180 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());
181 MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);
182 StackUsed = std::max(StackUsed, Size + Offset);
183 return AddrReg.getReg(0);
184}
185
186void CallReturnHandler::assignValueToReg(Register ValVReg, Register PhysReg,
187 const CCValAssign &VA,
188 ISD::ArgFlagsTy Flags) {
189 MIB.addDef(PhysReg, RegState::Implicit);
190 MIRBuilder.buildCopy(ValVReg, PhysReg);
191}
192
194 CallLoweringInfo &Info) const {
195 MachineFunction &MF = MIRBuilder.getMF();
196 Function &F = MF.getFunction();
198 auto &DL = F.getDataLayout();
200 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
201 const TargetInstrInfo &TII = *STI.getInstrInfo();
202 const M68kRegisterInfo *TRI = STI.getRegisterInfo();
203
205 for (auto &OrigArg : Info.OrigArgs)
206 splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);
207
209 if (!Info.OrigRet.Ty->isVoidTy())
210 splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
211
212 unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
213 auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown);
214
215 unsigned Opc = TLI.getTargetMachine().isPositionIndependent() ? M68k::CALLq
216 : Info.Callee.isReg() ? M68k::CALLj
217 : M68k::CALLb;
218
219 auto MIB = MIRBuilder.buildInstrNoInsert(Opc)
220 .add(Info.Callee)
221 .addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
222
223 CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg);
224 OutgoingValueAssigner Assigner(AssignFn);
225 M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
226 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
227 Info.CallConv, Info.IsVarArg))
228 return false;
229
230 if (Info.Callee.isReg())
231 constrainOperandRegClass(MF, *TRI, MRI, *STI.getInstrInfo(),
232 *STI.getRegBankInfo(), *MIB, MIB->getDesc(),
233 Info.Callee, 0);
234
235 MIRBuilder.insertInstr(MIB);
236
237 if (!Info.OrigRet.Ty->isVoidTy()) {
238 CCAssignFn *RetAssignFn =
239 TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg);
240
241 OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn);
242 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
243 if (!determineAndHandleAssignments(Handler, Assigner, InArgs, MIRBuilder,
244 Info.CallConv, Info.IsVarArg))
245 return false;
246 }
247
248 CallSeqStart.addImm(Assigner.StackSize).addImm(0);
249
250 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
251 MIRBuilder.buildInstr(AdjStackUp).addImm(Assigner.StackSize).addImm(0);
252
253 return true;
254}
255
256bool M68kCallLowering::enableBigEndian() const { return true; }
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file describes how to lower LLVM calls to machine code calls.
const HexagonInstrInfo * TII
This file implements the lowering of LLVM calls to machine code calls for GlobalISel.
This file defines the interfaces that M68k uses to lower LLVM code into a selection DAG.
This file contains the M68k implementation of the TargetInstrInfo class.
This file declares the M68k specific subclass of TargetSubtargetInfo.
This file declares the M68k specific subclass of TargetMachine.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static constexpr MCPhysReg SPReg
static const unsigned FramePtr
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
CCValAssign - Represent assignment of one arg/retval to a location.
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< TypeSize > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs={}) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
CallLowering(const TargetLowering *TLI)
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override
This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...
M68kCallLowering(const M68kTargetLowering &TLI)
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI, Register SwiftErrorVReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
bool enableBigEndian() const override
For targets which want to use big-endian can enable it with enableBigEndian() hook.
const RegisterBankInfo * getRegBankInfo() const override
const M68kInstrInfo * getInstrInfo() const override
const M68kRegisterInfo * getRegisterInfo() const override
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition Utils.cpp:56
@ Implicit
Not emitted register (e.g. carry, or temporary result).
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Success
The lock was released successfully.
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition Utils.cpp:900
MachineInstrBuilder MIB
Register getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO, ISD::ArgFlagsTy Flags) override
Materialize a VReg containing the address of the specified stack-based object.
M68kOutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstrBuilder MIB)
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO, const CCValAssign &VA) override
The specified value has been assigned to a stack location.
const M68kSubtarget & STI
void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA, ISD::ArgFlagsTy Flags={}) override
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
uint64_t StackSize
The size of the currently allocated portion of the stack.
Register extendRegister(Register ValReg, const CCValAssign &VA, unsigned MaxSizeBits=0)
Extend a register to the location type given in VA, capped at extending to at most MaxSize bits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.