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