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