• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/codegen/interface-descriptors.h"
8 
9 #include "src/execution/frames.h"
10 
11 namespace v8 {
12 namespace internal {
13 
ContextRegister()14 const Register CallInterfaceDescriptor::ContextRegister() { return esi; }
15 
DefaultInitializePlatformSpecific(CallInterfaceDescriptorData * data,int register_parameter_count)16 void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
17     CallInterfaceDescriptorData* data, int register_parameter_count) {
18   constexpr Register default_stub_registers[] = {eax, ecx, edx, edi};
19   STATIC_ASSERT(arraysize(default_stub_registers) == kMaxBuiltinRegisterParams);
20   CHECK_LE(static_cast<size_t>(register_parameter_count),
21            arraysize(default_stub_registers));
22   data->InitializePlatformSpecific(register_parameter_count,
23                                    default_stub_registers);
24 }
25 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)26 void RecordWriteDescriptor::InitializePlatformSpecific(
27     CallInterfaceDescriptorData* data) {
28   static const Register default_stub_registers[] = {ecx, edx, esi, edi,
29                                                     kReturnRegister0};
30 
31   data->RestrictAllocatableRegisters(default_stub_registers,
32                                      arraysize(default_stub_registers));
33 
34   CHECK_LE(static_cast<size_t>(kParameterCount),
35            arraysize(default_stub_registers));
36   data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
37 }
38 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)39 void EphemeronKeyBarrierDescriptor::InitializePlatformSpecific(
40     CallInterfaceDescriptorData* data) {
41   static const Register default_stub_registers[] = {ecx, edx, esi, edi,
42                                                     kReturnRegister0};
43 
44   data->RestrictAllocatableRegisters(default_stub_registers,
45                                      arraysize(default_stub_registers));
46 
47   CHECK_LE(static_cast<size_t>(kParameterCount),
48            arraysize(default_stub_registers));
49   data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
50 }
51 
ReceiverRegister()52 const Register LoadDescriptor::ReceiverRegister() { return edx; }
NameRegister()53 const Register LoadDescriptor::NameRegister() { return ecx; }
SlotRegister()54 const Register LoadDescriptor::SlotRegister() { return eax; }
55 
VectorRegister()56 const Register LoadWithVectorDescriptor::VectorRegister() { return no_reg; }
57 
58 const Register
LookupStartObjectRegister()59 LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
60   return edi;
61 }
62 
ReceiverRegister()63 const Register StoreDescriptor::ReceiverRegister() { return edx; }
NameRegister()64 const Register StoreDescriptor::NameRegister() { return ecx; }
ValueRegister()65 const Register StoreDescriptor::ValueRegister() { return no_reg; }
SlotRegister()66 const Register StoreDescriptor::SlotRegister() { return no_reg; }
67 
VectorRegister()68 const Register StoreWithVectorDescriptor::VectorRegister() { return no_reg; }
69 
SlotRegister()70 const Register StoreTransitionDescriptor::SlotRegister() { return no_reg; }
VectorRegister()71 const Register StoreTransitionDescriptor::VectorRegister() { return no_reg; }
MapRegister()72 const Register StoreTransitionDescriptor::MapRegister() { return edi; }
73 
HolderRegister()74 const Register ApiGetterDescriptor::HolderRegister() { return ecx; }
CallbackRegister()75 const Register ApiGetterDescriptor::CallbackRegister() { return eax; }
76 
ObjectRegister()77 const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
KeyRegister()78 const Register GrowArrayElementsDescriptor::KeyRegister() { return ecx; }
79 
80 // static
ArgumentRegister()81 const Register TypeConversionDescriptor::ArgumentRegister() { return eax; }
82 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)83 void TypeofDescriptor::InitializePlatformSpecific(
84     CallInterfaceDescriptorData* data) {
85   Register registers[] = {ecx};
86   data->InitializePlatformSpecific(arraysize(registers), registers);
87 }
88 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)89 void CallTrampolineDescriptor::InitializePlatformSpecific(
90     CallInterfaceDescriptorData* data) {
91   // eax : number of arguments
92   // edi : the target to call
93   Register registers[] = {edi, eax};
94   data->InitializePlatformSpecific(arraysize(registers), registers);
95 }
96 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)97 void CallVarargsDescriptor::InitializePlatformSpecific(
98     CallInterfaceDescriptorData* data) {
99   // eax : number of arguments (on the stack, not including receiver)
100   // edi : the target to call
101   // ecx : arguments list length (untagged)
102   // On the stack : arguments list (FixedArray)
103   Register registers[] = {edi, eax, ecx};
104   data->InitializePlatformSpecific(arraysize(registers), registers);
105 }
106 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)107 void CallForwardVarargsDescriptor::InitializePlatformSpecific(
108     CallInterfaceDescriptorData* data) {
109   // eax : number of arguments
110   // ecx : start index (to support rest parameters)
111   // edi : the target to call
112   Register registers[] = {edi, eax, ecx};
113   data->InitializePlatformSpecific(arraysize(registers), registers);
114 }
115 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)116 void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
117     CallInterfaceDescriptorData* data) {
118   // edx : function template info
119   // ecx : number of arguments (on the stack, not including receiver)
120   Register registers[] = {edx, ecx};
121   data->InitializePlatformSpecific(arraysize(registers), registers);
122 }
123 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)124 void CallWithSpreadDescriptor::InitializePlatformSpecific(
125     CallInterfaceDescriptorData* data) {
126   // eax : number of arguments (on the stack, not including receiver)
127   // edi : the target to call
128   // ecx : the object to spread
129   Register registers[] = {edi, eax, ecx};
130   data->InitializePlatformSpecific(arraysize(registers), registers);
131 }
132 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)133 void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
134     CallInterfaceDescriptorData* data) {
135   // edi : the target to call
136   // edx : the arguments list
137   Register registers[] = {edi, edx};
138   data->InitializePlatformSpecific(arraysize(registers), registers);
139 }
140 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)141 void ConstructVarargsDescriptor::InitializePlatformSpecific(
142     CallInterfaceDescriptorData* data) {
143   // eax : number of arguments (on the stack, not including receiver)
144   // edi : the target to call
145   // edx : the new target
146   // ecx : arguments list length (untagged)
147   // On the stack : arguments list (FixedArray)
148   Register registers[] = {edi, edx, eax, ecx};
149   data->InitializePlatformSpecific(arraysize(registers), registers);
150 }
151 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)152 void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
153     CallInterfaceDescriptorData* data) {
154   // eax : number of arguments
155   // edx : the new target
156   // ecx : start index (to support rest parameters)
157   // edi : the target to call
158   Register registers[] = {edi, edx, eax, ecx};
159   data->InitializePlatformSpecific(arraysize(registers), registers);
160 }
161 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)162 void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
163     CallInterfaceDescriptorData* data) {
164   // eax : number of arguments (on the stack, not including receiver)
165   // edi : the target to call
166   // edx : the new target
167   // ecx : the object to spread
168   Register registers[] = {edi, edx, eax, ecx};
169   data->InitializePlatformSpecific(arraysize(registers), registers);
170 }
171 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)172 void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
173     CallInterfaceDescriptorData* data) {
174   // edi : the target to call
175   // edx : the new target
176   // ecx : the arguments list
177   Register registers[] = {edi, edx, ecx};
178   data->InitializePlatformSpecific(arraysize(registers), registers);
179 }
180 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)181 void ConstructStubDescriptor::InitializePlatformSpecific(
182     CallInterfaceDescriptorData* data) {
183   // eax : number of arguments
184   // edx : the new target
185   // edi : the target to call
186   // ecx : allocation site or undefined
187   // TODO(jgruber): Remove the unused allocation site parameter.
188   Register registers[] = {edi, edx, eax, ecx};
189   data->InitializePlatformSpecific(arraysize(registers), registers);
190 }
191 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)192 void AbortDescriptor::InitializePlatformSpecific(
193     CallInterfaceDescriptorData* data) {
194   Register registers[] = {edx};
195   data->InitializePlatformSpecific(arraysize(registers), registers);
196 }
197 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)198 void CompareDescriptor::InitializePlatformSpecific(
199     CallInterfaceDescriptorData* data) {
200   Register registers[] = {edx, eax};
201   data->InitializePlatformSpecific(arraysize(registers), registers);
202 }
203 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)204 void BinaryOpDescriptor::InitializePlatformSpecific(
205     CallInterfaceDescriptorData* data) {
206   Register registers[] = {edx, eax};
207   data->InitializePlatformSpecific(arraysize(registers), registers);
208 }
209 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)210 void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
211     CallInterfaceDescriptorData* data) {
212   Register registers[] = {
213       edi,  // JSFunction
214       edx,  // the new target
215       eax,  // actual number of arguments
216       ecx,  // expected number of arguments
217   };
218   data->InitializePlatformSpecific(arraysize(registers), registers);
219 }
220 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)221 void ApiCallbackDescriptor::InitializePlatformSpecific(
222     CallInterfaceDescriptorData* data) {
223   Register registers[] = {
224       edx,  // kApiFunctionAddress
225       ecx,  // kArgc
226       eax,  // kCallData
227       edi,  // kHolder
228   };
229   data->InitializePlatformSpecific(arraysize(registers), registers);
230 }
231 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)232 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
233     CallInterfaceDescriptorData* data) {
234   Register registers[] = {
235       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
236       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
237   data->InitializePlatformSpecific(arraysize(registers), registers);
238 }
239 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)240 void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
241     CallInterfaceDescriptorData* data) {
242   Register registers[] = {
243       eax,  // argument count (not including receiver)
244       ecx,  // address of first argument
245       edi   // the target callable to be call
246   };
247   data->InitializePlatformSpecific(arraysize(registers), registers);
248 }
249 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)250 void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
251     CallInterfaceDescriptorData* data) {
252   Register registers[] = {
253       eax,  // argument count (not including receiver)
254       ecx,  // address of first argument
255   };
256   data->InitializePlatformSpecific(arraysize(registers), registers);
257 }
258 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)259 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
260     CallInterfaceDescriptorData* data) {
261   Register registers[] = {
262       eax,  // the value to pass to the generator
263       edx   // the JSGeneratorObject to resume
264   };
265   data->InitializePlatformSpecific(arraysize(registers), registers);
266 }
267 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)268 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
269     CallInterfaceDescriptorData* data) {
270   Register registers[] = {
271       eax,  // loaded new FP
272   };
273   data->InitializePlatformSpecific(arraysize(registers), registers);
274 }
275 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)276 void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
277     CallInterfaceDescriptorData* data) {
278   data->InitializePlatformSpecific(0, nullptr);
279 }
280 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)281 void WasmFloat32ToNumberDescriptor::InitializePlatformSpecific(
282     CallInterfaceDescriptorData* data) {
283   // Work around using eax, whose register code is 0, and leads to the FP
284   // parameter being passed via xmm0, which is not allocatable on ia32.
285   Register registers[] = {ecx};
286   data->InitializePlatformSpecific(arraysize(registers), registers);
287 }
288 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)289 void WasmFloat64ToNumberDescriptor::InitializePlatformSpecific(
290     CallInterfaceDescriptorData* data) {
291   // Work around using eax, whose register code is 0, and leads to the FP
292   // parameter being passed via xmm0, which is not allocatable on ia32.
293   Register registers[] = {ecx};
294   data->InitializePlatformSpecific(arraysize(registers), registers);
295 }
296 
297 }  // namespace internal
298 }  // namespace v8
299 
300 #endif  // V8_TARGET_ARCH_IA32
301