• 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_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