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 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[] = {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 25 const Register FastNewFunctionContextDescriptor::FunctionRegister() { 26 return r1; 27 } 28 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return r0; } 29 30 const Register LoadDescriptor::ReceiverRegister() { return r1; } 31 const Register LoadDescriptor::NameRegister() { return r2; } 32 const Register LoadDescriptor::SlotRegister() { return r0; } 33 34 const Register LoadWithVectorDescriptor::VectorRegister() { return r3; } 35 36 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r4; } 37 38 const Register StoreDescriptor::ReceiverRegister() { return r1; } 39 const Register StoreDescriptor::NameRegister() { return r2; } 40 const Register StoreDescriptor::ValueRegister() { return r0; } 41 const Register StoreDescriptor::SlotRegister() { return r4; } 42 43 const Register StoreWithVectorDescriptor::VectorRegister() { return r3; } 44 45 const Register StoreTransitionDescriptor::SlotRegister() { return r4; } 46 const Register StoreTransitionDescriptor::VectorRegister() { return r3; } 47 const Register StoreTransitionDescriptor::MapRegister() { return r5; } 48 49 const Register StringCompareDescriptor::LeftRegister() { return r1; } 50 const Register StringCompareDescriptor::RightRegister() { return r0; } 51 52 const Register ApiGetterDescriptor::HolderRegister() { return r0; } 53 const Register ApiGetterDescriptor::CallbackRegister() { return r3; } 54 55 const Register MathPowTaggedDescriptor::exponent() { return r2; } 56 57 58 const Register MathPowIntegerDescriptor::exponent() { 59 return MathPowTaggedDescriptor::exponent(); 60 } 61 62 63 const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; } 64 const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; } 65 66 67 void FastNewClosureDescriptor::InitializePlatformSpecific( 68 CallInterfaceDescriptorData* data) { 69 Register registers[] = {r1, r2, r3}; 70 data->InitializePlatformSpecific(arraysize(registers), registers); 71 } 72 73 // static 74 const Register TypeConversionDescriptor::ArgumentRegister() { return r0; } 75 76 void TypeofDescriptor::InitializePlatformSpecific( 77 CallInterfaceDescriptorData* data) { 78 Register registers[] = {r3}; 79 data->InitializePlatformSpecific(arraysize(registers), registers); 80 } 81 82 83 void FastCloneRegExpDescriptor::InitializePlatformSpecific( 84 CallInterfaceDescriptorData* data) { 85 Register registers[] = {r3, r2, r1, r0}; 86 data->InitializePlatformSpecific(arraysize(registers), registers); 87 } 88 89 90 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 91 CallInterfaceDescriptorData* data) { 92 Register registers[] = {r3, r2, r1}; 93 data->InitializePlatformSpecific(arraysize(registers), registers); 94 } 95 96 97 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 98 CallInterfaceDescriptorData* data) { 99 Register registers[] = {r3, r2, r1, r0}; 100 data->InitializePlatformSpecific(arraysize(registers), registers); 101 } 102 103 104 void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 105 CallInterfaceDescriptorData* data) { 106 Register registers[] = {r2, r3}; 107 data->InitializePlatformSpecific(arraysize(registers), registers); 108 } 109 110 111 void CreateWeakCellDescriptor::InitializePlatformSpecific( 112 CallInterfaceDescriptorData* data) { 113 Register registers[] = {r2, r3, r1}; 114 data->InitializePlatformSpecific(arraysize(registers), registers); 115 } 116 117 118 void CallFunctionDescriptor::InitializePlatformSpecific( 119 CallInterfaceDescriptorData* data) { 120 Register registers[] = {r1}; 121 data->InitializePlatformSpecific(arraysize(registers), registers); 122 } 123 124 void CallICTrampolineDescriptor::InitializePlatformSpecific( 125 CallInterfaceDescriptorData* data) { 126 Register registers[] = {r1, r0, r3}; 127 data->InitializePlatformSpecific(arraysize(registers), registers); 128 } 129 130 void CallICDescriptor::InitializePlatformSpecific( 131 CallInterfaceDescriptorData* data) { 132 Register registers[] = {r1, r0, r3, r2}; 133 data->InitializePlatformSpecific(arraysize(registers), registers); 134 } 135 136 137 void 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 151 void 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 159 void 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 167 void 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 178 void 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 188 void TransitionElementsKindDescriptor::InitializePlatformSpecific( 189 CallInterfaceDescriptorData* data) { 190 Register registers[] = {r0, r1}; 191 data->InitializePlatformSpecific(arraysize(registers), registers); 192 } 193 194 195 void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 196 CallInterfaceDescriptorData* data) { 197 data->InitializePlatformSpecific(0, nullptr, nullptr); 198 } 199 200 void 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 207 void 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 217 void 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 227 void 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 235 void VarArgFunctionDescriptor::InitializePlatformSpecific( 236 CallInterfaceDescriptorData* data) { 237 // stack param count needs (arg count) 238 Register registers[] = {r0}; 239 data->InitializePlatformSpecific(arraysize(registers), registers); 240 } 241 242 void CompareDescriptor::InitializePlatformSpecific( 243 CallInterfaceDescriptorData* data) { 244 Register registers[] = {r1, r0}; 245 data->InitializePlatformSpecific(arraysize(registers), registers); 246 } 247 248 249 void BinaryOpDescriptor::InitializePlatformSpecific( 250 CallInterfaceDescriptorData* data) { 251 Register registers[] = {r1, r0}; 252 data->InitializePlatformSpecific(arraysize(registers), registers); 253 } 254 255 256 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 257 CallInterfaceDescriptorData* data) { 258 Register registers[] = {r2, r1, r0}; 259 data->InitializePlatformSpecific(arraysize(registers), registers); 260 } 261 262 void 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 273 void CountOpDescriptor::InitializePlatformSpecific( 274 CallInterfaceDescriptorData* data) { 275 Register registers[] = {r1}; 276 data->InitializePlatformSpecific(arraysize(registers), registers); 277 } 278 279 void StringAddDescriptor::InitializePlatformSpecific( 280 CallInterfaceDescriptorData* data) { 281 Register registers[] = {r1, r0}; 282 data->InitializePlatformSpecific(arraysize(registers), registers); 283 } 284 285 286 void 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 299 void 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 312 void 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 325 void 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 340 void 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 355 void InterpreterDispatchDescriptor::InitializePlatformSpecific( 356 CallInterfaceDescriptorData* data) { 357 Register registers[] = { 358 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 359 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 360 data->InitializePlatformSpecific(arraysize(registers), registers); 361 } 362 363 void 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 373 void 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 385 void 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 396 void 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 406 void 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 416 void 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