1// Copyright 2012 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#if V8_TARGET_ARCH_X64 6 7#include "src/interface-descriptors.h" 8 9namespace v8 { 10namespace internal { 11 12const Register CallInterfaceDescriptor::ContextRegister() { return rsi; } 13 14void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( 15 CallInterfaceDescriptorData* data, int register_parameter_count) { 16 const Register default_stub_registers[] = {rax, rbx, rcx, rdx, rdi}; 17 CHECK_LE(static_cast<size_t>(register_parameter_count), 18 arraysize(default_stub_registers)); 19 data->InitializePlatformSpecific(register_parameter_count, 20 default_stub_registers); 21} 22 23const Register LoadDescriptor::ReceiverRegister() { return rdx; } 24const Register LoadDescriptor::NameRegister() { return rcx; } 25const Register LoadDescriptor::SlotRegister() { return rax; } 26 27 28const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; } 29 30 31const Register StoreDescriptor::ReceiverRegister() { return rdx; } 32const Register StoreDescriptor::NameRegister() { return rcx; } 33const Register StoreDescriptor::ValueRegister() { return rax; } 34 35 36const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return rdi; } 37 38 39const Register VectorStoreICDescriptor::VectorRegister() { return rbx; } 40 41 42const Register VectorStoreTransitionDescriptor::SlotRegister() { return rdi; } 43const Register VectorStoreTransitionDescriptor::VectorRegister() { return rbx; } 44const Register VectorStoreTransitionDescriptor::MapRegister() { return r11; } 45 46 47const Register StoreTransitionDescriptor::MapRegister() { return rbx; } 48 49 50const Register StoreGlobalViaContextDescriptor::SlotRegister() { return rbx; } 51const Register StoreGlobalViaContextDescriptor::ValueRegister() { return rax; } 52 53 54const Register StringCompareDescriptor::LeftRegister() { return rdx; } 55const Register StringCompareDescriptor::RightRegister() { return rax; } 56 57const Register ApiGetterDescriptor::HolderRegister() { return rcx; } 58const Register ApiGetterDescriptor::CallbackRegister() { return rbx; } 59 60const Register MathPowTaggedDescriptor::exponent() { return rdx; } 61 62 63const Register MathPowIntegerDescriptor::exponent() { 64 return MathPowTaggedDescriptor::exponent(); 65} 66 67 68const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; } 69const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; } 70 71 72void FastNewClosureDescriptor::InitializePlatformSpecific( 73 CallInterfaceDescriptorData* data) { 74 Register registers[] = {rbx}; 75 data->InitializePlatformSpecific(arraysize(registers), registers); 76} 77 78 79void FastNewContextDescriptor::InitializePlatformSpecific( 80 CallInterfaceDescriptorData* data) { 81 Register registers[] = {rdi}; 82 data->InitializePlatformSpecific(arraysize(registers), registers); 83} 84 85void FastNewObjectDescriptor::InitializePlatformSpecific( 86 CallInterfaceDescriptorData* data) { 87 Register registers[] = {rdi, rdx}; 88 data->InitializePlatformSpecific(arraysize(registers), registers); 89} 90 91void FastNewRestParameterDescriptor::InitializePlatformSpecific( 92 CallInterfaceDescriptorData* data) { 93 Register registers[] = {rdi}; 94 data->InitializePlatformSpecific(arraysize(registers), registers); 95} 96 97void FastNewSloppyArgumentsDescriptor::InitializePlatformSpecific( 98 CallInterfaceDescriptorData* data) { 99 Register registers[] = {rdi}; 100 data->InitializePlatformSpecific(arraysize(registers), registers); 101} 102 103void FastNewStrictArgumentsDescriptor::InitializePlatformSpecific( 104 CallInterfaceDescriptorData* data) { 105 Register registers[] = {rdi}; 106 data->InitializePlatformSpecific(arraysize(registers), registers); 107} 108 109 110void TypeofDescriptor::InitializePlatformSpecific( 111 CallInterfaceDescriptorData* data) { 112 Register registers[] = {rbx}; 113 data->InitializePlatformSpecific(arraysize(registers), registers); 114} 115 116 117// static 118const Register TypeConversionDescriptor::ArgumentRegister() { return rax; } 119 120void FastCloneRegExpDescriptor::InitializePlatformSpecific( 121 CallInterfaceDescriptorData* data) { 122 Register registers[] = {rdi, rax, rcx, rdx}; 123 data->InitializePlatformSpecific(arraysize(registers), registers); 124} 125 126 127void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 128 CallInterfaceDescriptorData* data) { 129 Register registers[] = {rax, rbx, rcx}; 130 data->InitializePlatformSpecific(arraysize(registers), registers); 131} 132 133 134void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 135 CallInterfaceDescriptorData* data) { 136 Register registers[] = {rax, rbx, rcx, rdx}; 137 data->InitializePlatformSpecific(arraysize(registers), registers); 138} 139 140 141void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 142 CallInterfaceDescriptorData* data) { 143 Register registers[] = {rbx, rdx}; 144 data->InitializePlatformSpecific(arraysize(registers), registers); 145} 146 147 148void CreateWeakCellDescriptor::InitializePlatformSpecific( 149 CallInterfaceDescriptorData* data) { 150 Register registers[] = {rbx, rdx, rdi}; 151 data->InitializePlatformSpecific(arraysize(registers), registers); 152} 153 154 155void CallFunctionDescriptor::InitializePlatformSpecific( 156 CallInterfaceDescriptorData* data) { 157 Register registers[] = {rdi}; 158 data->InitializePlatformSpecific(arraysize(registers), registers); 159} 160 161 162void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific( 163 CallInterfaceDescriptorData* data) { 164 Register registers[] = {rdi, rdx}; 165 data->InitializePlatformSpecific(arraysize(registers), registers); 166} 167 168 169void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific( 170 CallInterfaceDescriptorData* data) { 171 Register registers[] = {rdi, rdx, rbx}; 172 data->InitializePlatformSpecific(arraysize(registers), registers); 173} 174 175 176void CallConstructDescriptor::InitializePlatformSpecific( 177 CallInterfaceDescriptorData* data) { 178 // rax : number of arguments 179 // rbx : feedback vector 180 // rdx : slot in feedback vector (Smi, for RecordCallTarget) 181 // rdi : constructor function 182 // TODO(turbofan): So far we don't gather type feedback and hence skip the 183 // slot parameter, but ArrayConstructStub needs the vector to be undefined. 184 Register registers[] = {rax, rdi, rbx}; 185 data->InitializePlatformSpecific(arraysize(registers), registers); 186} 187 188 189void CallTrampolineDescriptor::InitializePlatformSpecific( 190 CallInterfaceDescriptorData* data) { 191 // rax : number of arguments 192 // rdi : the target to call 193 Register registers[] = {rdi, rax}; 194 data->InitializePlatformSpecific(arraysize(registers), registers); 195} 196 197 198void ConstructStubDescriptor::InitializePlatformSpecific( 199 CallInterfaceDescriptorData* data) { 200 // rax : number of arguments 201 // rdx : the new target 202 // rdi : the target to call 203 // rbx : allocation site or undefined 204 Register registers[] = {rdi, rdx, rax, rbx}; 205 data->InitializePlatformSpecific(arraysize(registers), registers); 206} 207 208 209void ConstructTrampolineDescriptor::InitializePlatformSpecific( 210 CallInterfaceDescriptorData* data) { 211 // rax : number of arguments 212 // rdx : the new target 213 // rdi : the target to call 214 Register registers[] = {rdi, rdx, rax}; 215 data->InitializePlatformSpecific(arraysize(registers), registers); 216} 217 218 219void RegExpConstructResultDescriptor::InitializePlatformSpecific( 220 CallInterfaceDescriptorData* data) { 221 Register registers[] = {rcx, rbx, rax}; 222 data->InitializePlatformSpecific(arraysize(registers), registers); 223} 224 225 226void TransitionElementsKindDescriptor::InitializePlatformSpecific( 227 CallInterfaceDescriptorData* data) { 228 Register registers[] = {rax, rbx}; 229 data->InitializePlatformSpecific(arraysize(registers), registers); 230} 231 232 233void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 234 CallInterfaceDescriptorData* data) { 235 data->InitializePlatformSpecific(0, nullptr, nullptr); 236} 237 238#define SIMD128_ALLOC_DESC(TYPE, Type, type, lane_count, lane_type) \ 239 void Allocate##Type##Descriptor::InitializePlatformSpecific( \ 240 CallInterfaceDescriptorData* data) { \ 241 data->InitializePlatformSpecific(0, nullptr, nullptr); \ 242 } 243SIMD128_TYPES(SIMD128_ALLOC_DESC) 244#undef SIMD128_ALLOC_DESC 245 246void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific( 247 CallInterfaceDescriptorData* data) { 248 // register state 249 // rax -- number of arguments 250 // rdi -- function 251 // rbx -- allocation site with elements kind 252 Register registers[] = {rdi, rbx, rax}; 253 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 254} 255 256void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific( 257 CallInterfaceDescriptorData* data) { 258 // register state 259 // rax -- number of arguments 260 // rdi -- function 261 // rbx -- allocation site with elements kind 262 Register registers[] = {rdi, rbx, rax}; 263 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 264} 265 266void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific( 267 CallInterfaceDescriptorData* data) { 268 // register state 269 // rax -- number of arguments 270 // rdi -- function 271 // rbx -- allocation site with elements kind 272 Register registers[] = {rdi, rbx, rax}; 273 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 274} 275 276void VarArgFunctionDescriptor::InitializePlatformSpecific( 277 CallInterfaceDescriptorData* data) { 278 // stack param count needs (arg count) 279 Register registers[] = {rax}; 280 data->InitializePlatformSpecific(arraysize(registers), registers); 281} 282 283void CompareDescriptor::InitializePlatformSpecific( 284 CallInterfaceDescriptorData* data) { 285 Register registers[] = {rdx, rax}; 286 data->InitializePlatformSpecific(arraysize(registers), registers); 287} 288 289 290void BinaryOpDescriptor::InitializePlatformSpecific( 291 CallInterfaceDescriptorData* data) { 292 Register registers[] = {rdx, rax}; 293 data->InitializePlatformSpecific(arraysize(registers), registers); 294} 295 296 297void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 298 CallInterfaceDescriptorData* data) { 299 Register registers[] = {rcx, rdx, rax}; 300 data->InitializePlatformSpecific(arraysize(registers), registers); 301} 302 303void CountOpDescriptor::InitializePlatformSpecific( 304 CallInterfaceDescriptorData* data) { 305 Register registers[] = {rax}; 306 data->InitializePlatformSpecific(arraysize(registers), registers); 307} 308 309void StringAddDescriptor::InitializePlatformSpecific( 310 CallInterfaceDescriptorData* data) { 311 Register registers[] = {rdx, rax}; 312 data->InitializePlatformSpecific(arraysize(registers), registers); 313} 314 315 316void KeyedDescriptor::InitializePlatformSpecific( 317 CallInterfaceDescriptorData* data) { 318 Register registers[] = { 319 rcx, // key 320 }; 321 data->InitializePlatformSpecific(arraysize(registers), registers); 322} 323 324 325void NamedDescriptor::InitializePlatformSpecific( 326 CallInterfaceDescriptorData* data) { 327 Register registers[] = { 328 rcx, // name 329 }; 330 data->InitializePlatformSpecific(arraysize(registers), registers); 331} 332 333 334void CallHandlerDescriptor::InitializePlatformSpecific( 335 CallInterfaceDescriptorData* data) { 336 Register registers[] = { 337 rdx, // receiver 338 }; 339 data->InitializePlatformSpecific(arraysize(registers), registers); 340} 341 342 343void ArgumentAdaptorDescriptor::InitializePlatformSpecific( 344 CallInterfaceDescriptorData* data) { 345 Register registers[] = { 346 rdi, // JSFunction 347 rdx, // the new target 348 rax, // actual number of arguments 349 rbx, // expected number of arguments 350 }; 351 data->InitializePlatformSpecific(arraysize(registers), registers); 352} 353 354void ApiCallbackDescriptorBase::InitializePlatformSpecific( 355 CallInterfaceDescriptorData* data) { 356 Register registers[] = { 357 rdi, // callee 358 rbx, // call_data 359 rcx, // holder 360 rdx, // api_function_address 361 }; 362 data->InitializePlatformSpecific(arraysize(registers), registers); 363} 364 365void InterpreterDispatchDescriptor::InitializePlatformSpecific( 366 CallInterfaceDescriptorData* data) { 367 Register registers[] = { 368 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 369 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 370 data->InitializePlatformSpecific(arraysize(registers), registers); 371} 372 373void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( 374 CallInterfaceDescriptorData* data) { 375 Register registers[] = { 376 rax, // argument count (not including receiver) 377 rbx, // address of first argument 378 rdi // the target callable to be call 379 }; 380 data->InitializePlatformSpecific(arraysize(registers), registers); 381} 382 383void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( 384 CallInterfaceDescriptorData* data) { 385 Register registers[] = { 386 rax, // argument count (not including receiver) 387 rdx, // new target 388 rdi, // constructor 389 rbx, // address of first argument 390 }; 391 data->InitializePlatformSpecific(arraysize(registers), registers); 392} 393 394void InterpreterCEntryDescriptor::InitializePlatformSpecific( 395 CallInterfaceDescriptorData* data) { 396 Register registers[] = { 397 rax, // argument count (argc) 398 r15, // address of first argument (argv) 399 rbx // the runtime function to call 400 }; 401 data->InitializePlatformSpecific(arraysize(registers), registers); 402} 403 404void ResumeGeneratorDescriptor::InitializePlatformSpecific( 405 CallInterfaceDescriptorData* data) { 406 Register registers[] = { 407 rax, // the value to pass to the generator 408 rbx, // the JSGeneratorObject to resume 409 rdx // the resume mode (tagged) 410 }; 411 data->InitializePlatformSpecific(arraysize(registers), registers); 412} 413 414} // namespace internal 415} // namespace v8 416 417#endif // V8_TARGET_ARCH_X64 418