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