• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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