LLVM 22.0.0git
SystemZCallingConv.h
Go to the documentation of this file.
1//===-- SystemZCallingConv.h - Calling conventions for SystemZ --*- 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#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZCALLINGCONV_H
10#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZCALLINGCONV_H
11
12#include "SystemZSubtarget.h"
16
17namespace llvm {
18namespace SystemZ {
19 const unsigned ELFNumArgGPRs = 5;
21
22 const unsigned ELFNumArgFPRs = 4;
24
25 const unsigned XPLINK64NumArgGPRs = 3;
27
28 const unsigned XPLINK64NumArgFPRs = 4;
30} // end namespace SystemZ
31
32// Handle i128 argument types. These need to be passed by implicit
33// reference. This could be as simple as the following .td line:
34// CCIfType<[i128], CCPassIndirect<i64>>,
35// except that i128 is not a legal type, and therefore gets split by
36// common code into a pair of i64 arguments.
37inline bool CC_SystemZ_I128Indirect(unsigned &ValNo, MVT &ValVT,
38 MVT &LocVT,
39 CCValAssign::LocInfo &LocInfo,
40 ISD::ArgFlagsTy &ArgFlags,
41 CCState &State) {
42 SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
43
44 // ArgFlags.isSplit() is true on the first part of a i128 argument;
45 // PendingMembers.empty() is false on all subsequent parts.
46 if (!ArgFlags.isSplit() && PendingMembers.empty())
47 return false;
48
49 // Push a pending Indirect value location for each part.
50 LocVT = MVT::i64;
51 LocInfo = CCValAssign::Indirect;
52 PendingMembers.push_back(CCValAssign::getPending(ValNo, ValVT,
53 LocVT, LocInfo));
54 if (!ArgFlags.isSplitEnd())
55 return true;
56
57 // OK, we've collected all parts in the pending list. Allocate
58 // the location (register or stack slot) for the indirect pointer.
59 // (This duplicates the usual i64 calling convention rules.)
60 unsigned Reg;
61 const SystemZSubtarget &Subtarget =
63 if (Subtarget.isTargetELF())
65 else if (Subtarget.isTargetXPLINK64())
67 else
68 llvm_unreachable("Unknown Calling Convention!");
69
70 unsigned Offset = Reg && !Subtarget.isTargetXPLINK64()
71 ? 0
72 : State.AllocateStack(8, Align(8));
73
74 // Use that same location for all the pending parts.
75 for (auto &It : PendingMembers) {
76 if (Reg)
77 It.convertToReg(Reg);
78 else
79 It.convertToMem(Offset);
80 State.addLoc(It);
81 }
82
83 PendingMembers.clear();
84
85 return true;
86}
87
88// A pointer in 64bit mode is always passed as 64bit.
89inline bool CC_XPLINK64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
90 CCValAssign::LocInfo &LocInfo,
91 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
92 if (LocVT != MVT::i64) {
93 LocVT = MVT::i64;
94 LocInfo = CCValAssign::ZExt;
95 }
96 return false;
97}
98
99inline bool CC_XPLINK64_Shadow_Reg(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
100 CCValAssign::LocInfo &LocInfo,
101 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
102 if (LocVT == MVT::f32 || LocVT == MVT::f64) {
104 }
105 if (LocVT == MVT::f128 || LocVT.is128BitVector()) {
106 // Shadow next two GPRs, if available.
109
110 // Quad precision floating point needs to
111 // go inside pre-defined FPR pair.
112 if (LocVT == MVT::f128) {
113 for (unsigned I = 0; I < SystemZ::XPLINK64NumArgFPRs; I += 2)
116 }
117 }
118 return false;
119}
120
121inline bool CC_XPLINK64_Allocate128BitVararg(unsigned &ValNo, MVT &ValVT,
122 MVT &LocVT,
123 CCValAssign::LocInfo &LocInfo,
124 ISD::ArgFlagsTy &ArgFlags,
125 CCState &State) {
126 // For any C or C++ program, this should always be
127 // false, since it is illegal to have a function
128 // where the first argument is variadic. Therefore
129 // the first fixed argument should already have
130 // allocated GPR1 either through shadowing it or
131 // using it for parameter passing.
132 State.AllocateReg(SystemZ::R1D);
133
134 bool AllocGPR2 = State.AllocateReg(SystemZ::R2D);
135 bool AllocGPR3 = State.AllocateReg(SystemZ::R3D);
136
137 // If GPR2 and GPR3 are available, then we may pass vararg in R2Q.
138 // If only GPR3 is available, we need to set custom handling to copy
139 // hi bits into GPR3.
140 // Either way, we allocate on the stack.
141 if (AllocGPR3) {
142 // For f128 and vector var arg case, set the bitcast flag to bitcast to
143 // i128.
144 LocVT = MVT::i128;
145 LocInfo = CCValAssign::BCvt;
146 auto Offset = State.AllocateStack(16, Align(8));
147 if (AllocGPR2)
148 State.addLoc(
149 CCValAssign::getReg(ValNo, ValVT, SystemZ::R2Q, LocVT, LocInfo));
150 else
151 State.addLoc(
152 CCValAssign::getCustomMem(ValNo, ValVT, Offset, LocVT, LocInfo));
153 return true;
154 }
155
156 return false;
157}
158
159inline bool RetCC_SystemZ_Error(unsigned &, MVT &, MVT &,
161 CCState &) {
162 llvm_unreachable("Return value calling convention currently unsupported.");
163}
164
165inline bool CC_SystemZ_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &,
167 llvm_unreachable("Argument calling convention currently unsupported.");
168}
169
170inline bool CC_SystemZ_GHC_Error(unsigned &, MVT &, MVT &,
172 CCState &) {
173 report_fatal_error("No registers left in GHC calling convention");
174 return false;
175}
176
177} // end namespace llvm
178
179#endif
#define I(x, y, z)
Definition: MD5.cpp:58
Register Reg
This file defines the SmallVector class.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
SmallVectorImpl< CCValAssign > & getPendingLocs()
bool isAllocated(MCRegister Reg) const
isAllocated - Return true if the specified register (or an alias) is allocated.
void addLoc(const CCValAssign &V)
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool empty() const
Definition: SmallVector.h:82
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCPhysReg XPLINK64ArgFPRs[XPLINK64NumArgFPRs]
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
const unsigned XPLINK64NumArgFPRs
const unsigned XPLINK64NumArgGPRs
const MCPhysReg ELFArgGPRs[ELFNumArgGPRs]
const unsigned ELFNumArgGPRs
const unsigned ELFNumArgFPRs
const MCPhysReg XPLINK64ArgGPRs[XPLINK64NumArgGPRs]
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
bool CC_SystemZ_I128Indirect(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
bool CC_XPLINK64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
bool CC_XPLINK64_Allocate128BitVararg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
bool CC_SystemZ_GHC_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
bool RetCC_SystemZ_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &)
bool CC_SystemZ_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &)
bool CC_XPLINK64_Shadow_Reg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39