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