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