1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_CODEGEN_PPC_INTERFACE_DESCRIPTORS_PPC_INL_H_
6 #define V8_CODEGEN_PPC_INTERFACE_DESCRIPTORS_PPC_INL_H_
7 
8 #if V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
9 
10 #include "src/codegen/interface-descriptors.h"
11 #include "src/execution/frames.h"
12 
13 namespace v8 {
14 namespace internal {
15 
DefaultRegisterArray()16 constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
17   auto registers = RegisterArray(r3, r4, r5, r6, r7);
18   STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
19   return registers;
20 }
21 
22 #if DEBUG
23 template <typename DerivedDescriptor>
24 void StaticCallInterfaceDescriptor<DerivedDescriptor>::
VerifyArgumentRegisterCount(CallInterfaceDescriptorData * data,int argc)25     VerifyArgumentRegisterCount(CallInterfaceDescriptorData* data, int argc) {
26   RegList allocatable_regs = data->allocatable_registers();
27   if (argc >= 1) DCHECK(allocatable_regs | r3.bit());
28   if (argc >= 2) DCHECK(allocatable_regs | r4.bit());
29   if (argc >= 3) DCHECK(allocatable_regs | r5.bit());
30   if (argc >= 4) DCHECK(allocatable_regs | r6.bit());
31   if (argc >= 5) DCHECK(allocatable_regs | r7.bit());
32   if (argc >= 6) DCHECK(allocatable_regs | r8.bit());
33   if (argc >= 7) DCHECK(allocatable_regs | r9.bit());
34   if (argc >= 8) DCHECK(allocatable_regs | r10.bit());
35   // Additional arguments are passed on the stack.
36 }
37 #endif  // DEBUG
38 
39 // static
registers()40 constexpr auto WriteBarrierDescriptor::registers() {
41   return RegisterArray(r4, r8, r7, r5, r3);
42 }
43 
44 // static
registers()45 constexpr auto DynamicCheckMapsDescriptor::registers() {
46   STATIC_ASSERT(kReturnRegister0 == r3);
47   return RegisterArray(r3, r4, r5, r6, cp);
48 }
49 
50 // static
registers()51 constexpr auto DynamicCheckMapsWithFeedbackVectorDescriptor::registers() {
52   STATIC_ASSERT(kReturnRegister0 == r3);
53   return RegisterArray(r3, r4, r5, r6, cp);
54 }
55 
56 // static
ReceiverRegister()57 constexpr Register LoadDescriptor::ReceiverRegister() { return r4; }
58 // static
NameRegister()59 constexpr Register LoadDescriptor::NameRegister() { return r5; }
60 // static
SlotRegister()61 constexpr Register LoadDescriptor::SlotRegister() { return r3; }
62 
63 // static
VectorRegister()64 constexpr Register LoadWithVectorDescriptor::VectorRegister() { return r6; }
65 
66 // static
67 constexpr Register
LookupStartObjectRegister()68 LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
69   return r7;
70 }
71 
72 // static
ReceiverRegister()73 constexpr Register StoreDescriptor::ReceiverRegister() { return r4; }
74 // static
NameRegister()75 constexpr Register StoreDescriptor::NameRegister() { return r5; }
76 // static
ValueRegister()77 constexpr Register StoreDescriptor::ValueRegister() { return r3; }
78 // static
SlotRegister()79 constexpr Register StoreDescriptor::SlotRegister() { return r7; }
80 
81 // static
VectorRegister()82 constexpr Register StoreWithVectorDescriptor::VectorRegister() { return r6; }
83 
84 // static
MapRegister()85 constexpr Register StoreTransitionDescriptor::MapRegister() { return r8; }
86 
87 // static
HolderRegister()88 constexpr Register ApiGetterDescriptor::HolderRegister() { return r3; }
89 // static
CallbackRegister()90 constexpr Register ApiGetterDescriptor::CallbackRegister() { return r6; }
91 
92 // static
ObjectRegister()93 constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return r3; }
94 // static
KeyRegister()95 constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return r6; }
96 
97 // static
ParamsSizeRegister()98 constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
99   // TODO(v8:11421): Implement on this platform.
100   return r6;
101 }
102 // static
WeightRegister()103 constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
104   // TODO(v8:11421): Implement on this platform.
105   return r7;
106 }
107 
108 // static
109 // static
ArgumentRegister()110 constexpr Register TypeConversionDescriptor::ArgumentRegister() { return r3; }
111 
112 // static
registers()113 constexpr auto TypeofDescriptor::registers() { return RegisterArray(r6); }
114 
115 // static
registers()116 constexpr auto CallTrampolineDescriptor::registers() {
117   // r3 : number of arguments
118   // r4 : the target to call
119   return RegisterArray(r4, r3);
120 }
121 
122 // static
registers()123 constexpr auto CallVarargsDescriptor::registers() {
124   // r3 : number of arguments (on the stack, not including receiver)
125   // r4 : the target to call
126   // r7 : arguments list length (untagged)
127   // r5 : arguments list (FixedArray)
128   return RegisterArray(r4, r3, r7, r5);
129 }
130 
131 // static
registers()132 constexpr auto CallForwardVarargsDescriptor::registers() {
133   // r3 : number of arguments
134   // r5 : start index (to support rest parameters)
135   // r4 : the target to call
136   return RegisterArray(r4, r3, r5);
137 }
138 
139 // static
registers()140 constexpr auto CallFunctionTemplateDescriptor::registers() {
141   // r4 : function template info
142   // r5 : number of arguments (on the stack, not including receiver)
143   return RegisterArray(r4, r5);
144 }
145 
146 // static
registers()147 constexpr auto CallWithSpreadDescriptor::registers() {
148   // r3 : number of arguments (on the stack, not including receiver)
149   // r4 : the target to call
150   // r5 : the object to spread
151   return RegisterArray(r4, r3, r5);
152 }
153 
154 // static
registers()155 constexpr auto CallWithArrayLikeDescriptor::registers() {
156   // r4 : the target to call
157   // r5 : the arguments list
158   return RegisterArray(r4, r5);
159 }
160 
161 // static
registers()162 constexpr auto ConstructVarargsDescriptor::registers() {
163   // r3 : number of arguments (on the stack, not including receiver)
164   // r4 : the target to call
165   // r6 : the new target
166   // r7 : arguments list length (untagged)
167   // r5 : arguments list (FixedArray)
168   return RegisterArray(r4, r6, r3, r7, r5);
169 }
170 
171 // static
registers()172 constexpr auto ConstructForwardVarargsDescriptor::registers() {
173   // r3 : number of arguments
174   // r6 : the new target
175   // r5 : start index (to support rest parameters)
176   // r4 : the target to call
177   return RegisterArray(r4, r6, r3, r5);
178 }
179 
180 // static
registers()181 constexpr auto ConstructWithSpreadDescriptor::registers() {
182   // r3 : number of arguments (on the stack, not including receiver)
183   // r4 : the target to call
184   // r6 : the new target
185   // r5 : the object to spread
186   return RegisterArray(r4, r6, r3, r5);
187 }
188 
189 // static
registers()190 constexpr auto ConstructWithArrayLikeDescriptor::registers() {
191   // r4 : the target to call
192   // r6 : the new target
193   // r5 : the arguments list
194   return RegisterArray(r4, r6, r5);
195 }
196 
197 // static
registers()198 constexpr auto ConstructStubDescriptor::registers() {
199   // r3 : number of arguments
200   // r4 : the target to call
201   // r6 : the new target
202   // r5 : allocation site or undefined
203   return RegisterArray(r4, r6, r3, r5);
204 }
205 
206 // static
registers()207 constexpr auto AbortDescriptor::registers() { return RegisterArray(r4); }
208 
209 // static
registers()210 constexpr auto CompareDescriptor::registers() { return RegisterArray(r4, r3); }
211 
212 // static
registers()213 constexpr auto Compare_BaselineDescriptor::registers() {
214   // TODO(v8:11421): Implement on this platform.
215   return DefaultRegisterArray();
216 }
217 
218 // static
registers()219 constexpr auto BinaryOpDescriptor::registers() { return RegisterArray(r4, r3); }
220 
221 // static
registers()222 constexpr auto BinaryOp_BaselineDescriptor::registers() {
223   // TODO(v8:11421): Implement on this platform.
224   return DefaultRegisterArray();
225 }
226 
227 // static
registers()228 constexpr auto ApiCallbackDescriptor::registers() {
229   return RegisterArray(r4,   // kApiFunctionAddress
230                        r5,   // kArgc
231                        r6,   // kCallData
232                        r3);  // kHolder
233 }
234 
235 // static
registers()236 constexpr auto InterpreterDispatchDescriptor::registers() {
237   return RegisterArray(
238       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
239       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
240 }
241 
242 // static
registers()243 constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
244   return RegisterArray(r3,   // argument count (not including receiver)
245                        r5,   // address of first argument
246                        r4);  // the target callable to be call
247 }
248 
249 // static
registers()250 constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
251   return RegisterArray(
252       r3,   // argument count (not including receiver)
253       r7,   // address of the first argument
254       r4,   // constructor to call
255       r6,   // new target
256       r5);  // allocation site feedback if available, undefined otherwise
257 }
258 
259 // static
registers()260 constexpr auto ResumeGeneratorDescriptor::registers() {
261   return RegisterArray(r3,   // the value to pass to the generator
262                        r4);  // the JSGeneratorObject to resume
263 }
264 
265 // static
registers()266 constexpr auto RunMicrotasksEntryDescriptor::registers() {
267   return RegisterArray(r3, r4);
268 }
269 
270 }  // namespace internal
271 }  // namespace v8
272 
273 #endif  // V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
274 
275 #endif  // V8_CODEGEN_PPC_INTERFACE_DESCRIPTORS_PPC_INL_H_
276