LLVM 18.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
29 : CallLowering(&TLI) {}
30
34 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB),
35 DL(MIRBuilder.getMF().getDataLayout()),
36 STI(MIRBuilder.getMF().getSubtarget<M68kSubtarget>()) {}
37
38 void assignValueToReg(Register ValVReg, Register PhysReg,
39 const CCValAssign &VA) override {
40 MIB.addUse(PhysReg, RegState::Implicit);
41 Register ExtReg = extendRegister(ValVReg, VA);
42 MIRBuilder.buildCopy(PhysReg, ExtReg);
43 }
44
46 const MachinePointerInfo &MPO,
47 const CCValAssign &VA) override {
48 MachineFunction &MF = MIRBuilder.getMF();
49 Register ExtReg = extendRegister(ValVReg, VA);
50
51 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,
52 inferAlignFromPtrInfo(MF, MPO));
53 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
54 }
55
58 ISD::ArgFlagsTy Flags) override {
59 LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0));
60 LLT SType = LLT::scalar(DL.getPointerSizeInBits(0));
61 Register StackReg = STI.getRegisterInfo()->getStackRegister();
62 auto SPReg = MIRBuilder.buildCopy(p0, StackReg).getReg(0);
63 auto OffsetReg = MIRBuilder.buildConstant(SType, Offset);
64 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
65 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
66 return AddrReg.getReg(0);
67 }
69 const DataLayout &DL;
71};
73 const Value *Val, ArrayRef<Register> VRegs,
75 Register SwiftErrorVReg) const {
76
77 auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);
78 bool Success = true;
79 MachineFunction &MF = MIRBuilder.getMF();
80 const Function &F = MF.getFunction();
82 const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();
83 CCAssignFn *AssignFn =
84 TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());
85 auto &DL = F.getParent()->getDataLayout();
86 if (!VRegs.empty()) {
88 ArgInfo OrigArg{VRegs, Val->getType(), 0};
90 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
91 OutgoingValueAssigner ArgAssigner(AssignFn);
92 M68kOutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
93 Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
94 MIRBuilder, F.getCallingConv(),
95 F.isVarArg());
96 }
97 MIRBuilder.insertInstr(MIB);
98 return Success;
99}
100
102 const Function &F,
104 FunctionLoweringInfo &FLI) const {
105 MachineFunction &MF = MIRBuilder.getMF();
107 const auto &DL = F.getParent()->getDataLayout();
108 auto &TLI = *getTLI<M68kTargetLowering>();
109
110 SmallVector<ArgInfo, 8> SplitArgs;
111 unsigned I = 0;
112 for (const auto &Arg : F.args()) {
113 ArgInfo OrigArg{VRegs[I], Arg.getType(), I};
115 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
116 ++I;
117 }
118
119 CCAssignFn *AssignFn =
120 TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());
121 IncomingValueAssigner ArgAssigner(AssignFn);
122 FormalArgHandler ArgHandler(MIRBuilder, MRI);
123 return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
124 MIRBuilder, F.getCallingConv(),
125 F.isVarArg());
126}
127
128void M68kIncomingValueHandler::assignValueToReg(Register ValVReg,
129 Register PhysReg,
130 const CCValAssign &VA) {
131 MIRBuilder.getMRI()->addLiveIn(PhysReg);
132 MIRBuilder.getMBB().addLiveIn(PhysReg);
133 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
134}
135
136void M68kIncomingValueHandler::assignValueToAddress(
137 Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
138 const CCValAssign &VA) {
140 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
141 inferAlignFromPtrInfo(MF, MPO));
142 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
143}
144
145Register M68kIncomingValueHandler::getStackAddress(uint64_t Size,
146 int64_t Offset,
148 ISD::ArgFlagsTy Flags) {
149 auto &MFI = MIRBuilder.getMF().getFrameInfo();
150 const bool IsImmutable = !Flags.isByVal();
151 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
153
154 // Build Frame Index
158 StackUsed = std::max(StackUsed, Size + Offset);
159 return AddrReg.getReg(0);
160}
161
162void CallReturnHandler::assignValueToReg(Register ValVReg, Register PhysReg,
163 const CCValAssign &VA) {
164 MIB.addDef(PhysReg, RegState::Implicit);
165 MIRBuilder.buildCopy(ValVReg, PhysReg);
166}
167
169 CallLoweringInfo &Info) const {
170 MachineFunction &MF = MIRBuilder.getMF();
171 Function &F = MF.getFunction();
173 auto &DL = F.getParent()->getDataLayout();
174 const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();
175 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
176 const TargetInstrInfo &TII = *STI.getInstrInfo();
177 const M68kRegisterInfo *TRI = STI.getRegisterInfo();
178
180 for (auto &OrigArg : Info.OrigArgs)
181 splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);
182
184 if (!Info.OrigRet.Ty->isVoidTy())
185 splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
186
187 unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
188 auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown);
189
190 unsigned Opc = TLI.getTargetMachine().isPositionIndependent() ? M68k::CALLq
191 : Info.Callee.isReg() ? M68k::CALLj
192 : M68k::CALLb;
193
194 auto MIB = MIRBuilder.buildInstrNoInsert(Opc)
195 .add(Info.Callee)
196 .addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
197
198 CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg);
199 OutgoingValueAssigner Assigner(AssignFn);
200 M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
201 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
202 Info.CallConv, Info.IsVarArg))
203 return false;
204
205 if (Info.Callee.isReg())
207 *STI.getRegBankInfo(), *MIB, MIB->getDesc(),
208 Info.Callee, 0);
209
210 MIRBuilder.insertInstr(MIB);
211
212 if (!Info.OrigRet.Ty->isVoidTy()) {
213 CCAssignFn *RetAssignFn =
214 TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg);
215
216 OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn);
217 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
218 if (!determineAndHandleAssignments(Handler, Assigner, InArgs, MIRBuilder,
219 Info.CallConv, Info.IsVarArg))
220 return false;
221 }
222
223 CallSeqStart.addImm(Assigner.StackSize).addImm(0);
224
225 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
226 MIRBuilder.buildInstr(AdjStackUp).addImm(Assigner.StackSize).addImm(0);
227
228 return true;
229}
230
231bool M68kCallLowering::enableBigEndian() const { return true; }
unsigned const MachineRegisterInfo * MRI
#define Success
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
This file describes how to lower LLVM calls to machine code calls.
uint64_t Addr
uint64_t Size
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:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
static const unsigned FramePtr
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
CCValAssign - Represent assignment of one arg/retval to a location.
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs=std::nullopt) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< uint64_t > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
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:110
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Definition: DataLayout.h:410
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".
Definition: LowLevelType.h:42
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelType.h:49
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
CCAssignFn * getCCAssignFn(CallingConv::ID CC, bool Return, bool IsVarArg) const
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, 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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
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>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
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>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
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
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
@ 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:19
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
TargetInstrInfo - Interface to description of machine instruction set.
const TargetMachine & getTargetMachine() const
bool isPositionIndependent() const
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
@ Implicit
Not emitted register (e.g. carry, or temporary result).
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
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:53
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition: Utils.cpp:716
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)
const DataLayout & DL
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) 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.
Definition: CallLowering.h:336
uint64_t StackSize
The size of the currently allocated portion of the stack.
Definition: CallLowering.h:206
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.