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 
ContextRegister()14 const Register CallInterfaceDescriptor::ContextRegister() { return esi; }
15 
16 
ReceiverRegister()17 const Register LoadDescriptor::ReceiverRegister() { return edx; }
NameRegister()18 const Register LoadDescriptor::NameRegister() { return ecx; }
19 
20 
SlotRegister()21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return eax; }
22 
23 
VectorRegister()24 const Register VectorLoadICDescriptor::VectorRegister() { return ebx; }
25 
26 
ReceiverRegister()27 const Register StoreDescriptor::ReceiverRegister() { return edx; }
NameRegister()28 const Register StoreDescriptor::NameRegister() { return ecx; }
ValueRegister()29 const Register StoreDescriptor::ValueRegister() { return eax; }
30 
31 
MapRegister()32 const Register ElementTransitionAndStoreDescriptor::MapRegister() {
33   return ebx;
34 }
35 
36 
left()37 const Register InstanceofDescriptor::left() { return eax; }
right()38 const Register InstanceofDescriptor::right() { return edx; }
39 
40 
index()41 const Register ArgumentsAccessReadDescriptor::index() { return edx; }
parameter_count()42 const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; }
43 
44 
function_address()45 const Register ApiGetterDescriptor::function_address() { return edx; }
46 
47 
exponent()48 const Register MathPowTaggedDescriptor::exponent() { return eax; }
49 
50 
exponent()51 const Register MathPowIntegerDescriptor::exponent() {
52   return MathPowTaggedDescriptor::exponent();
53 }
54 
55 
Initialize(CallInterfaceDescriptorData * data)56 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
57   Register registers[] = {esi, ebx};
58   data->Initialize(arraysize(registers), registers, NULL);
59 }
60 
61 
Initialize(CallInterfaceDescriptorData * data)62 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
63   Register registers[] = {esi, edi};
64   data->Initialize(arraysize(registers), registers, NULL);
65 }
66 
67 
Initialize(CallInterfaceDescriptorData * data)68 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
69   // ToNumberStub invokes a function, and therefore needs a context.
70   Register registers[] = {esi, eax};
71   data->Initialize(arraysize(registers), registers, NULL);
72 }
73 
74 
Initialize(CallInterfaceDescriptorData * data)75 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
76   Register registers[] = {esi, eax};
77   data->Initialize(arraysize(registers), registers, NULL);
78 }
79 
80 
Initialize(CallInterfaceDescriptorData * data)81 void FastCloneShallowArrayDescriptor::Initialize(
82     CallInterfaceDescriptorData* data) {
83   Register registers[] = {esi, eax, ebx, ecx};
84   Representation representations[] = {
85       Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
86       Representation::Tagged()};
87   data->Initialize(arraysize(registers), registers, representations);
88 }
89 
90 
Initialize(CallInterfaceDescriptorData * data)91 void FastCloneShallowObjectDescriptor::Initialize(
92     CallInterfaceDescriptorData* data) {
93   Register registers[] = {esi, eax, ebx, ecx, edx};
94   data->Initialize(arraysize(registers), registers, NULL);
95 }
96 
97 
Initialize(CallInterfaceDescriptorData * data)98 void CreateAllocationSiteDescriptor::Initialize(
99     CallInterfaceDescriptorData* data) {
100   Register registers[] = {esi, ebx, edx};
101   data->Initialize(arraysize(registers), registers, NULL);
102 }
103 
104 
Initialize(CallInterfaceDescriptorData * data)105 void StoreArrayLiteralElementDescriptor::Initialize(
106     CallInterfaceDescriptorData* data) {
107   Register registers[] = {esi, ecx, eax};
108   data->Initialize(arraysize(registers), registers, NULL);
109 }
110 
111 
Initialize(CallInterfaceDescriptorData * data)112 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
113   Register registers[] = {esi, edi};
114   data->Initialize(arraysize(registers), registers, NULL);
115 }
116 
117 
Initialize(CallInterfaceDescriptorData * data)118 void CallFunctionWithFeedbackDescriptor::Initialize(
119     CallInterfaceDescriptorData* data) {
120   Register registers[] = {esi, edi, edx};
121   Representation representations[] = {Representation::Tagged(),
122                                       Representation::Tagged(),
123                                       Representation::Smi()};
124   data->Initialize(arraysize(registers), registers, representations);
125 }
126 
127 
Initialize(CallInterfaceDescriptorData * data)128 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
129   // eax : number of arguments
130   // ebx : feedback vector
131   // edx : (only if ebx is not the megamorphic symbol) slot in feedback
132   //       vector (Smi)
133   // edi : constructor function
134   // TODO(turbofan): So far we don't gather type feedback and hence skip the
135   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
136   Register registers[] = {esi, eax, edi, ebx};
137   data->Initialize(arraysize(registers), registers, NULL);
138 }
139 
140 
Initialize(CallInterfaceDescriptorData * data)141 void RegExpConstructResultDescriptor::Initialize(
142     CallInterfaceDescriptorData* data) {
143   Register registers[] = {esi, ecx, ebx, eax};
144   data->Initialize(arraysize(registers), registers, NULL);
145 }
146 
147 
Initialize(CallInterfaceDescriptorData * data)148 void TransitionElementsKindDescriptor::Initialize(
149     CallInterfaceDescriptorData* data) {
150   Register registers[] = {esi, eax, ebx};
151   data->Initialize(arraysize(registers), registers, NULL);
152 }
153 
154 
Initialize(CallInterfaceDescriptorData * data)155 void ArrayConstructorConstantArgCountDescriptor::Initialize(
156     CallInterfaceDescriptorData* data) {
157   // register state
158   // eax -- number of arguments
159   // edi -- function
160   // ebx -- allocation site with elements kind
161   Register registers[] = {esi, edi, ebx};
162   data->Initialize(arraysize(registers), registers, NULL);
163 }
164 
165 
Initialize(CallInterfaceDescriptorData * data)166 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
167   // stack param count needs (constructor pointer, and single argument)
168   Register registers[] = {esi, edi, ebx, eax};
169   Representation representations[] = {
170       Representation::Tagged(), Representation::Tagged(),
171       Representation::Tagged(), Representation::Integer32()};
172   data->Initialize(arraysize(registers), registers, representations);
173 }
174 
175 
Initialize(CallInterfaceDescriptorData * data)176 void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
177     CallInterfaceDescriptorData* data) {
178   // register state
179   // eax -- number of arguments
180   // edi -- function
181   Register registers[] = {esi, edi};
182   data->Initialize(arraysize(registers), registers, NULL);
183 }
184 
185 
Initialize(CallInterfaceDescriptorData * data)186 void InternalArrayConstructorDescriptor::Initialize(
187     CallInterfaceDescriptorData* data) {
188   // stack param count needs (constructor pointer, and single argument)
189   Register registers[] = {esi, edi, eax};
190   Representation representations[] = {Representation::Tagged(),
191                                       Representation::Tagged(),
192                                       Representation::Integer32()};
193   data->Initialize(arraysize(registers), registers, representations);
194 }
195 
196 
Initialize(CallInterfaceDescriptorData * data)197 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
198   Register registers[] = {esi, eax};
199   data->Initialize(arraysize(registers), registers, NULL);
200 }
201 
202 
Initialize(CallInterfaceDescriptorData * data)203 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
204   Register registers[] = {esi, eax};
205   data->Initialize(arraysize(registers), registers, NULL);
206 }
207 
208 
Initialize(CallInterfaceDescriptorData * data)209 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
210   Register registers[] = {esi, edx, eax};
211   data->Initialize(arraysize(registers), registers, NULL);
212 }
213 
214 
Initialize(CallInterfaceDescriptorData * data)215 void BinaryOpWithAllocationSiteDescriptor::Initialize(
216     CallInterfaceDescriptorData* data) {
217   Register registers[] = {esi, ecx, edx, eax};
218   data->Initialize(arraysize(registers), registers, NULL);
219 }
220 
221 
Initialize(CallInterfaceDescriptorData * data)222 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
223   Register registers[] = {esi, edx, eax};
224   data->Initialize(arraysize(registers), registers, NULL);
225 }
226 
227 
Initialize(CallInterfaceDescriptorData * data)228 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
229   Register registers[] = {
230       esi,  // context
231       ecx,  // key
232   };
233   Representation representations[] = {
234       Representation::Tagged(),  // context
235       Representation::Tagged(),  // key
236   };
237   data->Initialize(arraysize(registers), registers, representations);
238 }
239 
240 
Initialize(CallInterfaceDescriptorData * data)241 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
242   Register registers[] = {
243       esi,  // context
244       ecx,  // name
245   };
246   Representation representations[] = {
247       Representation::Tagged(),  // context
248       Representation::Tagged(),  // name
249   };
250   data->Initialize(arraysize(registers), registers, representations);
251 }
252 
253 
Initialize(CallInterfaceDescriptorData * data)254 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
255   Register registers[] = {
256       esi,  // context
257       edx,  // name
258   };
259   Representation representations[] = {
260       Representation::Tagged(),  // context
261       Representation::Tagged(),  // receiver
262   };
263   data->Initialize(arraysize(registers), registers, representations);
264 }
265 
266 
Initialize(CallInterfaceDescriptorData * data)267 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
268   Register registers[] = {
269       esi,  // context
270       edi,  // JSFunction
271       eax,  // actual number of arguments
272       ebx,  // expected number of arguments
273   };
274   Representation representations[] = {
275       Representation::Tagged(),     // context
276       Representation::Tagged(),     // JSFunction
277       Representation::Integer32(),  // actual number of arguments
278       Representation::Integer32(),  // expected number of arguments
279   };
280   data->Initialize(arraysize(registers), registers, representations);
281 }
282 
283 
Initialize(CallInterfaceDescriptorData * data)284 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
285   Register registers[] = {
286       esi,  // context
287       eax,  // callee
288       ebx,  // call_data
289       ecx,  // holder
290       edx,  // api_function_address
291   };
292   Representation representations[] = {
293       Representation::Tagged(),    // context
294       Representation::Tagged(),    // callee
295       Representation::Tagged(),    // call_data
296       Representation::Tagged(),    // holder
297       Representation::External(),  // api_function_address
298   };
299   data->Initialize(arraysize(registers), registers, representations);
300 }
301 }
302 }  // namespace v8::internal
303 
304 #endif  // V8_TARGET_ARCH_X87
305