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