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