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