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