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 
11 namespace v8 {
12 namespace internal {
13 
ContextRegister()14 const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
15 
16 
ReceiverRegister()17 const Register LoadDescriptor::ReceiverRegister() { return x1; }
NameRegister()18 const Register LoadDescriptor::NameRegister() { return x2; }
19 
20 
SlotRegister()21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; }
22 
23 
VectorRegister()24 const Register VectorLoadICDescriptor::VectorRegister() { return x3; }
25 
26 
ReceiverRegister()27 const Register StoreDescriptor::ReceiverRegister() { return x1; }
NameRegister()28 const Register StoreDescriptor::NameRegister() { return x2; }
ValueRegister()29 const Register StoreDescriptor::ValueRegister() { return x0; }
30 
31 
MapRegister()32 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; }
33 
34 
left()35 const Register InstanceofDescriptor::left() {
36   // Object to check (instanceof lhs).
37   return x11;
38 }
39 
40 
right()41 const Register InstanceofDescriptor::right() {
42   // Constructor function (instanceof rhs).
43   return x10;
44 }
45 
46 
index()47 const Register ArgumentsAccessReadDescriptor::index() { return x1; }
parameter_count()48 const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
49 
50 
function_address()51 const Register ApiGetterDescriptor::function_address() { return x2; }
52 
53 
exponent()54 const Register MathPowTaggedDescriptor::exponent() { return x11; }
55 
56 
exponent()57 const Register MathPowIntegerDescriptor::exponent() { return x12; }
58 
59 
Initialize(CallInterfaceDescriptorData * data)60 void 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 
Initialize(CallInterfaceDescriptorData * data)68 void 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 
Initialize(CallInterfaceDescriptorData * data)76 void 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 
Initialize(CallInterfaceDescriptorData * data)84 void 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 
Initialize(CallInterfaceDescriptorData * data)92 void 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 
Initialize(CallInterfaceDescriptorData * data)106 void 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 
Initialize(CallInterfaceDescriptorData * data)118 void 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 
Initialize(CallInterfaceDescriptorData * data)128 void StoreArrayLiteralElementDescriptor::Initialize(
129     CallInterfaceDescriptorData* data) {
130   Register registers[] = {cp, x3, x0};
131   data->Initialize(arraysize(registers), registers, NULL);
132 }
133 
134 
Initialize(CallInterfaceDescriptorData * data)135 void 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 
Initialize(CallInterfaceDescriptorData * data)142 void 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 
Initialize(CallInterfaceDescriptorData * data)152 void 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 
Initialize(CallInterfaceDescriptorData * data)164 void 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 
Initialize(CallInterfaceDescriptorData * data)175 void 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 
Initialize(CallInterfaceDescriptorData * data)185 void 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 
Initialize(CallInterfaceDescriptorData * data)196 void 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 
Initialize(CallInterfaceDescriptorData * data)206 void 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 
Initialize(CallInterfaceDescriptorData * data)216 void 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 
Initialize(CallInterfaceDescriptorData * data)227 void 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 
Initialize(CallInterfaceDescriptorData * data)235 void 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 
Initialize(CallInterfaceDescriptorData * data)243 void 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 
Initialize(CallInterfaceDescriptorData * data)252 void 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 
Initialize(CallInterfaceDescriptorData * data)263 void 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 
Initialize(CallInterfaceDescriptorData * data)272 void 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 
Initialize(CallInterfaceDescriptorData * data)289 void 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 
Initialize(CallInterfaceDescriptorData * data)306 void 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 
Initialize(CallInterfaceDescriptorData * data)323 void 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 
Initialize(CallInterfaceDescriptorData * data)344 void 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