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 14namespace v8 { 15namespace internal { 16 17constexpr 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 24template <typename DerivedDescriptor> 25void StaticCallInterfaceDescriptor<DerivedDescriptor>:: 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 41constexpr 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 47constexpr Register LoadDescriptor::ReceiverRegister() { return a1; } 48// static 49constexpr Register LoadDescriptor::NameRegister() { return a2; } 50// static 51constexpr Register LoadDescriptor::SlotRegister() { return a0; } 52 53// static 54constexpr Register LoadWithVectorDescriptor::VectorRegister() { return a3; } 55 56// static 57constexpr Register KeyedLoadBaselineDescriptor::ReceiverRegister() { 58 return a1; 59} 60// static 61constexpr Register KeyedLoadBaselineDescriptor::NameRegister() { 62 return kInterpreterAccumulatorRegister; 63} 64// static 65constexpr Register KeyedLoadBaselineDescriptor::SlotRegister() { return a2; } 66 67// static 68constexpr Register KeyedLoadWithVectorDescriptor::VectorRegister() { 69 return a3; 70} 71 72// static 73constexpr Register KeyedHasICBaselineDescriptor::ReceiverRegister() { 74 return kInterpreterAccumulatorRegister; 75} 76// static 77constexpr Register KeyedHasICBaselineDescriptor::NameRegister() { return a1; } 78// static 79constexpr Register KeyedHasICBaselineDescriptor::SlotRegister() { return a2; } 80 81// static 82constexpr Register KeyedHasICWithVectorDescriptor::VectorRegister() { 83 return a3; 84} 85 86// static 87constexpr Register 88LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() { 89 return a4; 90} 91 92// static 93constexpr Register StoreDescriptor::ReceiverRegister() { return a1; } 94// static 95constexpr Register StoreDescriptor::NameRegister() { return a2; } 96// static 97constexpr Register StoreDescriptor::ValueRegister() { return a0; } 98// static 99constexpr Register StoreDescriptor::SlotRegister() { return a4; } 100 101// static 102constexpr Register StoreWithVectorDescriptor::VectorRegister() { return a3; } 103 104// static 105constexpr Register StoreTransitionDescriptor::MapRegister() { return a5; } 106 107// static 108constexpr Register ApiGetterDescriptor::HolderRegister() { return a0; } 109// static 110constexpr Register ApiGetterDescriptor::CallbackRegister() { return a3; } 111 112// static 113constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; } 114// static 115constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return a3; } 116 117// static 118constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() { 119 return a2; 120} 121// static 122constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() { return a3; } 123 124// static 125// static 126constexpr Register TypeConversionDescriptor::ArgumentRegister() { return a0; } 127 128// static 129constexpr auto TypeofDescriptor::registers() { return RegisterArray(a0); } 130 131// static 132constexpr auto CallTrampolineDescriptor::registers() { 133 // a1: target 134 // a0: number of arguments 135 return RegisterArray(a1, a0); 136} 137 138// static 139constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() { 140 // a1 : the source 141 // a0 : the excluded property count 142 return RegisterArray(a1, a0); 143} 144 145// static 146constexpr auto 147CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::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 155constexpr 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 164constexpr 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 172constexpr 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 179constexpr 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 187constexpr auto CallWithArrayLikeDescriptor::registers() { 188 // a1 : the target to call 189 // a2 : the arguments list 190 return RegisterArray(a1, a2); 191} 192 193// static 194constexpr 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 204constexpr 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 213constexpr 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 222constexpr 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 230constexpr 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 239constexpr auto AbortDescriptor::registers() { return RegisterArray(a0); } 240 241// static 242constexpr auto CompareDescriptor::registers() { 243 // a1: left operand 244 // a0: right operand 245 return RegisterArray(a1, a0); 246} 247 248// static 249constexpr 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 257constexpr auto BinaryOpDescriptor::registers() { 258 // a1: left operand 259 // a0: right operand 260 return RegisterArray(a1, a0); 261} 262 263// static 264constexpr 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 272constexpr 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 280constexpr auto ApiCallbackDescriptor::registers() { 281 return RegisterArray(a1, // kApiFunctionAddress 282 a2, // kArgc 283 a3, // kCallData 284 a0); // kHolder 285} 286 287// static 288constexpr auto InterpreterDispatchDescriptor::registers() { 289 return RegisterArray( 290 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 291 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister); 292} 293 294// static 295constexpr 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 302constexpr 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 312constexpr auto ResumeGeneratorDescriptor::registers() { 313 return RegisterArray(a0, // the value to pass to the generator 314 a1); // the JSGeneratorObject to resume 315} 316 317// static 318constexpr 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