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