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