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