• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   // SharedFunctionInfo, vector, slot index.
68   Register registers[] = {ebx, ecx, edx};
69   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
70 }
71 
72 // static
ArgumentRegister()73 const Register TypeConversionDescriptor::ArgumentRegister() { return eax; }
74 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)75 void TypeofDescriptor::InitializePlatformSpecific(
76     CallInterfaceDescriptorData* data) {
77   Register registers[] = {ebx};
78   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
79 }
80 
81 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)82 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
83     CallInterfaceDescriptorData* data) {
84   Register registers[] = {edi, eax, ecx, edx};
85   data->InitializePlatformSpecific(arraysize(registers), registers);
86 }
87 
88 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)89 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
90     CallInterfaceDescriptorData* data) {
91   Register registers[] = {eax, ebx, ecx};
92   data->InitializePlatformSpecific(arraysize(registers), registers);
93 }
94 
95 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)96 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
97     CallInterfaceDescriptorData* data) {
98   Register registers[] = {eax, ebx, ecx, edx};
99   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
100 }
101 
102 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)103 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
104     CallInterfaceDescriptorData* data) {
105   Register registers[] = {ebx, edx};
106   data->InitializePlatformSpecific(arraysize(registers), registers);
107 }
108 
109 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)110 void CreateWeakCellDescriptor::InitializePlatformSpecific(
111     CallInterfaceDescriptorData* data) {
112   Register registers[] = {ebx, edx, edi};
113   data->InitializePlatformSpecific(arraysize(registers), registers);
114 }
115 
116 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)117 void CallFunctionDescriptor::InitializePlatformSpecific(
118     CallInterfaceDescriptorData* data) {
119   Register registers[] = {edi};
120   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
121 }
122 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)123 void CallICTrampolineDescriptor::InitializePlatformSpecific(
124     CallInterfaceDescriptorData* data) {
125   Register registers[] = {edi, eax, edx};
126   data->InitializePlatformSpecific(arraysize(registers), registers);
127 }
128 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)129 void CallICDescriptor::InitializePlatformSpecific(
130     CallInterfaceDescriptorData* data) {
131   Register registers[] = {edi, eax, edx, ebx};
132   data->InitializePlatformSpecific(arraysize(registers), registers);
133 }
134 
135 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)136 void CallConstructDescriptor::InitializePlatformSpecific(
137     CallInterfaceDescriptorData* data) {
138   // eax : number of arguments
139   // ebx : feedback vector
140   // ecx : new target (for IsSuperConstructorCall)
141   // edx : slot in feedback vector (Smi, for RecordCallTarget)
142   // edi : constructor function
143   // TODO(turbofan): So far we don't gather type feedback and hence skip the
144   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
145   Register registers[] = {eax, edi, ecx, ebx};
146   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
147 }
148 
149 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)150 void CallTrampolineDescriptor::InitializePlatformSpecific(
151     CallInterfaceDescriptorData* data) {
152   // eax : number of arguments
153   // edi : the target to call
154   Register registers[] = {edi, eax};
155   data->InitializePlatformSpecific(arraysize(registers), registers);
156 }
157 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)158 void CallForwardVarargsDescriptor::InitializePlatformSpecific(
159     CallInterfaceDescriptorData* data) {
160   // ecx : start index (to support rest parameters)
161   // edi : the target to call
162   Register registers[] = {edi, ecx};
163   data->InitializePlatformSpecific(arraysize(registers), registers);
164 }
165 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)166 void ConstructStubDescriptor::InitializePlatformSpecific(
167     CallInterfaceDescriptorData* data) {
168   // eax : number of arguments
169   // edx : the new target
170   // edi : the target to call
171   // ebx : allocation site or undefined
172   Register registers[] = {edi, edx, eax, ebx};
173   data->InitializePlatformSpecific(arraysize(registers), registers);
174 }
175 
176 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)177 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
178     CallInterfaceDescriptorData* data) {
179   // eax : number of arguments
180   // edx : the new target
181   // edi : the target to call
182   Register registers[] = {edi, edx, eax};
183   data->InitializePlatformSpecific(arraysize(registers), registers);
184 }
185 
186 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)187 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
188     CallInterfaceDescriptorData* data) {
189   Register registers[] = {eax, ebx};
190   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
191 }
192 
193 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)194 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
195     CallInterfaceDescriptorData* data) {
196   // register state
197   data->InitializePlatformSpecific(0, nullptr, nullptr);
198 }
199 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)200 void ArrayConstructorDescriptor::InitializePlatformSpecific(
201     CallInterfaceDescriptorData* data) {
202   // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite
203   Register registers[] = {edi, edx, eax, ebx};
204   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
205 }
206 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)207 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
208     CallInterfaceDescriptorData* data) {
209   // register state
210   // eax -- number of arguments
211   // edi -- function
212   // ebx -- allocation site with elements kind
213   Register registers[] = {edi, ebx, eax};
214   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
215 }
216 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)217 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
218     CallInterfaceDescriptorData* data) {
219   // register state
220   // eax -- number of arguments
221   // edi -- function
222   // ebx -- allocation site with elements kind
223   Register registers[] = {edi, ebx, eax};
224   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
225 }
226 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)227 void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
228     CallInterfaceDescriptorData* data) {
229   // register state
230   // eax -- number of arguments
231   // edi -- function
232   // ebx -- allocation site with elements kind
233   Register registers[] = {edi, ebx, eax};
234   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
235 }
236 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)237 void VarArgFunctionDescriptor::InitializePlatformSpecific(
238     CallInterfaceDescriptorData* data) {
239   // stack param count needs (arg count)
240   Register registers[] = {eax};
241   data->InitializePlatformSpecific(arraysize(registers), registers);
242 }
243 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)244 void CompareDescriptor::InitializePlatformSpecific(
245     CallInterfaceDescriptorData* data) {
246   Register registers[] = {edx, eax};
247   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
248 }
249 
250 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)251 void BinaryOpDescriptor::InitializePlatformSpecific(
252     CallInterfaceDescriptorData* data) {
253   Register registers[] = {edx, eax};
254   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
255 }
256 
257 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)258 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
259     CallInterfaceDescriptorData* data) {
260   Register registers[] = {ecx, edx, eax};
261   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
262 }
263 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)264 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
265     CallInterfaceDescriptorData* data) {
266   // register state
267   // edx -- lhs
268   // eax -- rhs
269   // edi -- slot id
270   // ebx -- vector
271   Register registers[] = {edx, eax, edi, ebx};
272   data->InitializePlatformSpecific(arraysize(registers), registers);
273 }
274 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)275 void CountOpDescriptor::InitializePlatformSpecific(
276     CallInterfaceDescriptorData* data) {
277   Register registers[] = {eax};
278   data->InitializePlatformSpecific(arraysize(registers), registers);
279 }
280 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)281 void StringAddDescriptor::InitializePlatformSpecific(
282     CallInterfaceDescriptorData* data) {
283   Register registers[] = {edx, eax};
284   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
285 }
286 
287 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)288 void KeyedDescriptor::InitializePlatformSpecific(
289     CallInterfaceDescriptorData* data) {
290   Register registers[] = {
291       ecx,  // key
292   };
293   data->InitializePlatformSpecific(arraysize(registers), registers);
294 }
295 
296 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)297 void NamedDescriptor::InitializePlatformSpecific(
298     CallInterfaceDescriptorData* data) {
299   Register registers[] = {
300       ecx,  // name
301   };
302   data->InitializePlatformSpecific(arraysize(registers), registers);
303 }
304 
305 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)306 void CallHandlerDescriptor::InitializePlatformSpecific(
307     CallInterfaceDescriptorData* data) {
308   Register registers[] = {
309       edx,  // name
310   };
311   data->InitializePlatformSpecific(arraysize(registers), registers);
312 }
313 
314 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)315 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
316     CallInterfaceDescriptorData* data) {
317   Register registers[] = {
318       edi,  // JSFunction
319       edx,  // the new target
320       eax,  // actual number of arguments
321       ebx,  // expected number of arguments
322   };
323   data->InitializePlatformSpecific(arraysize(registers), registers);
324 }
325 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)326 void ApiCallbackDescriptor::InitializePlatformSpecific(
327     CallInterfaceDescriptorData* data) {
328   Register registers[] = {
329       edi,  // callee
330       ebx,  // call_data
331       ecx,  // holder
332       edx,  // api_function_address
333   };
334   data->InitializePlatformSpecific(arraysize(registers), registers);
335 }
336 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)337 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
338     CallInterfaceDescriptorData* data) {
339   Register registers[] = {
340       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
341       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
342   data->InitializePlatformSpecific(arraysize(registers), registers);
343 }
344 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)345 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
346     CallInterfaceDescriptorData* data) {
347   Register registers[] = {
348       eax,  // argument count (not including receiver)
349       ebx,  // address of first argument
350       edi   // the target callable to be call
351   };
352   data->InitializePlatformSpecific(arraysize(registers), registers);
353 }
354 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)355 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
356     CallInterfaceDescriptorData* data) {
357   Register registers[] = {
358       eax,  // argument count (not including receiver)
359       edx,  // new target
360       edi,  // constructor
361       ebx,  // allocation site feedback
362       ecx,  // address of first argument
363   };
364   data->InitializePlatformSpecific(arraysize(registers), registers);
365 }
366 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)367 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
368     CallInterfaceDescriptorData* data) {
369   Register registers[] = {
370       eax,  // argument count (not including receiver)
371       edx,  // target to the call. It is checked to be Array function.
372       ebx,  // allocation site feedback
373       ecx,  // address of first argument
374   };
375   data->InitializePlatformSpecific(arraysize(registers), registers);
376 }
377 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)378 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
379     CallInterfaceDescriptorData* data) {
380   Register registers[] = {
381       eax,  // argument count (argc)
382       ecx,  // address of first argument (argv)
383       ebx   // the runtime function to call
384   };
385   data->InitializePlatformSpecific(arraysize(registers), registers);
386 }
387 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)388 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
389     CallInterfaceDescriptorData* data) {
390   Register registers[] = {
391       eax,  // the value to pass to the generator
392       ebx,  // the JSGeneratorObject to resume
393       edx   // the resume mode (tagged)
394   };
395   data->InitializePlatformSpecific(arraysize(registers), registers);
396 }
397 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)398 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
399     CallInterfaceDescriptorData* data) {
400   Register registers[] = {
401       ebx,  // loaded new FP
402   };
403   data->InitializePlatformSpecific(arraysize(registers), registers);
404 }
405 
406 }  // namespace internal
407 }  // namespace v8
408 
409 #endif  // V8_TARGET_ARCH_IA32
410