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