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