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