• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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