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/v8.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; }
19
20
SlotRegister()21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; }
22
23
VectorRegister()24 const Register VectorLoadICDescriptor::VectorRegister() { return x3; }
25
26
ReceiverRegister()27 const Register StoreDescriptor::ReceiverRegister() { return x1; }
NameRegister()28 const Register StoreDescriptor::NameRegister() { return x2; }
ValueRegister()29 const Register StoreDescriptor::ValueRegister() { return x0; }
30
31
MapRegister()32 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; }
33
34
left()35 const Register InstanceofDescriptor::left() {
36 // Object to check (instanceof lhs).
37 return x11;
38 }
39
40
right()41 const Register InstanceofDescriptor::right() {
42 // Constructor function (instanceof rhs).
43 return x10;
44 }
45
46
index()47 const Register ArgumentsAccessReadDescriptor::index() { return x1; }
parameter_count()48 const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
49
50
function_address()51 const Register ApiGetterDescriptor::function_address() { return x2; }
52
53
exponent()54 const Register MathPowTaggedDescriptor::exponent() { return x11; }
55
56
exponent()57 const Register MathPowIntegerDescriptor::exponent() { return x12; }
58
59
Initialize(CallInterfaceDescriptorData * data)60 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
61 // cp: context
62 // x2: function info
63 Register registers[] = {cp, x2};
64 data->Initialize(arraysize(registers), registers, NULL);
65 }
66
67
Initialize(CallInterfaceDescriptorData * data)68 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
69 // cp: context
70 // x1: function
71 Register registers[] = {cp, x1};
72 data->Initialize(arraysize(registers), registers, NULL);
73 }
74
75
Initialize(CallInterfaceDescriptorData * data)76 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
77 // cp: context
78 // x0: value
79 Register registers[] = {cp, x0};
80 data->Initialize(arraysize(registers), registers, NULL);
81 }
82
83
Initialize(CallInterfaceDescriptorData * data)84 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
85 // cp: context
86 // x0: value
87 Register registers[] = {cp, x0};
88 data->Initialize(arraysize(registers), registers, NULL);
89 }
90
91
Initialize(CallInterfaceDescriptorData * data)92 void FastCloneShallowArrayDescriptor::Initialize(
93 CallInterfaceDescriptorData* data) {
94 // cp: context
95 // x3: array literals array
96 // x2: array literal index
97 // x1: constant elements
98 Register registers[] = {cp, x3, x2, x1};
99 Representation representations[] = {
100 Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
101 Representation::Tagged()};
102 data->Initialize(arraysize(registers), registers, representations);
103 }
104
105
Initialize(CallInterfaceDescriptorData * data)106 void FastCloneShallowObjectDescriptor::Initialize(
107 CallInterfaceDescriptorData* data) {
108 // cp: context
109 // x3: object literals array
110 // x2: object literal index
111 // x1: constant properties
112 // x0: object literal flags
113 Register registers[] = {cp, x3, x2, x1, x0};
114 data->Initialize(arraysize(registers), registers, NULL);
115 }
116
117
Initialize(CallInterfaceDescriptorData * data)118 void CreateAllocationSiteDescriptor::Initialize(
119 CallInterfaceDescriptorData* data) {
120 // cp: context
121 // x2: feedback vector
122 // x3: call feedback slot
123 Register registers[] = {cp, x2, x3};
124 data->Initialize(arraysize(registers), registers, NULL);
125 }
126
127
Initialize(CallInterfaceDescriptorData * data)128 void StoreArrayLiteralElementDescriptor::Initialize(
129 CallInterfaceDescriptorData* data) {
130 Register registers[] = {cp, x3, x0};
131 data->Initialize(arraysize(registers), registers, NULL);
132 }
133
134
Initialize(CallInterfaceDescriptorData * data)135 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
136 // x1 function the function to call
137 Register registers[] = {cp, x1};
138 data->Initialize(arraysize(registers), registers, NULL);
139 }
140
141
Initialize(CallInterfaceDescriptorData * data)142 void CallFunctionWithFeedbackDescriptor::Initialize(
143 CallInterfaceDescriptorData* data) {
144 Register registers[] = {cp, x1, x3};
145 Representation representations[] = {Representation::Tagged(),
146 Representation::Tagged(),
147 Representation::Smi()};
148 data->Initialize(arraysize(registers), registers, representations);
149 }
150
151
Initialize(CallInterfaceDescriptorData * data)152 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
153 // x0 : number of arguments
154 // x1 : the function to call
155 // x2 : feedback vector
156 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
157 // TODO(turbofan): So far we don't gather type feedback and hence skip the
158 // slot parameter, but ArrayConstructStub needs the vector to be undefined.
159 Register registers[] = {cp, x0, x1, x2};
160 data->Initialize(arraysize(registers), registers, NULL);
161 }
162
163
Initialize(CallInterfaceDescriptorData * data)164 void RegExpConstructResultDescriptor::Initialize(
165 CallInterfaceDescriptorData* data) {
166 // cp: context
167 // x2: length
168 // x1: index (of last match)
169 // x0: string
170 Register registers[] = {cp, x2, x1, x0};
171 data->Initialize(arraysize(registers), registers, NULL);
172 }
173
174
Initialize(CallInterfaceDescriptorData * data)175 void TransitionElementsKindDescriptor::Initialize(
176 CallInterfaceDescriptorData* data) {
177 // cp: context
178 // x0: value (js_array)
179 // x1: to_map
180 Register registers[] = {cp, x0, x1};
181 data->Initialize(arraysize(registers), registers, NULL);
182 }
183
184
Initialize(CallInterfaceDescriptorData * data)185 void ArrayConstructorConstantArgCountDescriptor::Initialize(
186 CallInterfaceDescriptorData* data) {
187 // cp: context
188 // x1: function
189 // x2: allocation site with elements kind
190 // x0: number of arguments to the constructor function
191 Register registers[] = {cp, x1, x2};
192 data->Initialize(arraysize(registers), registers, NULL);
193 }
194
195
Initialize(CallInterfaceDescriptorData * data)196 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
197 // stack param count needs (constructor pointer, and single argument)
198 Register registers[] = {cp, x1, x2, x0};
199 Representation representations[] = {
200 Representation::Tagged(), Representation::Tagged(),
201 Representation::Tagged(), Representation::Integer32()};
202 data->Initialize(arraysize(registers), registers, representations);
203 }
204
205
Initialize(CallInterfaceDescriptorData * data)206 void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
207 CallInterfaceDescriptorData* data) {
208 // cp: context
209 // x1: constructor function
210 // x0: number of arguments to the constructor function
211 Register registers[] = {cp, x1};
212 data->Initialize(arraysize(registers), registers, NULL);
213 }
214
215
Initialize(CallInterfaceDescriptorData * data)216 void InternalArrayConstructorDescriptor::Initialize(
217 CallInterfaceDescriptorData* data) {
218 // stack param count needs (constructor pointer, and single argument)
219 Register registers[] = {cp, x1, x0};
220 Representation representations[] = {Representation::Tagged(),
221 Representation::Tagged(),
222 Representation::Integer32()};
223 data->Initialize(arraysize(registers), registers, representations);
224 }
225
226
Initialize(CallInterfaceDescriptorData * data)227 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
228 // cp: context
229 // x0: value to compare
230 Register registers[] = {cp, x0};
231 data->Initialize(arraysize(registers), registers, NULL);
232 }
233
234
Initialize(CallInterfaceDescriptorData * data)235 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
236 // cp: context
237 // x0: value
238 Register registers[] = {cp, x0};
239 data->Initialize(arraysize(registers), registers, NULL);
240 }
241
242
Initialize(CallInterfaceDescriptorData * data)243 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
244 // cp: context
245 // x1: left operand
246 // x0: right operand
247 Register registers[] = {cp, x1, x0};
248 data->Initialize(arraysize(registers), registers, NULL);
249 }
250
251
Initialize(CallInterfaceDescriptorData * data)252 void BinaryOpWithAllocationSiteDescriptor::Initialize(
253 CallInterfaceDescriptorData* data) {
254 // cp: context
255 // x2: allocation site
256 // x1: left operand
257 // x0: right operand
258 Register registers[] = {cp, x2, x1, x0};
259 data->Initialize(arraysize(registers), registers, NULL);
260 }
261
262
Initialize(CallInterfaceDescriptorData * data)263 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
264 // cp: context
265 // x1: left operand
266 // x0: right operand
267 Register registers[] = {cp, x1, x0};
268 data->Initialize(arraysize(registers), registers, NULL);
269 }
270
271
Initialize(CallInterfaceDescriptorData * data)272 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
273 static PlatformInterfaceDescriptor noInlineDescriptor =
274 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
275
276 Register registers[] = {
277 cp, // context
278 x2, // key
279 };
280 Representation representations[] = {
281 Representation::Tagged(), // context
282 Representation::Tagged(), // key
283 };
284 data->Initialize(arraysize(registers), registers, representations,
285 &noInlineDescriptor);
286 }
287
288
Initialize(CallInterfaceDescriptorData * data)289 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
290 static PlatformInterfaceDescriptor noInlineDescriptor =
291 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
292
293 Register registers[] = {
294 cp, // context
295 x2, // name
296 };
297 Representation representations[] = {
298 Representation::Tagged(), // context
299 Representation::Tagged(), // name
300 };
301 data->Initialize(arraysize(registers), registers, representations,
302 &noInlineDescriptor);
303 }
304
305
Initialize(CallInterfaceDescriptorData * data)306 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
307 static PlatformInterfaceDescriptor default_descriptor =
308 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
309
310 Register registers[] = {
311 cp, // context
312 x0, // receiver
313 };
314 Representation representations[] = {
315 Representation::Tagged(), // context
316 Representation::Tagged(), // receiver
317 };
318 data->Initialize(arraysize(registers), registers, representations,
319 &default_descriptor);
320 }
321
322
Initialize(CallInterfaceDescriptorData * data)323 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
324 static PlatformInterfaceDescriptor default_descriptor =
325 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
326
327 Register registers[] = {
328 cp, // context
329 x1, // JSFunction
330 x0, // actual number of arguments
331 x2, // expected number of arguments
332 };
333 Representation representations[] = {
334 Representation::Tagged(), // context
335 Representation::Tagged(), // JSFunction
336 Representation::Integer32(), // actual number of arguments
337 Representation::Integer32(), // expected number of arguments
338 };
339 data->Initialize(arraysize(registers), registers, representations,
340 &default_descriptor);
341 }
342
343
Initialize(CallInterfaceDescriptorData * data)344 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
345 static PlatformInterfaceDescriptor default_descriptor =
346 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
347
348 Register registers[] = {
349 cp, // context
350 x0, // callee
351 x4, // call_data
352 x2, // holder
353 x1, // api_function_address
354 };
355 Representation representations[] = {
356 Representation::Tagged(), // context
357 Representation::Tagged(), // callee
358 Representation::Tagged(), // call_data
359 Representation::Tagged(), // holder
360 Representation::External(), // api_function_address
361 };
362 data->Initialize(arraysize(registers), registers, representations,
363 &default_descriptor);
364 }
365 }
366 } // namespace v8::internal
367
368 #endif // V8_TARGET_ARCH_ARM64
369