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