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.
9 #include "src/interface-descriptors.h"
14 const Register CallInterfaceDescriptor::ContextRegister() { return esi; }
17 const Register LoadDescriptor::ReceiverRegister() { return edx; }
18 const Register LoadDescriptor::NameRegister() { return ecx; }
19 const Register LoadDescriptor::SlotRegister() { return eax; }
21 const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
24 const Register StoreDescriptor::ReceiverRegister() { return edx; }
25 const Register StoreDescriptor::NameRegister() { return ecx; }
26 const Register StoreDescriptor::ValueRegister() { return eax; }
29 const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return edi; }
32 const Register VectorStoreICDescriptor::VectorRegister() { return ebx; }
35 const Register StoreTransitionDescriptor::MapRegister() {
36 return FLAG_vector_stores ? no_reg : ebx;
40 const Register LoadGlobalViaContextDescriptor::SlotRegister() { return ebx; }
43 const Register StoreGlobalViaContextDescriptor::SlotRegister() { return ebx; }
44 const Register StoreGlobalViaContextDescriptor::ValueRegister() { return eax; }
47 const Register InstanceofDescriptor::left() { return eax; }
48 const Register InstanceofDescriptor::right() { return edx; }
51 const Register ArgumentsAccessReadDescriptor::index() { return edx; }
52 const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; }
55 const Register ApiGetterDescriptor::function_address() { return edx; }
58 const Register MathPowTaggedDescriptor::exponent() { return eax; }
61 const Register MathPowIntegerDescriptor::exponent() {
62 return MathPowTaggedDescriptor::exponent();
66 const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
67 const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; }
70 void StoreTransitionDescriptor::InitializePlatformSpecific(
71 CallInterfaceDescriptorData* data) {
72 Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
75 // When FLAG_vector_stores is true, we want to pass the map register on the
76 // stack instead of in a register.
77 DCHECK(FLAG_vector_stores || !MapRegister().is(no_reg));
79 int register_count = FLAG_vector_stores ? 3 : 4;
80 data->InitializePlatformSpecific(register_count, registers);
84 void FastNewClosureDescriptor::InitializePlatformSpecific(
85 CallInterfaceDescriptorData* data) {
86 Register registers[] = {ebx};
87 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
91 void FastNewContextDescriptor::InitializePlatformSpecific(
92 CallInterfaceDescriptorData* data) {
93 Register registers[] = {edi};
94 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
98 void ToNumberDescriptor::InitializePlatformSpecific(
99 CallInterfaceDescriptorData* data) {
100 // ToNumberStub invokes a function, and therefore needs a context.
101 Register registers[] = {eax};
102 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
107 const Register ToObjectDescriptor::ReceiverRegister() { return eax; }
110 void NumberToStringDescriptor::InitializePlatformSpecific(
111 CallInterfaceDescriptorData* data) {
112 Register registers[] = {eax};
113 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
117 void TypeofDescriptor::InitializePlatformSpecific(
118 CallInterfaceDescriptorData* data) {
119 Register registers[] = {ebx};
120 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
124 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
125 CallInterfaceDescriptorData* data) {
126 Register registers[] = {eax, ebx, ecx};
127 data->InitializePlatformSpecific(arraysize(registers), registers);
131 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
132 CallInterfaceDescriptorData* data) {
133 Register registers[] = {eax, ebx, ecx, edx};
134 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
138 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
139 CallInterfaceDescriptorData* data) {
140 Register registers[] = {ebx, edx};
141 data->InitializePlatformSpecific(arraysize(registers), registers);
145 void CreateWeakCellDescriptor::InitializePlatformSpecific(
146 CallInterfaceDescriptorData* data) {
147 Register registers[] = {ebx, edx, edi};
148 data->InitializePlatformSpecific(arraysize(registers), registers);
152 void StoreArrayLiteralElementDescriptor::InitializePlatformSpecific(
153 CallInterfaceDescriptorData* data) {
154 Register registers[] = {ecx, eax};
155 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
159 void CallFunctionDescriptor::InitializePlatformSpecific(
160 CallInterfaceDescriptorData* data) {
161 Register registers[] = {edi};
162 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
166 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
167 CallInterfaceDescriptorData* data) {
168 Register registers[] = {edi, edx};
169 data->InitializePlatformSpecific(arraysize(registers), registers);
173 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
174 CallInterfaceDescriptorData* data) {
175 Register registers[] = {edi, edx, ebx};
176 data->InitializePlatformSpecific(arraysize(registers), registers);
180 void CallConstructDescriptor::InitializePlatformSpecific(
181 CallInterfaceDescriptorData* data) {
182 // eax : number of arguments
183 // ebx : feedback vector
184 // ecx : original constructor (for IsSuperConstructorCall)
185 // edx : slot in feedback vector (Smi, for RecordCallTarget)
186 // edi : constructor function
187 // TODO(turbofan): So far we don't gather type feedback and hence skip the
188 // slot parameter, but ArrayConstructStub needs the vector to be undefined.
189 Register registers[] = {eax, edi, ecx, ebx};
190 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
194 void RegExpConstructResultDescriptor::InitializePlatformSpecific(
195 CallInterfaceDescriptorData* data) {
196 Register registers[] = {ecx, ebx, eax};
197 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
201 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
202 CallInterfaceDescriptorData* data) {
203 Register registers[] = {eax, ebx};
204 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
208 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
209 CallInterfaceDescriptorData* data) {
211 data->InitializePlatformSpecific(0, nullptr, nullptr);
215 void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
216 CallInterfaceDescriptorData* data) {
218 // eax -- number of arguments
220 // ebx -- allocation site with elements kind
221 Register registers[] = {edi, ebx};
222 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
226 void ArrayConstructorDescriptor::InitializePlatformSpecific(
227 CallInterfaceDescriptorData* data) {
228 // stack param count needs (constructor pointer, and single argument)
229 Register registers[] = {edi, ebx, eax};
230 data->InitializePlatformSpecific(arraysize(registers), registers);
234 void InternalArrayConstructorConstantArgCountDescriptor::
235 InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
237 // eax -- number of arguments
239 Register registers[] = {edi};
240 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
244 void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
245 CallInterfaceDescriptorData* data) {
246 // stack param count needs (constructor pointer, and single argument)
247 Register registers[] = {edi, eax};
248 data->InitializePlatformSpecific(arraysize(registers), registers);
252 void CompareDescriptor::InitializePlatformSpecific(
253 CallInterfaceDescriptorData* data) {
254 Register registers[] = {edx, eax};
255 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
259 void CompareNilDescriptor::InitializePlatformSpecific(
260 CallInterfaceDescriptorData* data) {
261 Register registers[] = {eax};
262 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
266 void ToBooleanDescriptor::InitializePlatformSpecific(
267 CallInterfaceDescriptorData* data) {
268 Register registers[] = {eax};
269 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
273 void BinaryOpDescriptor::InitializePlatformSpecific(
274 CallInterfaceDescriptorData* data) {
275 Register registers[] = {edx, eax};
276 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
280 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
281 CallInterfaceDescriptorData* data) {
282 Register registers[] = {ecx, edx, eax};
283 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
287 void StringAddDescriptor::InitializePlatformSpecific(
288 CallInterfaceDescriptorData* data) {
289 Register registers[] = {edx, eax};
290 data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
294 void KeyedDescriptor::InitializePlatformSpecific(
295 CallInterfaceDescriptorData* data) {
296 Register registers[] = {
299 data->InitializePlatformSpecific(arraysize(registers), registers);
303 void NamedDescriptor::InitializePlatformSpecific(
304 CallInterfaceDescriptorData* data) {
305 Register registers[] = {
308 data->InitializePlatformSpecific(arraysize(registers), registers);
312 void CallHandlerDescriptor::InitializePlatformSpecific(
313 CallInterfaceDescriptorData* data) {
314 Register registers[] = {
317 data->InitializePlatformSpecific(arraysize(registers), registers);
321 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
322 CallInterfaceDescriptorData* data) {
323 Register registers[] = {
325 eax, // actual number of arguments
326 ebx, // expected number of arguments
328 data->InitializePlatformSpecific(arraysize(registers), registers);
332 void ApiFunctionDescriptor::InitializePlatformSpecific(
333 CallInterfaceDescriptorData* data) {
334 Register registers[] = {
338 edx, // api_function_address
339 eax, // actual number of arguments
341 data->InitializePlatformSpecific(arraysize(registers), registers);
345 void ApiAccessorDescriptor::InitializePlatformSpecific(
346 CallInterfaceDescriptorData* data) {
347 Register registers[] = {
351 edx, // api_function_address
353 data->InitializePlatformSpecific(arraysize(registers), registers);
357 void MathRoundVariantCallFromUnoptimizedCodeDescriptor::
358 InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
359 Register registers[] = {
360 edi, // math rounding function
361 edx, // vector slot id
363 data->InitializePlatformSpecific(arraysize(registers), registers);
367 void MathRoundVariantCallFromOptimizedCodeDescriptor::
368 InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
369 Register registers[] = {
370 edi, // math rounding function
371 edx, // vector slot id
374 data->InitializePlatformSpecific(arraysize(registers), registers);
376 } // namespace internal
379 #endif // V8_TARGET_ARCH_X87