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