/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/PowerPC/PPCCallingConv.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- PPCCallingConv.h - --------------------------------------*- 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 | | #include "PPCRegisterInfo.h" |
10 | | #include "PPCCallingConv.h" |
11 | | #include "PPCSubtarget.h" |
12 | | #include "PPCCCState.h" |
13 | | using namespace llvm; |
14 | | |
15 | | inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &, |
16 | | CCValAssign::LocInfo &, ISD::ArgFlagsTy &, |
17 | 0 | CCState &) { |
18 | 0 | llvm_unreachable("The AnyReg calling convention is only supported by the " \ |
19 | 0 | "stackmap and patchpoint intrinsics."); |
20 | 0 | // gracefully fallback to PPC C calling convention on Release builds. |
21 | 0 | return false; |
22 | 0 | } |
23 | | |
24 | | static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, |
25 | | CCValAssign::LocInfo &LocInfo, |
26 | | ISD::ArgFlagsTy &ArgFlags, |
27 | 2.87k | CCState &State) { |
28 | 2.87k | return true; |
29 | 2.87k | } |
30 | | |
31 | | static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, |
32 | | MVT &LocVT, |
33 | | CCValAssign::LocInfo &LocInfo, |
34 | | ISD::ArgFlagsTy &ArgFlags, |
35 | 309 | CCState &State) { |
36 | 309 | static const MCPhysReg ArgRegs[] = { |
37 | 309 | PPC::R3, PPC::R4, PPC::R5, PPC::R6, |
38 | 309 | PPC::R7, PPC::R8, PPC::R9, PPC::R10, |
39 | 309 | }; |
40 | 309 | const unsigned NumArgRegs = array_lengthof(ArgRegs); |
41 | 309 | |
42 | 309 | unsigned RegNum = State.getFirstUnallocated(ArgRegs); |
43 | 309 | |
44 | 309 | // Skip one register if the first unallocated register has an even register |
45 | 309 | // number and there are still argument registers available which have not been |
46 | 309 | // allocated yet. RegNum is actually an index into ArgRegs, which means we |
47 | 309 | // need to skip a register if RegNum is odd. |
48 | 309 | if (RegNum != NumArgRegs && RegNum % 2 == 1303 ) { |
49 | 29 | State.AllocateReg(ArgRegs[RegNum]); |
50 | 29 | } |
51 | 309 | |
52 | 309 | // Always return false here, as this function only makes sure that the first |
53 | 309 | // unallocated register has an odd register number and does not actually |
54 | 309 | // allocate a register for the current argument. |
55 | 309 | return false; |
56 | 309 | } |
57 | | |
58 | | static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128( |
59 | | unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, |
60 | 6 | ISD::ArgFlagsTy &ArgFlags, CCState &State) { |
61 | 6 | static const MCPhysReg ArgRegs[] = { |
62 | 6 | PPC::R3, PPC::R4, PPC::R5, PPC::R6, |
63 | 6 | PPC::R7, PPC::R8, PPC::R9, PPC::R10, |
64 | 6 | }; |
65 | 6 | const unsigned NumArgRegs = array_lengthof(ArgRegs); |
66 | 6 | |
67 | 6 | unsigned RegNum = State.getFirstUnallocated(ArgRegs); |
68 | 6 | int RegsLeft = NumArgRegs - RegNum; |
69 | 6 | |
70 | 6 | // Skip if there is not enough registers left for long double type (4 gpr regs |
71 | 6 | // in soft float mode) and put long double argument on the stack. |
72 | 6 | if (RegNum != NumArgRegs && RegsLeft < 4) { |
73 | 4 | for (int i = 0; i < RegsLeft; i++3 ) { |
74 | 3 | State.AllocateReg(ArgRegs[RegNum + i]); |
75 | 3 | } |
76 | 1 | } |
77 | 6 | |
78 | 6 | return false; |
79 | 6 | } |
80 | | |
81 | | static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, |
82 | | MVT &LocVT, |
83 | | CCValAssign::LocInfo &LocInfo, |
84 | | ISD::ArgFlagsTy &ArgFlags, |
85 | 98 | CCState &State) { |
86 | 98 | static const MCPhysReg ArgRegs[] = { |
87 | 98 | PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, |
88 | 98 | PPC::F8 |
89 | 98 | }; |
90 | 98 | |
91 | 98 | const unsigned NumArgRegs = array_lengthof(ArgRegs); |
92 | 98 | |
93 | 98 | unsigned RegNum = State.getFirstUnallocated(ArgRegs); |
94 | 98 | |
95 | 98 | // If there is only one Floating-point register left we need to put both f64 |
96 | 98 | // values of a split ppc_fp128 value on the stack. |
97 | 98 | if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) { |
98 | 0 | State.AllocateReg(ArgRegs[RegNum]); |
99 | 0 | } |
100 | 98 | |
101 | 98 | // Always return false here, as this function only makes sure that the two f64 |
102 | 98 | // values a ppc_fp128 value is split into are both passed in registers or both |
103 | 98 | // passed on the stack and does not actually allocate a register for the |
104 | 98 | // current argument. |
105 | 98 | return false; |
106 | 98 | } |
107 | | |
108 | | // Split F64 arguments into two 32-bit consecutive registers. |
109 | | static bool CC_PPC32_SPE_CustomSplitFP64(unsigned &ValNo, MVT &ValVT, |
110 | | MVT &LocVT, |
111 | | CCValAssign::LocInfo &LocInfo, |
112 | | ISD::ArgFlagsTy &ArgFlags, |
113 | 62 | CCState &State) { |
114 | 62 | static const MCPhysReg HiRegList[] = { PPC::R3, PPC::R5, PPC::R7, PPC::R9 }; |
115 | 62 | static const MCPhysReg LoRegList[] = { PPC::R4, PPC::R6, PPC::R8, PPC::R10 }; |
116 | 62 | |
117 | 62 | // Try to get the first register. |
118 | 62 | unsigned Reg = State.AllocateReg(HiRegList); |
119 | 62 | if (!Reg) |
120 | 0 | return false; |
121 | 62 | |
122 | 62 | unsigned i; |
123 | 89 | for (i = 0; i < sizeof(HiRegList) / sizeof(HiRegList[0]); ++i27 ) |
124 | 89 | if (HiRegList[i] == Reg) |
125 | 62 | break; |
126 | 62 | |
127 | 62 | unsigned T = State.AllocateReg(LoRegList[i]); |
128 | 62 | (void)T; |
129 | 62 | assert(T == LoRegList[i] && "Could not allocate register"); |
130 | 62 | |
131 | 62 | State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); |
132 | 62 | State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], |
133 | 62 | LocVT, LocInfo)); |
134 | 62 | return true; |
135 | 62 | } |
136 | | |
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, |
139 | | MVT &LocVT, |
140 | | CCValAssign::LocInfo &LocInfo, |
141 | | ISD::ArgFlagsTy &ArgFlags, |
142 | 26 | CCState &State) { |
143 | 26 | static const MCPhysReg HiRegList[] = { PPC::R3 }; |
144 | 26 | static const MCPhysReg LoRegList[] = { PPC::R4 }; |
145 | 26 | |
146 | 26 | // Try to get the first register. |
147 | 26 | unsigned Reg = State.AllocateReg(HiRegList, LoRegList); |
148 | 26 | if (!Reg) |
149 | 0 | return false; |
150 | 26 | |
151 | 26 | unsigned i; |
152 | 26 | for (i = 0; i < sizeof(HiRegList) / sizeof(HiRegList[0]); ++i0 ) |
153 | 26 | if (HiRegList[i] == Reg) |
154 | 26 | break; |
155 | 26 | |
156 | 26 | State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); |
157 | 26 | State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], |
158 | 26 | LocVT, LocInfo)); |
159 | 26 | return true; |
160 | 26 | } |
161 | | |
162 | | #include "PPCGenCallingConv.inc" |