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