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