1 //===-- PPCCallingConv.h - --------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "PPCRegisterInfo.h"
10 #include "PPCCallingConv.h"
11 #include "PPCSubtarget.h"
12 #include "PPCCCState.h"
15 inline bool CC_PPC_AnyReg_Error(unsigned &, MVT
&, MVT
&,
16 CCValAssign::LocInfo
&, ISD::ArgFlagsTy
&,
18 llvm_unreachable("The AnyReg calling convention is only supported by the " \
19 "stackmap and patchpoint intrinsics.");
20 // gracefully fallback to PPC C calling convention on Release builds.
24 static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo
, MVT
&ValVT
, MVT
&LocVT
,
25 CCValAssign::LocInfo
&LocInfo
,
26 ISD::ArgFlagsTy
&ArgFlags
,
31 static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo
, MVT
&ValVT
,
33 CCValAssign::LocInfo
&LocInfo
,
34 ISD::ArgFlagsTy
&ArgFlags
,
36 static const MCPhysReg ArgRegs
[] = {
37 PPC::R3
, PPC::R4
, PPC::R5
, PPC::R6
,
38 PPC::R7
, PPC::R8
, PPC::R9
, PPC::R10
,
40 const unsigned NumArgRegs
= array_lengthof(ArgRegs
);
42 unsigned RegNum
= State
.getFirstUnallocated(ArgRegs
);
44 // Skip one register if the first unallocated register has an even register
45 // number and there are still argument registers available which have not been
46 // allocated yet. RegNum is actually an index into ArgRegs, which means we
47 // need to skip a register if RegNum is odd.
48 if (RegNum
!= NumArgRegs
&& RegNum
% 2 == 1) {
49 State
.AllocateReg(ArgRegs
[RegNum
]);
52 // Always return false here, as this function only makes sure that the first
53 // unallocated register has an odd register number and does not actually
54 // allocate a register for the current argument.
58 static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(
59 unsigned &ValNo
, MVT
&ValVT
, MVT
&LocVT
, CCValAssign::LocInfo
&LocInfo
,
60 ISD::ArgFlagsTy
&ArgFlags
, CCState
&State
) {
61 static const MCPhysReg ArgRegs
[] = {
62 PPC::R3
, PPC::R4
, PPC::R5
, PPC::R6
,
63 PPC::R7
, PPC::R8
, PPC::R9
, PPC::R10
,
65 const unsigned NumArgRegs
= array_lengthof(ArgRegs
);
67 unsigned RegNum
= State
.getFirstUnallocated(ArgRegs
);
68 int RegsLeft
= NumArgRegs
- RegNum
;
70 // Skip if there is not enough registers left for long double type (4 gpr regs
71 // in soft float mode) and put long double argument on the stack.
72 if (RegNum
!= NumArgRegs
&& RegsLeft
< 4) {
73 for (int i
= 0; i
< RegsLeft
; i
++) {
74 State
.AllocateReg(ArgRegs
[RegNum
+ i
]);
81 static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo
, MVT
&ValVT
,
83 CCValAssign::LocInfo
&LocInfo
,
84 ISD::ArgFlagsTy
&ArgFlags
,
86 static const MCPhysReg ArgRegs
[] = {
87 PPC::F1
, PPC::F2
, PPC::F3
, PPC::F4
, PPC::F5
, PPC::F6
, PPC::F7
,
91 const unsigned NumArgRegs
= array_lengthof(ArgRegs
);
93 unsigned RegNum
= State
.getFirstUnallocated(ArgRegs
);
95 // If there is only one Floating-point register left we need to put both f64
96 // values of a split ppc_fp128 value on the stack.
97 if (RegNum
!= NumArgRegs
&& ArgRegs
[RegNum
] == PPC::F8
) {
98 State
.AllocateReg(ArgRegs
[RegNum
]);
101 // Always return false here, as this function only makes sure that the two f64
102 // values a ppc_fp128 value is split into are both passed in registers or both
103 // passed on the stack and does not actually allocate a register for the
108 // Split F64 arguments into two 32-bit consecutive registers.
109 static bool CC_PPC32_SPE_CustomSplitFP64(unsigned &ValNo
, MVT
&ValVT
,
111 CCValAssign::LocInfo
&LocInfo
,
112 ISD::ArgFlagsTy
&ArgFlags
,
114 static const MCPhysReg HiRegList
[] = { PPC::R3
, PPC::R5
, PPC::R7
, PPC::R9
};
115 static const MCPhysReg LoRegList
[] = { PPC::R4
, PPC::R6
, PPC::R8
, PPC::R10
};
117 // Try to get the first register.
118 unsigned Reg
= State
.AllocateReg(HiRegList
);
123 for (i
= 0; i
< sizeof(HiRegList
) / sizeof(HiRegList
[0]); ++i
)
124 if (HiRegList
[i
] == Reg
)
127 unsigned T
= State
.AllocateReg(LoRegList
[i
]);
129 assert(T
== LoRegList
[i
] && "Could not allocate register");
131 State
.addLoc(CCValAssign::getCustomReg(ValNo
, ValVT
, Reg
, LocVT
, LocInfo
));
132 State
.addLoc(CCValAssign::getCustomReg(ValNo
, ValVT
, LoRegList
[i
],
137 // Same as above, but for return values, so only allocate for R3 and R4
138 static bool CC_PPC32_SPE_RetF64(unsigned &ValNo
, MVT
&ValVT
,
140 CCValAssign::LocInfo
&LocInfo
,
141 ISD::ArgFlagsTy
&ArgFlags
,
143 static const MCPhysReg HiRegList
[] = { PPC::R3
};
144 static const MCPhysReg LoRegList
[] = { PPC::R4
};
146 // Try to get the first register.
147 unsigned Reg
= State
.AllocateReg(HiRegList
, LoRegList
);
152 for (i
= 0; i
< sizeof(HiRegList
) / sizeof(HiRegList
[0]); ++i
)
153 if (HiRegList
[i
] == Reg
)
156 State
.addLoc(CCValAssign::getCustomReg(ValNo
, ValVT
, Reg
, LocVT
, LocInfo
));
157 State
.addLoc(CCValAssign::getCustomReg(ValNo
, ValVT
, LoRegList
[i
],
162 #include "PPCGenCallingConv.inc"