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