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