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