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