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/arm64/interface-descriptors-arm64.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; }
SlotRegister()19 const Register LoadDescriptor::SlotRegister() { return x0; }
20
21
VectorRegister()22 const Register LoadWithVectorDescriptor::VectorRegister() { return x3; }
23
24
ReceiverRegister()25 const Register StoreDescriptor::ReceiverRegister() { return x1; }
NameRegister()26 const Register StoreDescriptor::NameRegister() { return x2; }
ValueRegister()27 const Register StoreDescriptor::ValueRegister() { return x0; }
28
29
SlotRegister()30 const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return x4; }
31
32
VectorRegister()33 const Register VectorStoreICDescriptor::VectorRegister() { return x3; }
34
35
SlotRegister()36 const Register VectorStoreTransitionDescriptor::SlotRegister() { return x4; }
VectorRegister()37 const Register VectorStoreTransitionDescriptor::VectorRegister() { return x3; }
MapRegister()38 const Register VectorStoreTransitionDescriptor::MapRegister() { return x5; }
39
40
MapRegister()41 const Register StoreTransitionDescriptor::MapRegister() { return x3; }
42
43
SlotRegister()44 const Register LoadGlobalViaContextDescriptor::SlotRegister() { return x2; }
45
46
SlotRegister()47 const Register StoreGlobalViaContextDescriptor::SlotRegister() { return x2; }
ValueRegister()48 const Register StoreGlobalViaContextDescriptor::ValueRegister() { return x0; }
49
50
LeftRegister()51 const Register InstanceOfDescriptor::LeftRegister() { return x1; }
RightRegister()52 const Register InstanceOfDescriptor::RightRegister() { return x0; }
53
54
LeftRegister()55 const Register StringCompareDescriptor::LeftRegister() { return x1; }
RightRegister()56 const Register StringCompareDescriptor::RightRegister() { return x0; }
57
58
index()59 const Register ArgumentsAccessReadDescriptor::index() { return x1; }
parameter_count()60 const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
61
62
function()63 const Register ArgumentsAccessNewDescriptor::function() { return x1; }
parameter_count()64 const Register ArgumentsAccessNewDescriptor::parameter_count() { return x2; }
parameter_pointer()65 const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return x3; }
66
67
parameter_count()68 const Register RestParamAccessDescriptor::parameter_count() { return x2; }
parameter_pointer()69 const Register RestParamAccessDescriptor::parameter_pointer() { return x3; }
rest_parameter_index()70 const Register RestParamAccessDescriptor::rest_parameter_index() { return x4; }
71
72
function_address()73 const Register ApiGetterDescriptor::function_address() { return x2; }
74
75
exponent()76 const Register MathPowTaggedDescriptor::exponent() { return x11; }
77
78
exponent()79 const Register MathPowIntegerDescriptor::exponent() { return x12; }
80
81
ObjectRegister()82 const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; }
KeyRegister()83 const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; }
84
85
InitializePlatformSpecific(CallInterfaceDescriptorData * data)86 void FastNewClosureDescriptor::InitializePlatformSpecific(
87 CallInterfaceDescriptorData* data) {
88 // x2: function info
89 Register registers[] = {x2};
90 data->InitializePlatformSpecific(arraysize(registers), registers);
91 }
92
93
InitializePlatformSpecific(CallInterfaceDescriptorData * data)94 void FastNewContextDescriptor::InitializePlatformSpecific(
95 CallInterfaceDescriptorData* data) {
96 // x1: function
97 Register registers[] = {x1};
98 data->InitializePlatformSpecific(arraysize(registers), registers);
99 }
100
101
InitializePlatformSpecific(CallInterfaceDescriptorData * data)102 void ToNumberDescriptor::InitializePlatformSpecific(
103 CallInterfaceDescriptorData* data) {
104 // x0: value
105 Register registers[] = {x0};
106 data->InitializePlatformSpecific(arraysize(registers), registers);
107 }
108
109
110 // static
ReceiverRegister()111 const Register ToLengthDescriptor::ReceiverRegister() { return x0; }
112
113
114 // static
ReceiverRegister()115 const Register ToStringDescriptor::ReceiverRegister() { return x0; }
116
117
118 // static
ReceiverRegister()119 const Register ToObjectDescriptor::ReceiverRegister() { return x0; }
120
121
InitializePlatformSpecific(CallInterfaceDescriptorData * data)122 void NumberToStringDescriptor::InitializePlatformSpecific(
123 CallInterfaceDescriptorData* data) {
124 // x0: value
125 Register registers[] = {x0};
126 data->InitializePlatformSpecific(arraysize(registers), registers);
127 }
128
129
InitializePlatformSpecific(CallInterfaceDescriptorData * data)130 void TypeofDescriptor::InitializePlatformSpecific(
131 CallInterfaceDescriptorData* data) {
132 Register registers[] = {x3};
133 data->InitializePlatformSpecific(arraysize(registers), registers);
134 }
135
136
InitializePlatformSpecific(CallInterfaceDescriptorData * data)137 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
138 CallInterfaceDescriptorData* data) {
139 // x3: closure
140 // x2: object literal index
141 // x1: constant properties
142 // x0: object literal flags
143 Register registers[] = {x3, x2, x1, x0};
144 data->InitializePlatformSpecific(arraysize(registers), registers);
145 }
146
147
InitializePlatformSpecific(CallInterfaceDescriptorData * data)148 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
149 CallInterfaceDescriptorData* data) {
150 // x3: closure
151 // x2: array literal index
152 // x1: constant elements
153 Register registers[] = {x3, x2, x1};
154 data->InitializePlatformSpecific(arraysize(registers), registers);
155 }
156
157
InitializePlatformSpecific(CallInterfaceDescriptorData * data)158 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
159 CallInterfaceDescriptorData* data) {
160 // x3: closure
161 // x2: object literal index
162 // x1: constant properties
163 // x0: object literal flags
164 Register registers[] = {x3, x2, x1, x0};
165 data->InitializePlatformSpecific(arraysize(registers), registers);
166 }
167
168
InitializePlatformSpecific(CallInterfaceDescriptorData * data)169 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
170 CallInterfaceDescriptorData* data) {
171 // x2: feedback vector
172 // x3: call feedback slot
173 Register registers[] = {x2, x3};
174 data->InitializePlatformSpecific(arraysize(registers), registers);
175 }
176
177
InitializePlatformSpecific(CallInterfaceDescriptorData * data)178 void CreateWeakCellDescriptor::InitializePlatformSpecific(
179 CallInterfaceDescriptorData* data) {
180 // x2: feedback vector
181 // x3: call feedback slot
182 // x1: tagged value to put in the weak cell
183 Register registers[] = {x2, x3, x1};
184 data->InitializePlatformSpecific(arraysize(registers), registers);
185 }
186
187
InitializePlatformSpecific(CallInterfaceDescriptorData * data)188 void StoreArrayLiteralElementDescriptor::InitializePlatformSpecific(
189 CallInterfaceDescriptorData* data) {
190 Register registers[] = {x3, x0};
191 data->InitializePlatformSpecific(arraysize(registers), registers);
192 }
193
194
InitializePlatformSpecific(CallInterfaceDescriptorData * data)195 void CallFunctionDescriptor::InitializePlatformSpecific(
196 CallInterfaceDescriptorData* data) {
197 // x1 function the function to call
198 Register registers[] = {x1};
199 data->InitializePlatformSpecific(arraysize(registers), registers);
200 }
201
202
InitializePlatformSpecific(CallInterfaceDescriptorData * data)203 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
204 CallInterfaceDescriptorData* data) {
205 Register registers[] = {x1, x3};
206 data->InitializePlatformSpecific(arraysize(registers), registers);
207 }
208
209
InitializePlatformSpecific(CallInterfaceDescriptorData * data)210 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
211 CallInterfaceDescriptorData* data) {
212 Register registers[] = {x1, x3, x2};
213 data->InitializePlatformSpecific(arraysize(registers), registers);
214 }
215
216
InitializePlatformSpecific(CallInterfaceDescriptorData * data)217 void CallConstructDescriptor::InitializePlatformSpecific(
218 CallInterfaceDescriptorData* data) {
219 // x0 : number of arguments
220 // x1 : the function to call
221 // x2 : feedback vector
222 // x3 : slot in feedback vector (Smi, for RecordCallTarget)
223 // x4 : new target (for IsSuperConstructorCall)
224 // TODO(turbofan): So far we don't gather type feedback and hence skip the
225 // slot parameter, but ArrayConstructStub needs the vector to be undefined.
226 Register registers[] = {x0, x1, x4, x2};
227 data->InitializePlatformSpecific(arraysize(registers), registers);
228 }
229
230
InitializePlatformSpecific(CallInterfaceDescriptorData * data)231 void CallTrampolineDescriptor::InitializePlatformSpecific(
232 CallInterfaceDescriptorData* data) {
233 // x1: target
234 // x0: number of arguments
235 Register registers[] = {x1, x0};
236 data->InitializePlatformSpecific(arraysize(registers), registers);
237 }
238
239
InitializePlatformSpecific(CallInterfaceDescriptorData * data)240 void ConstructStubDescriptor::InitializePlatformSpecific(
241 CallInterfaceDescriptorData* data) {
242 // x3: new target
243 // x1: target
244 // x0: number of arguments
245 // x2: allocation site or undefined
246 Register registers[] = {x1, x3, x0, x2};
247 data->InitializePlatformSpecific(arraysize(registers), registers);
248 }
249
250
InitializePlatformSpecific(CallInterfaceDescriptorData * data)251 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
252 CallInterfaceDescriptorData* data) {
253 // x3: new target
254 // x1: target
255 // x0: number of arguments
256 Register registers[] = {x1, x3, x0};
257 data->InitializePlatformSpecific(arraysize(registers), registers);
258 }
259
260
InitializePlatformSpecific(CallInterfaceDescriptorData * data)261 void RegExpConstructResultDescriptor::InitializePlatformSpecific(
262 CallInterfaceDescriptorData* data) {
263 // x2: length
264 // x1: index (of last match)
265 // x0: string
266 Register registers[] = {x2, x1, x0};
267 data->InitializePlatformSpecific(arraysize(registers), registers);
268 }
269
270
InitializePlatformSpecific(CallInterfaceDescriptorData * data)271 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
272 CallInterfaceDescriptorData* data) {
273 // x0: value (js_array)
274 // x1: to_map
275 Register registers[] = {x0, x1};
276 data->InitializePlatformSpecific(arraysize(registers), registers);
277 }
278
279
InitializePlatformSpecific(CallInterfaceDescriptorData * data)280 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
281 CallInterfaceDescriptorData* data) {
282 data->InitializePlatformSpecific(0, nullptr, nullptr);
283 }
284
285
InitializePlatformSpecific(CallInterfaceDescriptorData * data)286 void AllocateInNewSpaceDescriptor::InitializePlatformSpecific(
287 CallInterfaceDescriptorData* data) {
288 Register registers[] = {x0};
289 data->InitializePlatformSpecific(arraysize(registers), registers);
290 }
291
292
InitializePlatformSpecific(CallInterfaceDescriptorData * data)293 void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
294 CallInterfaceDescriptorData* data) {
295 // x1: function
296 // x2: allocation site with elements kind
297 // x0: number of arguments to the constructor function
298 Register registers[] = {x1, x2};
299 data->InitializePlatformSpecific(arraysize(registers), registers);
300 }
301
302
InitializePlatformSpecific(CallInterfaceDescriptorData * data)303 void ArrayConstructorDescriptor::InitializePlatformSpecific(
304 CallInterfaceDescriptorData* data) {
305 // stack param count needs (constructor pointer, and single argument)
306 Register registers[] = {x1, x2, x0};
307 data->InitializePlatformSpecific(arraysize(registers), registers);
308 }
309
310
311 void InternalArrayConstructorConstantArgCountDescriptor::
InitializePlatformSpecific(CallInterfaceDescriptorData * data)312 InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
313 // x1: constructor function
314 // x0: number of arguments to the constructor function
315 Register registers[] = {x1};
316 data->InitializePlatformSpecific(arraysize(registers), registers);
317 }
318
319
InitializePlatformSpecific(CallInterfaceDescriptorData * data)320 void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
321 CallInterfaceDescriptorData* data) {
322 // stack param count needs (constructor pointer, and single argument)
323 Register registers[] = {x1, x0};
324 data->InitializePlatformSpecific(arraysize(registers), registers);
325 }
326
327
InitializePlatformSpecific(CallInterfaceDescriptorData * data)328 void CompareDescriptor::InitializePlatformSpecific(
329 CallInterfaceDescriptorData* data) {
330 // x1: left operand
331 // x0: right operand
332 Register registers[] = {x1, x0};
333 data->InitializePlatformSpecific(arraysize(registers), registers);
334 }
335
336
InitializePlatformSpecific(CallInterfaceDescriptorData * data)337 void CompareNilDescriptor::InitializePlatformSpecific(
338 CallInterfaceDescriptorData* data) {
339 // x0: value to compare
340 Register registers[] = {x0};
341 data->InitializePlatformSpecific(arraysize(registers), registers);
342 }
343
344
InitializePlatformSpecific(CallInterfaceDescriptorData * data)345 void ToBooleanDescriptor::InitializePlatformSpecific(
346 CallInterfaceDescriptorData* data) {
347 // x0: value
348 Register registers[] = {x0};
349 data->InitializePlatformSpecific(arraysize(registers), registers);
350 }
351
352
InitializePlatformSpecific(CallInterfaceDescriptorData * data)353 void BinaryOpDescriptor::InitializePlatformSpecific(
354 CallInterfaceDescriptorData* data) {
355 // x1: left operand
356 // x0: right operand
357 Register registers[] = {x1, x0};
358 data->InitializePlatformSpecific(arraysize(registers), registers);
359 }
360
361
InitializePlatformSpecific(CallInterfaceDescriptorData * data)362 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
363 CallInterfaceDescriptorData* data) {
364 // x2: allocation site
365 // x1: left operand
366 // x0: right operand
367 Register registers[] = {x2, x1, x0};
368 data->InitializePlatformSpecific(arraysize(registers), registers);
369 }
370
371
InitializePlatformSpecific(CallInterfaceDescriptorData * data)372 void StringAddDescriptor::InitializePlatformSpecific(
373 CallInterfaceDescriptorData* data) {
374 // x1: left operand
375 // x0: right operand
376 Register registers[] = {x1, x0};
377 data->InitializePlatformSpecific(arraysize(registers), registers);
378 }
379
380
InitializePlatformSpecific(CallInterfaceDescriptorData * data)381 void KeyedDescriptor::InitializePlatformSpecific(
382 CallInterfaceDescriptorData* data) {
383 static PlatformInterfaceDescriptor noInlineDescriptor =
384 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
385
386 Register registers[] = {
387 x2, // key
388 };
389 data->InitializePlatformSpecific(arraysize(registers), registers,
390 &noInlineDescriptor);
391 }
392
393
InitializePlatformSpecific(CallInterfaceDescriptorData * data)394 void NamedDescriptor::InitializePlatformSpecific(
395 CallInterfaceDescriptorData* data) {
396 static PlatformInterfaceDescriptor noInlineDescriptor =
397 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
398
399 Register registers[] = {
400 x2, // name
401 };
402 data->InitializePlatformSpecific(arraysize(registers), registers,
403 &noInlineDescriptor);
404 }
405
406
InitializePlatformSpecific(CallInterfaceDescriptorData * data)407 void CallHandlerDescriptor::InitializePlatformSpecific(
408 CallInterfaceDescriptorData* data) {
409 static PlatformInterfaceDescriptor default_descriptor =
410 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
411
412 Register registers[] = {
413 x0, // receiver
414 };
415 data->InitializePlatformSpecific(arraysize(registers), registers,
416 &default_descriptor);
417 }
418
419
InitializePlatformSpecific(CallInterfaceDescriptorData * data)420 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
421 CallInterfaceDescriptorData* data) {
422 static PlatformInterfaceDescriptor default_descriptor =
423 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
424
425 Register registers[] = {
426 x1, // JSFunction
427 x3, // the new target
428 x0, // actual number of arguments
429 x2, // expected number of arguments
430 };
431 data->InitializePlatformSpecific(arraysize(registers), registers,
432 &default_descriptor);
433 }
434
435
InitializePlatformSpecific(CallInterfaceDescriptorData * data)436 void ApiFunctionDescriptor::InitializePlatformSpecific(
437 CallInterfaceDescriptorData* data) {
438 static PlatformInterfaceDescriptor default_descriptor =
439 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
440
441 Register registers[] = {
442 x0, // callee
443 x4, // call_data
444 x2, // holder
445 x1, // api_function_address
446 x3, // actual number of arguments
447 };
448 data->InitializePlatformSpecific(arraysize(registers), registers,
449 &default_descriptor);
450 }
451
452
InitializePlatformSpecific(CallInterfaceDescriptorData * data)453 void ApiAccessorDescriptor::InitializePlatformSpecific(
454 CallInterfaceDescriptorData* data) {
455 static PlatformInterfaceDescriptor default_descriptor =
456 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
457
458 Register registers[] = {
459 x0, // callee
460 x4, // call_data
461 x2, // holder
462 x1, // api_function_address
463 };
464 data->InitializePlatformSpecific(arraysize(registers), registers,
465 &default_descriptor);
466 }
467
468
InitializePlatformSpecific(CallInterfaceDescriptorData * data)469 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
470 CallInterfaceDescriptorData* data) {
471 Register registers[] = {
472 x0, // argument count (not including receiver)
473 x2, // address of first argument
474 x1 // the target callable to be call
475 };
476 data->InitializePlatformSpecific(arraysize(registers), registers);
477 }
478
479
InitializePlatformSpecific(CallInterfaceDescriptorData * data)480 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
481 CallInterfaceDescriptorData* data) {
482 Register registers[] = {
483 x0, // argument count (not including receiver)
484 x3, // new target
485 x1, // constructor to call
486 x2 // address of the first argument
487 };
488 data->InitializePlatformSpecific(arraysize(registers), registers);
489 }
490
491
InitializePlatformSpecific(CallInterfaceDescriptorData * data)492 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
493 CallInterfaceDescriptorData* data) {
494 Register registers[] = {
495 x0, // argument count (argc)
496 x11, // address of first argument (argv)
497 x1 // the runtime function to call
498 };
499 data->InitializePlatformSpecific(arraysize(registers), registers);
500 }
501
502
503 } // namespace internal
504 } // namespace v8
505
506 #endif // V8_TARGET_ARCH_ARM64
507