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#include "src/v8.h"
6
7#if V8_TARGET_ARCH_ARM64
8
9#include "src/interface-descriptors.h"
10
11namespace v8 {
12namespace internal {
13
14const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
15
16
17const Register LoadDescriptor::ReceiverRegister() { return x1; }
18const Register LoadDescriptor::NameRegister() { return x2; }
19
20
21const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; }
22
23
24const Register VectorLoadICDescriptor::VectorRegister() { return x3; }
25
26
27const Register StoreDescriptor::ReceiverRegister() { return x1; }
28const Register StoreDescriptor::NameRegister() { return x2; }
29const Register StoreDescriptor::ValueRegister() { return x0; }
30
31
32const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; }
33
34
35const Register InstanceofDescriptor::left() {
36  // Object to check (instanceof lhs).
37  return x11;
38}
39
40
41const Register InstanceofDescriptor::right() {
42  // Constructor function (instanceof rhs).
43  return x10;
44}
45
46
47const Register ArgumentsAccessReadDescriptor::index() { return x1; }
48const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
49
50
51const Register ApiGetterDescriptor::function_address() { return x2; }
52
53
54const Register MathPowTaggedDescriptor::exponent() { return x11; }
55
56
57const Register MathPowIntegerDescriptor::exponent() { return x12; }
58
59
60void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
61  // cp: context
62  // x2: function info
63  Register registers[] = {cp, x2};
64  data->Initialize(arraysize(registers), registers, NULL);
65}
66
67
68void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
69  // cp: context
70  // x1: function
71  Register registers[] = {cp, x1};
72  data->Initialize(arraysize(registers), registers, NULL);
73}
74
75
76void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
77  // cp: context
78  // x0: value
79  Register registers[] = {cp, x0};
80  data->Initialize(arraysize(registers), registers, NULL);
81}
82
83
84void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
85  // cp: context
86  // x0: value
87  Register registers[] = {cp, x0};
88  data->Initialize(arraysize(registers), registers, NULL);
89}
90
91
92void FastCloneShallowArrayDescriptor::Initialize(
93    CallInterfaceDescriptorData* data) {
94  // cp: context
95  // x3: array literals array
96  // x2: array literal index
97  // x1: constant elements
98  Register registers[] = {cp, x3, x2, x1};
99  Representation representations[] = {
100      Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
101      Representation::Tagged()};
102  data->Initialize(arraysize(registers), registers, representations);
103}
104
105
106void FastCloneShallowObjectDescriptor::Initialize(
107    CallInterfaceDescriptorData* data) {
108  // cp: context
109  // x3: object literals array
110  // x2: object literal index
111  // x1: constant properties
112  // x0: object literal flags
113  Register registers[] = {cp, x3, x2, x1, x0};
114  data->Initialize(arraysize(registers), registers, NULL);
115}
116
117
118void CreateAllocationSiteDescriptor::Initialize(
119    CallInterfaceDescriptorData* data) {
120  // cp: context
121  // x2: feedback vector
122  // x3: call feedback slot
123  Register registers[] = {cp, x2, x3};
124  data->Initialize(arraysize(registers), registers, NULL);
125}
126
127
128void StoreArrayLiteralElementDescriptor::Initialize(
129    CallInterfaceDescriptorData* data) {
130  Register registers[] = {cp, x3, x0};
131  data->Initialize(arraysize(registers), registers, NULL);
132}
133
134
135void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
136  // x1  function    the function to call
137  Register registers[] = {cp, x1};
138  data->Initialize(arraysize(registers), registers, NULL);
139}
140
141
142void CallFunctionWithFeedbackDescriptor::Initialize(
143    CallInterfaceDescriptorData* data) {
144  Register registers[] = {cp, x1, x3};
145  Representation representations[] = {Representation::Tagged(),
146                                      Representation::Tagged(),
147                                      Representation::Smi()};
148  data->Initialize(arraysize(registers), registers, representations);
149}
150
151
152void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
153  // x0 : number of arguments
154  // x1 : the function to call
155  // x2 : feedback vector
156  // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
157  // TODO(turbofan): So far we don't gather type feedback and hence skip the
158  // slot parameter, but ArrayConstructStub needs the vector to be undefined.
159  Register registers[] = {cp, x0, x1, x2};
160  data->Initialize(arraysize(registers), registers, NULL);
161}
162
163
164void RegExpConstructResultDescriptor::Initialize(
165    CallInterfaceDescriptorData* data) {
166  // cp: context
167  // x2: length
168  // x1: index (of last match)
169  // x0: string
170  Register registers[] = {cp, x2, x1, x0};
171  data->Initialize(arraysize(registers), registers, NULL);
172}
173
174
175void TransitionElementsKindDescriptor::Initialize(
176    CallInterfaceDescriptorData* data) {
177  // cp: context
178  // x0: value (js_array)
179  // x1: to_map
180  Register registers[] = {cp, x0, x1};
181  data->Initialize(arraysize(registers), registers, NULL);
182}
183
184
185void ArrayConstructorConstantArgCountDescriptor::Initialize(
186    CallInterfaceDescriptorData* data) {
187  // cp: context
188  // x1: function
189  // x2: allocation site with elements kind
190  // x0: number of arguments to the constructor function
191  Register registers[] = {cp, x1, x2};
192  data->Initialize(arraysize(registers), registers, NULL);
193}
194
195
196void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
197  // stack param count needs (constructor pointer, and single argument)
198  Register registers[] = {cp, x1, x2, x0};
199  Representation representations[] = {
200      Representation::Tagged(), Representation::Tagged(),
201      Representation::Tagged(), Representation::Integer32()};
202  data->Initialize(arraysize(registers), registers, representations);
203}
204
205
206void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
207    CallInterfaceDescriptorData* data) {
208  // cp: context
209  // x1: constructor function
210  // x0: number of arguments to the constructor function
211  Register registers[] = {cp, x1};
212  data->Initialize(arraysize(registers), registers, NULL);
213}
214
215
216void InternalArrayConstructorDescriptor::Initialize(
217    CallInterfaceDescriptorData* data) {
218  // stack param count needs (constructor pointer, and single argument)
219  Register registers[] = {cp, x1, x0};
220  Representation representations[] = {Representation::Tagged(),
221                                      Representation::Tagged(),
222                                      Representation::Integer32()};
223  data->Initialize(arraysize(registers), registers, representations);
224}
225
226
227void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
228  // cp: context
229  // x0: value to compare
230  Register registers[] = {cp, x0};
231  data->Initialize(arraysize(registers), registers, NULL);
232}
233
234
235void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
236  // cp: context
237  // x0: value
238  Register registers[] = {cp, x0};
239  data->Initialize(arraysize(registers), registers, NULL);
240}
241
242
243void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
244  // cp: context
245  // x1: left operand
246  // x0: right operand
247  Register registers[] = {cp, x1, x0};
248  data->Initialize(arraysize(registers), registers, NULL);
249}
250
251
252void BinaryOpWithAllocationSiteDescriptor::Initialize(
253    CallInterfaceDescriptorData* data) {
254  // cp: context
255  // x2: allocation site
256  // x1: left operand
257  // x0: right operand
258  Register registers[] = {cp, x2, x1, x0};
259  data->Initialize(arraysize(registers), registers, NULL);
260}
261
262
263void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
264  // cp: context
265  // x1: left operand
266  // x0: right operand
267  Register registers[] = {cp, x1, x0};
268  data->Initialize(arraysize(registers), registers, NULL);
269}
270
271
272void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
273  static PlatformInterfaceDescriptor noInlineDescriptor =
274      PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
275
276  Register registers[] = {
277      cp,  // context
278      x2,  // key
279  };
280  Representation representations[] = {
281      Representation::Tagged(),  // context
282      Representation::Tagged(),  // key
283  };
284  data->Initialize(arraysize(registers), registers, representations,
285                   &noInlineDescriptor);
286}
287
288
289void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
290  static PlatformInterfaceDescriptor noInlineDescriptor =
291      PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
292
293  Register registers[] = {
294      cp,  // context
295      x2,  // name
296  };
297  Representation representations[] = {
298      Representation::Tagged(),  // context
299      Representation::Tagged(),  // name
300  };
301  data->Initialize(arraysize(registers), registers, representations,
302                   &noInlineDescriptor);
303}
304
305
306void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
307  static PlatformInterfaceDescriptor default_descriptor =
308      PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
309
310  Register registers[] = {
311      cp,  // context
312      x0,  // receiver
313  };
314  Representation representations[] = {
315      Representation::Tagged(),  // context
316      Representation::Tagged(),  // receiver
317  };
318  data->Initialize(arraysize(registers), registers, representations,
319                   &default_descriptor);
320}
321
322
323void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
324  static PlatformInterfaceDescriptor default_descriptor =
325      PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
326
327  Register registers[] = {
328      cp,  // context
329      x1,  // JSFunction
330      x0,  // actual number of arguments
331      x2,  // expected number of arguments
332  };
333  Representation representations[] = {
334      Representation::Tagged(),     // context
335      Representation::Tagged(),     // JSFunction
336      Representation::Integer32(),  // actual number of arguments
337      Representation::Integer32(),  // expected number of arguments
338  };
339  data->Initialize(arraysize(registers), registers, representations,
340                   &default_descriptor);
341}
342
343
344void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
345  static PlatformInterfaceDescriptor default_descriptor =
346      PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
347
348  Register registers[] = {
349      cp,  // context
350      x0,  // callee
351      x4,  // call_data
352      x2,  // holder
353      x1,  // api_function_address
354  };
355  Representation representations[] = {
356      Representation::Tagged(),    // context
357      Representation::Tagged(),    // callee
358      Representation::Tagged(),    // call_data
359      Representation::Tagged(),    // holder
360      Representation::External(),  // api_function_address
361  };
362  data->Initialize(arraysize(registers), registers, representations,
363                   &default_descriptor);
364}
365}
366}  // namespace v8::internal
367
368#endif  // V8_TARGET_ARCH_ARM64
369