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