1 //===-- SystemZCallingConv.h - Calling conventions for SystemZ --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZCALLINGCONV_H
11 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZCALLINGCONV_H
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/CodeGen/CallingConvLower.h"
15 #include "llvm/MC/MCRegisterInfo.h"
19 const unsigned NumArgGPRs
= 5;
20 extern const MCPhysReg ArgGPRs
[NumArgGPRs
];
22 const unsigned NumArgFPRs
= 4;
23 extern const MCPhysReg ArgFPRs
[NumArgFPRs
];
24 } // end namespace SystemZ
26 class SystemZCCState
: public CCState
{
28 /// Records whether the value was a fixed argument.
29 /// See ISD::OutputArg::IsFixed.
30 SmallVector
<bool, 4> ArgIsFixed
;
32 /// Records whether the value was widened from a short vector type.
33 SmallVector
<bool, 4> ArgIsShortVector
;
35 // Check whether ArgVT is a short vector type.
36 bool IsShortVectorType(EVT ArgVT
) {
37 return ArgVT
.isVector() && ArgVT
.getStoreSize() <= 8;
41 SystemZCCState(CallingConv::ID CC
, bool isVarArg
, MachineFunction
&MF
,
42 SmallVectorImpl
<CCValAssign
> &locs
, LLVMContext
&C
)
43 : CCState(CC
, isVarArg
, MF
, locs
, C
) {}
45 void AnalyzeFormalArguments(const SmallVectorImpl
<ISD::InputArg
> &Ins
,
47 // Formal arguments are always fixed.
49 for (unsigned i
= 0; i
< Ins
.size(); ++i
)
50 ArgIsFixed
.push_back(true);
51 // Record whether the call operand was a short vector.
52 ArgIsShortVector
.clear();
53 for (unsigned i
= 0; i
< Ins
.size(); ++i
)
54 ArgIsShortVector
.push_back(IsShortVectorType(Ins
[i
].ArgVT
));
56 CCState::AnalyzeFormalArguments(Ins
, Fn
);
59 void AnalyzeCallOperands(const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
61 // Record whether the call operand was a fixed argument.
63 for (unsigned i
= 0; i
< Outs
.size(); ++i
)
64 ArgIsFixed
.push_back(Outs
[i
].IsFixed
);
65 // Record whether the call operand was a short vector.
66 ArgIsShortVector
.clear();
67 for (unsigned i
= 0; i
< Outs
.size(); ++i
)
68 ArgIsShortVector
.push_back(IsShortVectorType(Outs
[i
].ArgVT
));
70 CCState::AnalyzeCallOperands(Outs
, Fn
);
73 // This version of AnalyzeCallOperands in the base class is not usable
74 // since we must provide a means of accessing ISD::OutputArg::IsFixed.
75 void AnalyzeCallOperands(const SmallVectorImpl
<MVT
> &Outs
,
76 SmallVectorImpl
<ISD::ArgFlagsTy
> &Flags
,
77 CCAssignFn Fn
) = delete;
79 bool IsFixed(unsigned ValNo
) { return ArgIsFixed
[ValNo
]; }
80 bool IsShortVector(unsigned ValNo
) { return ArgIsShortVector
[ValNo
]; }
83 // Handle i128 argument types. These need to be passed by implicit
84 // reference. This could be as simple as the following .td line:
85 // CCIfType<[i128], CCPassIndirect<i64>>,
86 // except that i128 is not a legal type, and therefore gets split by
87 // common code into a pair of i64 arguments.
88 inline bool CC_SystemZ_I128Indirect(unsigned &ValNo
, MVT
&ValVT
,
90 CCValAssign::LocInfo
&LocInfo
,
91 ISD::ArgFlagsTy
&ArgFlags
,
93 SmallVectorImpl
<CCValAssign
> &PendingMembers
= State
.getPendingLocs();
95 // ArgFlags.isSplit() is true on the first part of a i128 argument;
96 // PendingMembers.empty() is false on all subsequent parts.
97 if (!ArgFlags
.isSplit() && PendingMembers
.empty())
100 // Push a pending Indirect value location for each part.
102 LocInfo
= CCValAssign::Indirect
;
103 PendingMembers
.push_back(CCValAssign::getPending(ValNo
, ValVT
,
105 if (!ArgFlags
.isSplitEnd())
108 // OK, we've collected all parts in the pending list. Allocate
109 // the location (register or stack slot) for the indirect pointer.
110 // (This duplicates the usual i64 calling convention rules.)
111 unsigned Reg
= State
.AllocateReg(SystemZ::ArgGPRs
);
112 unsigned Offset
= Reg
? 0 : State
.AllocateStack(8, 8);
114 // Use that same location for all the pending parts.
115 for (auto &It
: PendingMembers
) {
117 It
.convertToReg(Reg
);
119 It
.convertToMem(Offset
);
123 PendingMembers
.clear();
128 } // end namespace llvm