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