[stubs] Optimize LoadGlobalViaContextStub and StoreGlobalViaContextStub.
[platform/upstream/v8.git] / src / arm / interface-descriptors-arm.cc
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_ARM
8
9 #include "src/interface-descriptors.h"
10
11 namespace v8 {
12 namespace internal {
13
14 const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
15
16
17 const Register LoadDescriptor::ReceiverRegister() { return r1; }
18 const Register LoadDescriptor::NameRegister() { return r2; }
19 const Register LoadDescriptor::SlotRegister() { return r0; }
20
21
22 const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
23
24
25 const Register StoreDescriptor::ReceiverRegister() { return r1; }
26 const Register StoreDescriptor::NameRegister() { return r2; }
27 const Register StoreDescriptor::ValueRegister() { return r0; }
28
29
30 const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return r4; }
31
32
33 const Register VectorStoreICDescriptor::VectorRegister() { return r3; }
34
35
36 const Register StoreTransitionDescriptor::MapRegister() { return r3; }
37
38
39 const Register LoadGlobalViaContextDescriptor::SlotRegister() { return r2; }
40 const Register LoadGlobalViaContextDescriptor::NameRegister() { return r3; }
41
42
43 const Register StoreGlobalViaContextDescriptor::SlotRegister() { return r2; }
44 const Register StoreGlobalViaContextDescriptor::NameRegister() { return r3; }
45 const Register StoreGlobalViaContextDescriptor::ValueRegister() { return r0; }
46
47
48 const Register InstanceofDescriptor::left() { return r0; }
49 const Register InstanceofDescriptor::right() { return r1; }
50
51
52 const Register ArgumentsAccessReadDescriptor::index() { return r1; }
53 const Register ArgumentsAccessReadDescriptor::parameter_count() { return r0; }
54
55
56 const Register ApiGetterDescriptor::function_address() { return r2; }
57
58
59 const Register MathPowTaggedDescriptor::exponent() { return r2; }
60
61
62 const Register MathPowIntegerDescriptor::exponent() {
63   return MathPowTaggedDescriptor::exponent();
64 }
65
66
67 const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
68 const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
69
70
71 void StoreTransitionDescriptor::InitializePlatformSpecific(
72     CallInterfaceDescriptorData* data) {
73   Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
74                           MapRegister()};
75   data->InitializePlatformSpecific(arraysize(registers), registers);
76 }
77
78
79 void FastNewClosureDescriptor::InitializePlatformSpecific(
80     CallInterfaceDescriptorData* data) {
81   Register registers[] = {r2};
82   data->InitializePlatformSpecific(arraysize(registers), registers);
83 }
84
85
86 void FastNewContextDescriptor::InitializePlatformSpecific(
87     CallInterfaceDescriptorData* data) {
88   Register registers[] = {r1};
89   data->InitializePlatformSpecific(arraysize(registers), registers);
90 }
91
92
93 void ToNumberDescriptor::InitializePlatformSpecific(
94     CallInterfaceDescriptorData* data) {
95   Register registers[] = {r0};
96   data->InitializePlatformSpecific(arraysize(registers), registers);
97 }
98
99
100 void NumberToStringDescriptor::InitializePlatformSpecific(
101     CallInterfaceDescriptorData* data) {
102   Register registers[] = {r0};
103   data->InitializePlatformSpecific(arraysize(registers), registers);
104 }
105
106
107 void TypeofDescriptor::InitializePlatformSpecific(
108     CallInterfaceDescriptorData* data) {
109   Register registers[] = {r3};
110   data->InitializePlatformSpecific(arraysize(registers), registers);
111 }
112
113
114 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
115     CallInterfaceDescriptorData* data) {
116   Register registers[] = {r3, r2, r1};
117   data->InitializePlatformSpecific(arraysize(registers), registers);
118 }
119
120
121 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
122     CallInterfaceDescriptorData* data) {
123   Register registers[] = {r3, r2, r1, r0};
124   data->InitializePlatformSpecific(arraysize(registers), registers);
125 }
126
127
128 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
129     CallInterfaceDescriptorData* data) {
130   Register registers[] = {r2, r3};
131   data->InitializePlatformSpecific(arraysize(registers), registers);
132 }
133
134
135 void CreateWeakCellDescriptor::InitializePlatformSpecific(
136     CallInterfaceDescriptorData* data) {
137   Register registers[] = {r2, r3, r1};
138   data->InitializePlatformSpecific(arraysize(registers), registers);
139 }
140
141
142 void StoreArrayLiteralElementDescriptor::InitializePlatformSpecific(
143     CallInterfaceDescriptorData* data) {
144   Register registers[] = {r3, r0};
145   data->InitializePlatformSpecific(arraysize(registers), registers);
146 }
147
148
149 void CallFunctionDescriptor::InitializePlatformSpecific(
150     CallInterfaceDescriptorData* data) {
151   Register registers[] = {r1};
152   data->InitializePlatformSpecific(arraysize(registers), registers);
153 }
154
155
156 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
157     CallInterfaceDescriptorData* data) {
158   Register registers[] = {r1, r3};
159   data->InitializePlatformSpecific(arraysize(registers), registers);
160 }
161
162
163 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
164     CallInterfaceDescriptorData* data) {
165   Register registers[] = {r1, r3, r2};
166   data->InitializePlatformSpecific(arraysize(registers), registers);
167 }
168
169
170 void CallConstructDescriptor::InitializePlatformSpecific(
171     CallInterfaceDescriptorData* data) {
172   // r0 : number of arguments
173   // r1 : the function to call
174   // r2 : feedback vector
175   // r3 : slot in feedback vector (Smi, for RecordCallTarget)
176   // r4 : original constructor (for IsSuperConstructorCall)
177   // TODO(turbofan): So far we don't gather type feedback and hence skip the
178   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
179   Register registers[] = {r0, r1, r4, r2};
180   data->InitializePlatformSpecific(arraysize(registers), registers);
181 }
182
183
184 void RegExpConstructResultDescriptor::InitializePlatformSpecific(
185     CallInterfaceDescriptorData* data) {
186   Register registers[] = {r2, r1, r0};
187   data->InitializePlatformSpecific(arraysize(registers), registers);
188 }
189
190
191 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
192     CallInterfaceDescriptorData* data) {
193   Register registers[] = {r0, r1};
194   data->InitializePlatformSpecific(arraysize(registers), registers);
195 }
196
197
198 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
199     CallInterfaceDescriptorData* data) {
200   data->InitializePlatformSpecific(0, nullptr, nullptr);
201 }
202
203
204 void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
205     CallInterfaceDescriptorData* data) {
206   // register state
207   // r0 -- number of arguments
208   // r1 -- function
209   // r2 -- allocation site with elements kind
210   Register registers[] = {r1, r2};
211   data->InitializePlatformSpecific(arraysize(registers), registers);
212 }
213
214
215 void ArrayConstructorDescriptor::InitializePlatformSpecific(
216     CallInterfaceDescriptorData* data) {
217   // stack param count needs (constructor pointer, and single argument)
218   Register registers[] = {r1, r2, r0};
219   data->InitializePlatformSpecific(arraysize(registers), registers);
220 }
221
222
223 void InternalArrayConstructorConstantArgCountDescriptor::
224     InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
225   // register state
226   // r0 -- number of arguments
227   // r1 -- constructor function
228   Register registers[] = {r1};
229   data->InitializePlatformSpecific(arraysize(registers), registers);
230 }
231
232
233 void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
234     CallInterfaceDescriptorData* data) {
235   // stack param count needs (constructor pointer, and single argument)
236   Register registers[] = {r1, r0};
237   data->InitializePlatformSpecific(arraysize(registers), registers);
238 }
239
240
241 void CompareDescriptor::InitializePlatformSpecific(
242     CallInterfaceDescriptorData* data) {
243   Register registers[] = {r1, r0};
244   data->InitializePlatformSpecific(arraysize(registers), registers);
245 }
246
247
248 void CompareNilDescriptor::InitializePlatformSpecific(
249     CallInterfaceDescriptorData* data) {
250   Register registers[] = {r0};
251   data->InitializePlatformSpecific(arraysize(registers), registers);
252 }
253
254
255 void ToBooleanDescriptor::InitializePlatformSpecific(
256     CallInterfaceDescriptorData* data) {
257   Register registers[] = {r0};
258   data->InitializePlatformSpecific(arraysize(registers), registers);
259 }
260
261
262 void BinaryOpDescriptor::InitializePlatformSpecific(
263     CallInterfaceDescriptorData* data) {
264   Register registers[] = {r1, r0};
265   data->InitializePlatformSpecific(arraysize(registers), registers);
266 }
267
268
269 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
270     CallInterfaceDescriptorData* data) {
271   Register registers[] = {r2, r1, r0};
272   data->InitializePlatformSpecific(arraysize(registers), registers);
273 }
274
275
276 void StringAddDescriptor::InitializePlatformSpecific(
277     CallInterfaceDescriptorData* data) {
278   Register registers[] = {r1, r0};
279   data->InitializePlatformSpecific(arraysize(registers), registers);
280 }
281
282
283 void KeyedDescriptor::InitializePlatformSpecific(
284     CallInterfaceDescriptorData* data) {
285   static PlatformInterfaceDescriptor noInlineDescriptor =
286       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
287
288   Register registers[] = {
289       r2,  // key
290   };
291   data->InitializePlatformSpecific(arraysize(registers), registers,
292                                    &noInlineDescriptor);
293 }
294
295
296 void NamedDescriptor::InitializePlatformSpecific(
297     CallInterfaceDescriptorData* data) {
298   static PlatformInterfaceDescriptor noInlineDescriptor =
299       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
300
301   Register registers[] = {
302       r2,  // name
303   };
304   data->InitializePlatformSpecific(arraysize(registers), registers,
305                                    &noInlineDescriptor);
306 }
307
308
309 void CallHandlerDescriptor::InitializePlatformSpecific(
310     CallInterfaceDescriptorData* data) {
311   static PlatformInterfaceDescriptor default_descriptor =
312       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
313
314   Register registers[] = {
315       r0,  // receiver
316   };
317   data->InitializePlatformSpecific(arraysize(registers), registers,
318                                    &default_descriptor);
319 }
320
321
322 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
323     CallInterfaceDescriptorData* data) {
324   static PlatformInterfaceDescriptor default_descriptor =
325       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
326
327   Register registers[] = {
328       r1,  // JSFunction
329       r0,  // actual number of arguments
330       r2,  // expected number of arguments
331   };
332   data->InitializePlatformSpecific(arraysize(registers), registers,
333                                    &default_descriptor);
334 }
335
336
337 void ApiFunctionDescriptor::InitializePlatformSpecific(
338     CallInterfaceDescriptorData* data) {
339   static PlatformInterfaceDescriptor default_descriptor =
340       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
341
342   Register registers[] = {
343       r0,  // callee
344       r4,  // call_data
345       r2,  // holder
346       r1,  // api_function_address
347       r3,  // actual number of arguments
348   };
349   data->InitializePlatformSpecific(arraysize(registers), registers,
350                                    &default_descriptor);
351 }
352
353
354 void ApiAccessorDescriptor::InitializePlatformSpecific(
355     CallInterfaceDescriptorData* data) {
356   static PlatformInterfaceDescriptor default_descriptor =
357       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
358
359   Register registers[] = {
360       r0,  // callee
361       r4,  // call_data
362       r2,  // holder
363       r1,  // api_function_address
364   };
365   data->InitializePlatformSpecific(arraysize(registers), registers,
366                                    &default_descriptor);
367 }
368
369
370 void MathRoundVariantCallFromUnoptimizedCodeDescriptor::
371     InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
372   Register registers[] = {
373       r1,  // math rounding function
374       r3,  // vector slot id
375   };
376   data->InitializePlatformSpecific(arraysize(registers), registers);
377 }
378
379
380 void MathRoundVariantCallFromOptimizedCodeDescriptor::
381     InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
382   Register registers[] = {
383       r1,  // math rounding function
384       r3,  // vector slot id
385       r4,  // type vector
386   };
387   data->InitializePlatformSpecific(arraysize(registers), registers);
388 }
389 }  // namespace internal
390 }  // namespace v8
391
392 #endif  // V8_TARGET_ARCH_ARM