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