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