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