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_IA32
6 
7 #include "src/interface-descriptors.h"
8 
9 namespace v8 {
10 namespace internal {
11 
ContextRegister()12 const Register CallInterfaceDescriptor::ContextRegister() { return esi; }
13 
DefaultInitializePlatformSpecific(CallInterfaceDescriptorData * data,int register_parameter_count)14 void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
15     CallInterfaceDescriptorData* data, int register_parameter_count) {
16   const Register default_stub_registers[] = {eax, ebx, ecx, edx, edi};
17   CHECK_LE(static_cast<size_t>(register_parameter_count),
18            arraysize(default_stub_registers));
19   data->InitializePlatformSpecific(register_parameter_count,
20                                    default_stub_registers);
21 }
22 
FunctionRegister()23 const Register FastNewFunctionContextDescriptor::FunctionRegister() {
24   return edi;
25 }
SlotsRegister()26 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return eax; }
27 
ReceiverRegister()28 const Register LoadDescriptor::ReceiverRegister() { return edx; }
NameRegister()29 const Register LoadDescriptor::NameRegister() { return ecx; }
SlotRegister()30 const Register LoadDescriptor::SlotRegister() { return eax; }
31 
VectorRegister()32 const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
33 
HandlerRegister()34 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; }
35 
ReceiverRegister()36 const Register StoreDescriptor::ReceiverRegister() { return edx; }
NameRegister()37 const Register StoreDescriptor::NameRegister() { return ecx; }
ValueRegister()38 const Register StoreDescriptor::ValueRegister() { return eax; }
SlotRegister()39 const Register StoreDescriptor::SlotRegister() { return edi; }
40 
VectorRegister()41 const Register StoreWithVectorDescriptor::VectorRegister() { return ebx; }
42 
SlotRegister()43 const Register StoreTransitionDescriptor::SlotRegister() { return no_reg; }
VectorRegister()44 const Register StoreTransitionDescriptor::VectorRegister() { return ebx; }
MapRegister()45 const Register StoreTransitionDescriptor::MapRegister() { return edi; }
46 
LeftRegister()47 const Register StringCompareDescriptor::LeftRegister() { return edx; }
RightRegister()48 const Register StringCompareDescriptor::RightRegister() { return eax; }
49 
HolderRegister()50 const Register ApiGetterDescriptor::HolderRegister() { return ecx; }
CallbackRegister()51 const Register ApiGetterDescriptor::CallbackRegister() { return eax; }
52 
exponent()53 const Register MathPowTaggedDescriptor::exponent() { return eax; }
54 
55 
exponent()56 const Register MathPowIntegerDescriptor::exponent() {
57   return MathPowTaggedDescriptor::exponent();
58 }
59 
60 
ObjectRegister()61 const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
KeyRegister()62 const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; }
63 
64 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)65 void FastNewClosureDescriptor::InitializePlatformSpecific(
66     CallInterfaceDescriptorData* data) {
67   Register registers[] = {ebx};
68   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
69 }
70 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)71 void FastNewObjectDescriptor::InitializePlatformSpecific(
72     CallInterfaceDescriptorData* data) {
73   Register registers[] = {edi, edx};
74   data->InitializePlatformSpecific(arraysize(registers), registers);
75 }
76 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)77 void FastNewRestParameterDescriptor::InitializePlatformSpecific(
78     CallInterfaceDescriptorData* data) {
79   Register registers[] = {edi};
80   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
81 }
82 
83 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)84 void FastNewSloppyArgumentsDescriptor::InitializePlatformSpecific(
85     CallInterfaceDescriptorData* data) {
86   Register registers[] = {edi};
87   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
88 }
89 
90 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)91 void FastNewStrictArgumentsDescriptor::InitializePlatformSpecific(
92     CallInterfaceDescriptorData* data) {
93   Register registers[] = {edi};
94   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
95 }
96 
97 
98 // static
ArgumentRegister()99 const Register TypeConversionDescriptor::ArgumentRegister() { return eax; }
100 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)101 void TypeofDescriptor::InitializePlatformSpecific(
102     CallInterfaceDescriptorData* data) {
103   Register registers[] = {ebx};
104   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
105 }
106 
107 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)108 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
109     CallInterfaceDescriptorData* data) {
110   Register registers[] = {edi, eax, ecx, edx};
111   data->InitializePlatformSpecific(arraysize(registers), registers);
112 }
113 
114 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)115 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
116     CallInterfaceDescriptorData* data) {
117   Register registers[] = {eax, ebx, ecx};
118   data->InitializePlatformSpecific(arraysize(registers), registers);
119 }
120 
121 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)122 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
123     CallInterfaceDescriptorData* data) {
124   Register registers[] = {eax, ebx, ecx, edx};
125   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
126 }
127 
128 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)129 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
130     CallInterfaceDescriptorData* data) {
131   Register registers[] = {ebx, edx};
132   data->InitializePlatformSpecific(arraysize(registers), registers);
133 }
134 
135 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)136 void CreateWeakCellDescriptor::InitializePlatformSpecific(
137     CallInterfaceDescriptorData* data) {
138   Register registers[] = {ebx, edx, edi};
139   data->InitializePlatformSpecific(arraysize(registers), registers);
140 }
141 
142 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)143 void CallFunctionDescriptor::InitializePlatformSpecific(
144     CallInterfaceDescriptorData* data) {
145   Register registers[] = {edi};
146   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
147 }
148 
149 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)150 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
151     CallInterfaceDescriptorData* data) {
152   Register registers[] = {edi, edx};
153   data->InitializePlatformSpecific(arraysize(registers), registers);
154 }
155 
156 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)157 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
158     CallInterfaceDescriptorData* data) {
159   Register registers[] = {edi, eax, edx, ebx};
160   data->InitializePlatformSpecific(arraysize(registers), registers);
161 }
162 
163 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)164 void CallConstructDescriptor::InitializePlatformSpecific(
165     CallInterfaceDescriptorData* data) {
166   // eax : number of arguments
167   // ebx : feedback vector
168   // ecx : new target (for IsSuperConstructorCall)
169   // edx : slot in feedback vector (Smi, for RecordCallTarget)
170   // edi : constructor function
171   // TODO(turbofan): So far we don't gather type feedback and hence skip the
172   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
173   Register registers[] = {eax, edi, ecx, ebx};
174   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
175 }
176 
177 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)178 void CallTrampolineDescriptor::InitializePlatformSpecific(
179     CallInterfaceDescriptorData* data) {
180   // eax : number of arguments
181   // edi : the target to call
182   Register registers[] = {edi, eax};
183   data->InitializePlatformSpecific(arraysize(registers), registers);
184 }
185 
186 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)187 void ConstructStubDescriptor::InitializePlatformSpecific(
188     CallInterfaceDescriptorData* data) {
189   // eax : number of arguments
190   // edx : the new target
191   // edi : the target to call
192   // ebx : allocation site or undefined
193   Register registers[] = {edi, edx, eax, ebx};
194   data->InitializePlatformSpecific(arraysize(registers), registers);
195 }
196 
197 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)198 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
199     CallInterfaceDescriptorData* data) {
200   // eax : number of arguments
201   // edx : the new target
202   // edi : the target to call
203   Register registers[] = {edi, edx, eax};
204   data->InitializePlatformSpecific(arraysize(registers), registers);
205 }
206 
207 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)208 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
209     CallInterfaceDescriptorData* data) {
210   Register registers[] = {eax, ebx};
211   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
212 }
213 
214 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)215 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
216     CallInterfaceDescriptorData* data) {
217   // register state
218   data->InitializePlatformSpecific(0, nullptr, nullptr);
219 }
220 
221 #define SIMD128_ALLOC_DESC(TYPE, Type, type, lane_count, lane_type) \
222   void Allocate##Type##Descriptor::InitializePlatformSpecific(      \
223       CallInterfaceDescriptorData* data) {                          \
224     data->InitializePlatformSpecific(0, nullptr, nullptr);          \
225   }
SIMD128_TYPES(SIMD128_ALLOC_DESC)226 SIMD128_TYPES(SIMD128_ALLOC_DESC)
227 #undef SIMD128_ALLOC_DESC
228 
229 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
230     CallInterfaceDescriptorData* data) {
231   // register state
232   // eax -- number of arguments
233   // edi -- function
234   // ebx -- allocation site with elements kind
235   Register registers[] = {edi, ebx, eax};
236   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
237 }
238 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)239 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
240     CallInterfaceDescriptorData* data) {
241   // register state
242   // eax -- number of arguments
243   // edi -- function
244   // ebx -- allocation site with elements kind
245   Register registers[] = {edi, ebx, eax};
246   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
247 }
248 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)249 void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
250     CallInterfaceDescriptorData* data) {
251   // register state
252   // eax -- number of arguments
253   // edi -- function
254   // ebx -- allocation site with elements kind
255   Register registers[] = {edi, ebx, eax};
256   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
257 }
258 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)259 void VarArgFunctionDescriptor::InitializePlatformSpecific(
260     CallInterfaceDescriptorData* data) {
261   // stack param count needs (arg count)
262   Register registers[] = {eax};
263   data->InitializePlatformSpecific(arraysize(registers), registers);
264 }
265 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)266 void CompareDescriptor::InitializePlatformSpecific(
267     CallInterfaceDescriptorData* data) {
268   Register registers[] = {edx, eax};
269   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
270 }
271 
272 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)273 void BinaryOpDescriptor::InitializePlatformSpecific(
274     CallInterfaceDescriptorData* data) {
275   Register registers[] = {edx, eax};
276   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
277 }
278 
279 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)280 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
281     CallInterfaceDescriptorData* data) {
282   Register registers[] = {ecx, edx, eax};
283   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
284 }
285 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)286 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
287     CallInterfaceDescriptorData* data) {
288   // register state
289   // edx -- lhs
290   // eax -- rhs
291   // edi -- slot id
292   // ebx -- vector
293   Register registers[] = {edx, eax, edi, ebx};
294   data->InitializePlatformSpecific(arraysize(registers), registers);
295 }
296 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)297 void CountOpDescriptor::InitializePlatformSpecific(
298     CallInterfaceDescriptorData* data) {
299   Register registers[] = {eax};
300   data->InitializePlatformSpecific(arraysize(registers), registers);
301 }
302 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)303 void StringAddDescriptor::InitializePlatformSpecific(
304     CallInterfaceDescriptorData* data) {
305   Register registers[] = {edx, eax};
306   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
307 }
308 
309 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)310 void KeyedDescriptor::InitializePlatformSpecific(
311     CallInterfaceDescriptorData* data) {
312   Register registers[] = {
313       ecx,  // key
314   };
315   data->InitializePlatformSpecific(arraysize(registers), registers);
316 }
317 
318 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)319 void NamedDescriptor::InitializePlatformSpecific(
320     CallInterfaceDescriptorData* data) {
321   Register registers[] = {
322       ecx,  // name
323   };
324   data->InitializePlatformSpecific(arraysize(registers), registers);
325 }
326 
327 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)328 void CallHandlerDescriptor::InitializePlatformSpecific(
329     CallInterfaceDescriptorData* data) {
330   Register registers[] = {
331       edx,  // name
332   };
333   data->InitializePlatformSpecific(arraysize(registers), registers);
334 }
335 
336 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)337 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
338     CallInterfaceDescriptorData* data) {
339   Register registers[] = {
340       edi,  // JSFunction
341       edx,  // the new target
342       eax,  // actual number of arguments
343       ebx,  // expected number of arguments
344   };
345   data->InitializePlatformSpecific(arraysize(registers), registers);
346 }
347 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)348 void ApiCallbackDescriptor::InitializePlatformSpecific(
349     CallInterfaceDescriptorData* data) {
350   Register registers[] = {
351       edi,  // callee
352       ebx,  // call_data
353       ecx,  // holder
354       edx,  // api_function_address
355   };
356   data->InitializePlatformSpecific(arraysize(registers), registers);
357 }
358 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)359 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
360     CallInterfaceDescriptorData* data) {
361   Register registers[] = {
362       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
363       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
364   data->InitializePlatformSpecific(arraysize(registers), registers);
365 }
366 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)367 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
368     CallInterfaceDescriptorData* data) {
369   Register registers[] = {
370       eax,  // argument count (not including receiver)
371       ebx,  // address of first argument
372       edi   // the target callable to be call
373   };
374   data->InitializePlatformSpecific(arraysize(registers), registers);
375 }
376 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)377 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
378     CallInterfaceDescriptorData* data) {
379   Register registers[] = {
380       eax,  // argument count (not including receiver)
381       edx,  // new target
382       edi,  // constructor
383       ebx,  // allocation site feedback
384       ecx,  // address of first argument
385   };
386   data->InitializePlatformSpecific(arraysize(registers), registers);
387 }
388 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)389 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
390     CallInterfaceDescriptorData* data) {
391   Register registers[] = {
392       eax,  // argument count (not including receiver)
393       edx,  // target to the call. It is checked to be Array function.
394       ebx,  // allocation site feedback
395       ecx,  // address of first argument
396   };
397   data->InitializePlatformSpecific(arraysize(registers), registers);
398 }
399 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)400 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
401     CallInterfaceDescriptorData* data) {
402   Register registers[] = {
403       eax,  // argument count (argc)
404       ecx,  // address of first argument (argv)
405       ebx   // the runtime function to call
406   };
407   data->InitializePlatformSpecific(arraysize(registers), registers);
408 }
409 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)410 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
411     CallInterfaceDescriptorData* data) {
412   Register registers[] = {
413       eax,  // the value to pass to the generator
414       ebx,  // the JSGeneratorObject to resume
415       edx   // the resume mode (tagged)
416   };
417   data->InitializePlatformSpecific(arraysize(registers), registers);
418 }
419 
420 }  // namespace internal
421 }  // namespace v8
422 
423 #endif  // V8_TARGET_ARCH_IA32
424