1// Copyright 2014 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#if V8_TARGET_ARCH_PPC
6
7#include "src/interface-descriptors.h"
8
9namespace v8 {
10namespace internal {
11
12const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
13
14void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
15    CallInterfaceDescriptorData* data, int register_parameter_count) {
16  const Register default_stub_registers[] = {r3, r4, r5, r6, r7};
17  CHECK_LE(static_cast<size_t>(register_parameter_count),
18           arraysize(default_stub_registers));
19  data->InitializePlatformSpecific(register_parameter_count,
20                                   default_stub_registers);
21}
22
23const Register FastNewFunctionContextDescriptor::FunctionRegister() {
24  return r4;
25}
26const Register FastNewFunctionContextDescriptor::SlotsRegister() { return r3; }
27
28const Register LoadDescriptor::ReceiverRegister() { return r4; }
29const Register LoadDescriptor::NameRegister() { return r5; }
30const Register LoadDescriptor::SlotRegister() { return r3; }
31
32const Register LoadWithVectorDescriptor::VectorRegister() { return r6; }
33
34const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r7; }
35
36const Register StoreDescriptor::ReceiverRegister() { return r4; }
37const Register StoreDescriptor::NameRegister() { return r5; }
38const Register StoreDescriptor::ValueRegister() { return r3; }
39const Register StoreDescriptor::SlotRegister() { return r7; }
40
41const Register StoreWithVectorDescriptor::VectorRegister() { return r6; }
42
43const Register StoreTransitionDescriptor::SlotRegister() { return r7; }
44const Register StoreTransitionDescriptor::VectorRegister() { return r6; }
45const Register StoreTransitionDescriptor::MapRegister() { return r8; }
46
47const Register StringCompareDescriptor::LeftRegister() { return r4; }
48const Register StringCompareDescriptor::RightRegister() { return r3; }
49
50const Register ApiGetterDescriptor::HolderRegister() { return r3; }
51const Register ApiGetterDescriptor::CallbackRegister() { return r6; }
52
53const Register MathPowTaggedDescriptor::exponent() { return r5; }
54
55
56const Register MathPowIntegerDescriptor::exponent() {
57  return MathPowTaggedDescriptor::exponent();
58}
59
60
61const Register GrowArrayElementsDescriptor::ObjectRegister() { return r3; }
62const Register GrowArrayElementsDescriptor::KeyRegister() { return r6; }
63
64void FastNewClosureDescriptor::InitializePlatformSpecific(
65    CallInterfaceDescriptorData* data) {
66  Register registers[] = {r4, r5, r6};
67  data->InitializePlatformSpecific(arraysize(registers), registers);
68}
69
70
71// static
72const Register TypeConversionDescriptor::ArgumentRegister() { return r3; }
73
74void TypeofDescriptor::InitializePlatformSpecific(
75    CallInterfaceDescriptorData* data) {
76  Register registers[] = {r6};
77  data->InitializePlatformSpecific(arraysize(registers), registers);
78}
79
80
81void FastCloneRegExpDescriptor::InitializePlatformSpecific(
82    CallInterfaceDescriptorData* data) {
83  Register registers[] = {r6, r5, r4, r3};
84  data->InitializePlatformSpecific(arraysize(registers), registers);
85}
86
87
88void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
89    CallInterfaceDescriptorData* data) {
90  Register registers[] = {r6, r5, r4};
91  data->InitializePlatformSpecific(arraysize(registers), registers);
92}
93
94
95void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
96    CallInterfaceDescriptorData* data) {
97  Register registers[] = {r6, r5, r4, r3};
98  data->InitializePlatformSpecific(arraysize(registers), registers);
99}
100
101
102void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
103    CallInterfaceDescriptorData* data) {
104  Register registers[] = {r5, r6};
105  data->InitializePlatformSpecific(arraysize(registers), registers);
106}
107
108
109void CreateWeakCellDescriptor::InitializePlatformSpecific(
110    CallInterfaceDescriptorData* data) {
111  Register registers[] = {r5, r6, r4};
112  data->InitializePlatformSpecific(arraysize(registers), registers);
113}
114
115
116void CallFunctionDescriptor::InitializePlatformSpecific(
117    CallInterfaceDescriptorData* data) {
118  Register registers[] = {r4};
119  data->InitializePlatformSpecific(arraysize(registers), registers);
120}
121
122void CallICTrampolineDescriptor::InitializePlatformSpecific(
123    CallInterfaceDescriptorData* data) {
124  Register registers[] = {r4, r3, r6};
125  data->InitializePlatformSpecific(arraysize(registers), registers);
126}
127
128void CallICDescriptor::InitializePlatformSpecific(
129    CallInterfaceDescriptorData* data) {
130  Register registers[] = {r4, r3, r6, r5};
131  data->InitializePlatformSpecific(arraysize(registers), registers);
132}
133
134
135void CallConstructDescriptor::InitializePlatformSpecific(
136    CallInterfaceDescriptorData* data) {
137  // r3 : number of arguments
138  // r4 : the function to call
139  // r5 : feedback vector
140  // r6 : slot in feedback vector (Smi, for RecordCallTarget)
141  // r7 : new target (for IsSuperConstructorCall)
142  // TODO(turbofan): So far we don't gather type feedback and hence skip the
143  // slot parameter, but ArrayConstructStub needs the vector to be undefined.
144  Register registers[] = {r3, r4, r7, r5};
145  data->InitializePlatformSpecific(arraysize(registers), registers);
146}
147
148
149void CallTrampolineDescriptor::InitializePlatformSpecific(
150    CallInterfaceDescriptorData* data) {
151  // r3 : number of arguments
152  // r4 : the target to call
153  Register registers[] = {r4, r3};
154  data->InitializePlatformSpecific(arraysize(registers), registers);
155}
156
157void CallForwardVarargsDescriptor::InitializePlatformSpecific(
158    CallInterfaceDescriptorData* data) {
159  // r5 : start index (to support rest parameters)
160  // r4 : the target to call
161  Register registers[] = {r4, r5};
162  data->InitializePlatformSpecific(arraysize(registers), registers);
163}
164
165void ConstructStubDescriptor::InitializePlatformSpecific(
166    CallInterfaceDescriptorData* data) {
167  // r3 : number of arguments
168  // r4 : the target to call
169  // r6 : the new target
170  // r5 : allocation site or undefined
171  Register registers[] = {r4, r6, r3, r5};
172  data->InitializePlatformSpecific(arraysize(registers), registers);
173}
174
175
176void ConstructTrampolineDescriptor::InitializePlatformSpecific(
177    CallInterfaceDescriptorData* data) {
178  // r3 : number of arguments
179  // r4 : the target to call
180  // r6 : the new target
181  Register registers[] = {r4, r6, r3};
182  data->InitializePlatformSpecific(arraysize(registers), registers);
183}
184
185
186void TransitionElementsKindDescriptor::InitializePlatformSpecific(
187    CallInterfaceDescriptorData* data) {
188  Register registers[] = {r3, r4};
189  data->InitializePlatformSpecific(arraysize(registers), registers);
190}
191
192
193void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
194    CallInterfaceDescriptorData* data) {
195  data->InitializePlatformSpecific(0, nullptr, nullptr);
196}
197
198void ArrayConstructorDescriptor::InitializePlatformSpecific(
199    CallInterfaceDescriptorData* data) {
200  // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite
201  Register registers[] = {r4, r6, r3, r5};
202  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
203}
204
205void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
206    CallInterfaceDescriptorData* data) {
207  // register state
208  // r3 -- number of arguments
209  // r4 -- function
210  // r5 -- allocation site with elements kind
211  Register registers[] = {r4, r5, r3};
212  data->InitializePlatformSpecific(arraysize(registers), registers);
213}
214
215void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
216    CallInterfaceDescriptorData* data) {
217  // register state
218  // r3 -- number of arguments
219  // r4 -- function
220  // r5 -- allocation site with elements kind
221  Register registers[] = {r4, r5, r3};
222  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
223}
224
225
226void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
227    CallInterfaceDescriptorData* data) {
228  // stack param count needs (constructor pointer, and single argument)
229  Register registers[] = {r4, r5, r3};
230  data->InitializePlatformSpecific(arraysize(registers), registers);
231}
232
233
234void VarArgFunctionDescriptor::InitializePlatformSpecific(
235    CallInterfaceDescriptorData* data) {
236  // stack param count needs (arg count)
237  Register registers[] = {r3};
238  data->InitializePlatformSpecific(arraysize(registers), registers);
239}
240
241void CompareDescriptor::InitializePlatformSpecific(
242    CallInterfaceDescriptorData* data) {
243  Register registers[] = {r4, r3};
244  data->InitializePlatformSpecific(arraysize(registers), registers);
245}
246
247
248void BinaryOpDescriptor::InitializePlatformSpecific(
249    CallInterfaceDescriptorData* data) {
250  Register registers[] = {r4, r3};
251  data->InitializePlatformSpecific(arraysize(registers), registers);
252}
253
254
255void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
256    CallInterfaceDescriptorData* data) {
257  Register registers[] = {r5, r4, r3};
258  data->InitializePlatformSpecific(arraysize(registers), registers);
259}
260
261void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
262    CallInterfaceDescriptorData* data) {
263  // register state
264  // r4 -- lhs
265  // r3 -- rhs
266  // r7 -- slot id
267  // r6 -- vector
268  Register registers[] = {r4, r3, r7, r6};
269  data->InitializePlatformSpecific(arraysize(registers), registers);
270}
271
272void CountOpDescriptor::InitializePlatformSpecific(
273    CallInterfaceDescriptorData* data) {
274  Register registers[] = {r4};
275  data->InitializePlatformSpecific(arraysize(registers), registers);
276}
277
278void StringAddDescriptor::InitializePlatformSpecific(
279    CallInterfaceDescriptorData* data) {
280  Register registers[] = {r4, r3};
281  data->InitializePlatformSpecific(arraysize(registers), registers);
282}
283
284
285void KeyedDescriptor::InitializePlatformSpecific(
286    CallInterfaceDescriptorData* data) {
287  Register registers[] = {
288      r5,  // key
289  };
290  data->InitializePlatformSpecific(arraysize(registers), registers);
291}
292
293
294void NamedDescriptor::InitializePlatformSpecific(
295    CallInterfaceDescriptorData* data) {
296  Register registers[] = {
297      r5,  // name
298  };
299  data->InitializePlatformSpecific(arraysize(registers), registers);
300}
301
302
303void CallHandlerDescriptor::InitializePlatformSpecific(
304    CallInterfaceDescriptorData* data) {
305  Register registers[] = {
306      r3,  // receiver
307  };
308  data->InitializePlatformSpecific(arraysize(registers), registers);
309}
310
311
312void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
313    CallInterfaceDescriptorData* data) {
314  Register registers[] = {
315      r4,  // JSFunction
316      r6,  // the new target
317      r3,  // actual number of arguments
318      r5,  // expected number of arguments
319  };
320  data->InitializePlatformSpecific(arraysize(registers), registers);
321}
322
323void ApiCallbackDescriptor::InitializePlatformSpecific(
324    CallInterfaceDescriptorData* data) {
325  Register registers[] = {
326      r3,  // callee
327      r7,  // call_data
328      r5,  // holder
329      r4,  // api_function_address
330  };
331  data->InitializePlatformSpecific(arraysize(registers), registers);
332}
333
334void InterpreterDispatchDescriptor::InitializePlatformSpecific(
335    CallInterfaceDescriptorData* data) {
336  Register registers[] = {
337  kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
338  kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
339  data->InitializePlatformSpecific(arraysize(registers), registers);
340}
341
342void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
343    CallInterfaceDescriptorData* data) {
344  Register registers[] = {
345      r3,  // argument count (not including receiver)
346      r5,  // address of first argument
347      r4   // the target callable to be call
348  };
349  data->InitializePlatformSpecific(arraysize(registers), registers);
350}
351
352void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
353    CallInterfaceDescriptorData* data) {
354  Register registers[] = {
355      r3,  // argument count (not including receiver)
356      r6,  // new target
357      r4,  // constructor to call
358      r5,  // allocation site feedback if available, undefined otherwise
359      r7   // address of the first argument
360  };
361  data->InitializePlatformSpecific(arraysize(registers), registers);
362}
363
364void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
365    CallInterfaceDescriptorData* data) {
366  Register registers[] = {
367      r3,  // argument count (not including receiver)
368      r4,  // target to call checked to be Array function
369      r5,  // allocation site feedback if available, undefined otherwise
370      r6   // address of the first argument
371  };
372  data->InitializePlatformSpecific(arraysize(registers), registers);
373}
374
375void InterpreterCEntryDescriptor::InitializePlatformSpecific(
376    CallInterfaceDescriptorData* data) {
377  Register registers[] = {
378      r3,  // argument count (argc)
379      r5,  // address of first argument (argv)
380      r4   // the runtime function to call
381  };
382  data->InitializePlatformSpecific(arraysize(registers), registers);
383}
384
385void ResumeGeneratorDescriptor::InitializePlatformSpecific(
386    CallInterfaceDescriptorData* data) {
387  Register registers[] = {
388      r3,  // the value to pass to the generator
389      r4,  // the JSGeneratorObject to resume
390      r5   // the resume mode (tagged)
391  };
392  data->InitializePlatformSpecific(arraysize(registers), registers);
393}
394
395void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
396    CallInterfaceDescriptorData* data) {
397  Register registers[] = {
398      r4,  // loaded new FP
399  };
400  data->InitializePlatformSpecific(arraysize(registers), registers);
401}
402
403}  // namespace internal
404}  // namespace v8
405
406#endif  // V8_TARGET_ARCH_PPC
407