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.
7 #if V8_TARGET_ARCH_ARM64
9 #include "src/interface-descriptors.h"
14 const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
17 const Register LoadDescriptor::ReceiverRegister() { return x1; }
18 const Register LoadDescriptor::NameRegister() { return x2; }
21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; }
24 const Register VectorLoadICDescriptor::VectorRegister() { return x3; }
27 const Register StoreDescriptor::ReceiverRegister() { return x1; }
28 const Register StoreDescriptor::NameRegister() { return x2; }
29 const Register StoreDescriptor::ValueRegister() { return x0; }
32 const Register StoreTransitionDescriptor::MapRegister() { return x3; }
35 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; }
38 const Register InstanceofDescriptor::left() {
39 // Object to check (instanceof lhs).
44 const Register InstanceofDescriptor::right() {
45 // Constructor function (instanceof rhs).
50 const Register ArgumentsAccessReadDescriptor::index() { return x1; }
51 const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
54 const Register ApiGetterDescriptor::function_address() { return x2; }
57 const Register MathPowTaggedDescriptor::exponent() { return x11; }
60 const Register MathPowIntegerDescriptor::exponent() { return x12; }
63 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
66 Register registers[] = {cp, x2};
67 data->Initialize(arraysize(registers), registers, NULL);
71 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
74 Register registers[] = {cp, x1};
75 data->Initialize(arraysize(registers), registers, NULL);
79 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
82 Register registers[] = {cp, x0};
83 data->Initialize(arraysize(registers), registers, NULL);
87 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
90 Register registers[] = {cp, x0};
91 data->Initialize(arraysize(registers), registers, NULL);
95 void FastCloneShallowArrayDescriptor::Initialize(
96 CallInterfaceDescriptorData* data) {
98 // x3: array literals array
99 // x2: array literal index
100 // x1: constant elements
101 Register registers[] = {cp, x3, x2, x1};
102 Representation representations[] = {
103 Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
104 Representation::Tagged()};
105 data->Initialize(arraysize(registers), registers, representations);
109 void FastCloneShallowObjectDescriptor::Initialize(
110 CallInterfaceDescriptorData* data) {
112 // x3: object literals array
113 // x2: object literal index
114 // x1: constant properties
115 // x0: object literal flags
116 Register registers[] = {cp, x3, x2, x1, x0};
117 data->Initialize(arraysize(registers), registers, NULL);
121 void CreateAllocationSiteDescriptor::Initialize(
122 CallInterfaceDescriptorData* data) {
124 // x2: feedback vector
125 // x3: call feedback slot
126 Register registers[] = {cp, x2, x3};
127 Representation representations[] = {Representation::Tagged(),
128 Representation::Tagged(),
129 Representation::Smi()};
130 data->Initialize(arraysize(registers), registers, representations);
134 void CreateWeakCellDescriptor::Initialize(CallInterfaceDescriptorData* data) {
136 // x2: feedback vector
137 // x3: call feedback slot
138 // x1: tagged value to put in the weak cell
139 Register registers[] = {cp, x2, x3, x1};
140 Representation representations[] = {
141 Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
142 Representation::Tagged()};
143 data->Initialize(arraysize(registers), registers, representations);
147 void StoreArrayLiteralElementDescriptor::Initialize(
148 CallInterfaceDescriptorData* data) {
149 Register registers[] = {cp, x3, x0};
150 data->Initialize(arraysize(registers), registers, NULL);
154 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
155 // x1 function the function to call
156 Register registers[] = {cp, x1};
157 data->Initialize(arraysize(registers), registers, NULL);
161 void CallFunctionWithFeedbackDescriptor::Initialize(
162 CallInterfaceDescriptorData* data) {
163 Register registers[] = {cp, x1, x3};
164 Representation representations[] = {Representation::Tagged(),
165 Representation::Tagged(),
166 Representation::Smi()};
167 data->Initialize(arraysize(registers), registers, representations);
171 void CallFunctionWithFeedbackAndVectorDescriptor::Initialize(
172 CallInterfaceDescriptorData* data) {
173 Register registers[] = {cp, x1, x3, x2};
174 Representation representations[] = {
175 Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
176 Representation::Tagged()};
177 data->Initialize(arraysize(registers), registers, representations);
181 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
182 // x0 : number of arguments
183 // x1 : the function to call
184 // x2 : feedback vector
185 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
186 // TODO(turbofan): So far we don't gather type feedback and hence skip the
187 // slot parameter, but ArrayConstructStub needs the vector to be undefined.
188 Register registers[] = {cp, x0, x1, x2};
189 data->Initialize(arraysize(registers), registers, NULL);
193 void RegExpConstructResultDescriptor::Initialize(
194 CallInterfaceDescriptorData* data) {
197 // x1: index (of last match)
199 Register registers[] = {cp, x2, x1, x0};
200 data->Initialize(arraysize(registers), registers, NULL);
204 void TransitionElementsKindDescriptor::Initialize(
205 CallInterfaceDescriptorData* data) {
207 // x0: value (js_array)
209 Register registers[] = {cp, x0, x1};
210 data->Initialize(arraysize(registers), registers, NULL);
214 void AllocateHeapNumberDescriptor::Initialize(
215 CallInterfaceDescriptorData* data) {
217 Register registers[] = {cp};
218 data->Initialize(arraysize(registers), registers, nullptr);
222 void ArrayConstructorConstantArgCountDescriptor::Initialize(
223 CallInterfaceDescriptorData* data) {
226 // x2: allocation site with elements kind
227 // x0: number of arguments to the constructor function
228 Register registers[] = {cp, x1, x2};
229 data->Initialize(arraysize(registers), registers, NULL);
233 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
234 // stack param count needs (constructor pointer, and single argument)
235 Register registers[] = {cp, x1, x2, x0};
236 Representation representations[] = {
237 Representation::Tagged(), Representation::Tagged(),
238 Representation::Tagged(), Representation::Integer32()};
239 data->Initialize(arraysize(registers), registers, representations);
243 void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
244 CallInterfaceDescriptorData* data) {
246 // x1: constructor function
247 // x0: number of arguments to the constructor function
248 Register registers[] = {cp, x1};
249 data->Initialize(arraysize(registers), registers, NULL);
253 void InternalArrayConstructorDescriptor::Initialize(
254 CallInterfaceDescriptorData* data) {
255 // stack param count needs (constructor pointer, and single argument)
256 Register registers[] = {cp, x1, x0};
257 Representation representations[] = {Representation::Tagged(),
258 Representation::Tagged(),
259 Representation::Integer32()};
260 data->Initialize(arraysize(registers), registers, representations);
264 void CompareDescriptor::Initialize(CallInterfaceDescriptorData* data) {
268 Register registers[] = {cp, x1, x0};
269 data->Initialize(arraysize(registers), registers, NULL);
273 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
275 // x0: value to compare
276 Register registers[] = {cp, x0};
277 data->Initialize(arraysize(registers), registers, NULL);
281 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
284 Register registers[] = {cp, x0};
285 data->Initialize(arraysize(registers), registers, NULL);
289 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
293 Register registers[] = {cp, x1, x0};
294 data->Initialize(arraysize(registers), registers, NULL);
298 void BinaryOpWithAllocationSiteDescriptor::Initialize(
299 CallInterfaceDescriptorData* data) {
301 // x2: allocation site
304 Register registers[] = {cp, x2, x1, x0};
305 data->Initialize(arraysize(registers), registers, NULL);
309 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
313 Register registers[] = {cp, x1, x0};
314 data->Initialize(arraysize(registers), registers, NULL);
318 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
319 static PlatformInterfaceDescriptor noInlineDescriptor =
320 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
322 Register registers[] = {
326 Representation representations[] = {
327 Representation::Tagged(), // context
328 Representation::Tagged(), // key
330 data->Initialize(arraysize(registers), registers, representations,
331 &noInlineDescriptor);
335 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
336 static PlatformInterfaceDescriptor noInlineDescriptor =
337 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
339 Register registers[] = {
343 Representation representations[] = {
344 Representation::Tagged(), // context
345 Representation::Tagged(), // name
347 data->Initialize(arraysize(registers), registers, representations,
348 &noInlineDescriptor);
352 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
353 static PlatformInterfaceDescriptor default_descriptor =
354 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
356 Register registers[] = {
360 Representation representations[] = {
361 Representation::Tagged(), // context
362 Representation::Tagged(), // receiver
364 data->Initialize(arraysize(registers), registers, representations,
365 &default_descriptor);
369 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
370 static PlatformInterfaceDescriptor default_descriptor =
371 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
373 Register registers[] = {
376 x0, // actual number of arguments
377 x2, // expected number of arguments
379 Representation representations[] = {
380 Representation::Tagged(), // context
381 Representation::Tagged(), // JSFunction
382 Representation::Integer32(), // actual number of arguments
383 Representation::Integer32(), // expected number of arguments
385 data->Initialize(arraysize(registers), registers, representations,
386 &default_descriptor);
390 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
391 static PlatformInterfaceDescriptor default_descriptor =
392 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
394 Register registers[] = {
399 x1, // api_function_address
400 x3, // actual number of arguments
402 Representation representations[] = {
403 Representation::Tagged(), // context
404 Representation::Tagged(), // callee
405 Representation::Tagged(), // call_data
406 Representation::Tagged(), // holder
407 Representation::External(), // api_function_address
408 Representation::Integer32(), // actual number of arguments
410 data->Initialize(arraysize(registers), registers, representations,
411 &default_descriptor);
415 void ApiAccessorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
416 static PlatformInterfaceDescriptor default_descriptor =
417 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
419 Register registers[] = {
424 x1, // api_function_address
426 Representation representations[] = {
427 Representation::Tagged(), // context
428 Representation::Tagged(), // callee
429 Representation::Tagged(), // call_data
430 Representation::Tagged(), // holder
431 Representation::External(), // api_function_address
433 data->Initialize(arraysize(registers), registers, representations,
434 &default_descriptor);
437 } // namespace v8::internal
439 #endif // V8_TARGET_ARCH_ARM64