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 9 namespace v8 { 10 namespace internal { 11 12 const Register CallInterfaceDescriptor::ContextRegister() { return cp; } 13 14 void 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 23 const Register FastNewFunctionContextDescriptor::FunctionRegister() { 24 return a1; 25 } 26 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return a0; } 27 28 const Register LoadDescriptor::ReceiverRegister() { return a1; } 29 const Register LoadDescriptor::NameRegister() { return a2; } 30 const Register LoadDescriptor::SlotRegister() { return a0; } 31 32 const Register LoadWithVectorDescriptor::VectorRegister() { return a3; } 33 34 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return a4; } 35 36 const Register StoreDescriptor::ReceiverRegister() { return a1; } 37 const Register StoreDescriptor::NameRegister() { return a2; } 38 const Register StoreDescriptor::ValueRegister() { return a0; } 39 const Register StoreDescriptor::SlotRegister() { return a4; } 40 41 const Register StoreWithVectorDescriptor::VectorRegister() { return a3; } 42 43 const Register StoreTransitionDescriptor::SlotRegister() { return a4; } 44 const Register StoreTransitionDescriptor::VectorRegister() { return a3; } 45 const Register StoreTransitionDescriptor::MapRegister() { return a5; } 46 47 const Register StringCompareDescriptor::LeftRegister() { return a1; } 48 const Register StringCompareDescriptor::RightRegister() { return a0; } 49 50 const Register ApiGetterDescriptor::HolderRegister() { return a0; } 51 const Register ApiGetterDescriptor::CallbackRegister() { return a3; } 52 53 const Register MathPowTaggedDescriptor::exponent() { return a2; } 54 55 56 const Register MathPowIntegerDescriptor::exponent() { 57 return MathPowTaggedDescriptor::exponent(); 58 } 59 60 61 const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; } 62 const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; } 63 64 65 void FastNewClosureDescriptor::InitializePlatformSpecific( 66 CallInterfaceDescriptorData* data) { 67 Register registers[] = {a1, a2, a3}; 68 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 69 } 70 71 // static 72 const Register TypeConversionDescriptor::ArgumentRegister() { return a0; } 73 74 void TypeofDescriptor::InitializePlatformSpecific( 75 CallInterfaceDescriptorData* data) { 76 Register registers[] = {a3}; 77 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 78 } 79 80 81 void FastCloneRegExpDescriptor::InitializePlatformSpecific( 82 CallInterfaceDescriptorData* data) { 83 Register registers[] = {a3, a2, a1, a0}; 84 data->InitializePlatformSpecific(arraysize(registers), registers); 85 } 86 87 88 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 89 CallInterfaceDescriptorData* data) { 90 Register registers[] = {a3, a2, a1}; 91 data->InitializePlatformSpecific(arraysize(registers), registers); 92 } 93 94 95 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 96 CallInterfaceDescriptorData* data) { 97 Register registers[] = {a3, a2, a1, a0}; 98 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 99 } 100 101 102 void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 103 CallInterfaceDescriptorData* data) { 104 Register registers[] = {a2, a3}; 105 data->InitializePlatformSpecific(arraysize(registers), registers); 106 } 107 108 109 void CreateWeakCellDescriptor::InitializePlatformSpecific( 110 CallInterfaceDescriptorData* data) { 111 Register registers[] = {a2, a3, a1}; 112 data->InitializePlatformSpecific(arraysize(registers), registers); 113 } 114 115 void CallICTrampolineDescriptor::InitializePlatformSpecific( 116 CallInterfaceDescriptorData* data) { 117 Register registers[] = {a1, a0, a3}; 118 data->InitializePlatformSpecific(arraysize(registers), registers); 119 } 120 121 void CallICDescriptor::InitializePlatformSpecific( 122 CallInterfaceDescriptorData* data) { 123 Register registers[] = {a1, a0, a3, a2}; 124 data->InitializePlatformSpecific(arraysize(registers), registers); 125 } 126 127 128 void CallFunctionDescriptor::InitializePlatformSpecific( 129 CallInterfaceDescriptorData* data) { 130 Register registers[] = {a1}; 131 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 132 } 133 134 135 void 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 149 void 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 157 void 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 165 void 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 176 void 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 186 void TransitionElementsKindDescriptor::InitializePlatformSpecific( 187 CallInterfaceDescriptorData* data) { 188 Register registers[] = {a0, a1}; 189 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 190 } 191 192 193 void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 194 CallInterfaceDescriptorData* data) { 195 // register state 196 data->InitializePlatformSpecific(0, nullptr, nullptr); 197 } 198 199 void 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 206 void 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 216 void 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 226 void 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 233 void VarArgFunctionDescriptor::InitializePlatformSpecific( 234 CallInterfaceDescriptorData* data) { 235 // stack param count needs (arg count) 236 Register registers[] = {a0}; 237 data->InitializePlatformSpecific(arraysize(registers), registers); 238 } 239 void CompareDescriptor::InitializePlatformSpecific( 240 CallInterfaceDescriptorData* data) { 241 Register registers[] = {a1, a0}; 242 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 243 } 244 245 246 void BinaryOpDescriptor::InitializePlatformSpecific( 247 CallInterfaceDescriptorData* data) { 248 Register registers[] = {a1, a0}; 249 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 250 } 251 252 253 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 254 CallInterfaceDescriptorData* data) { 255 Register registers[] = {a2, a1, a0}; 256 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 257 } 258 259 void 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 270 void CountOpDescriptor::InitializePlatformSpecific( 271 CallInterfaceDescriptorData* data) { 272 Register registers[] = {a1}; 273 data->InitializePlatformSpecific(arraysize(registers), registers); 274 } 275 276 void StringAddDescriptor::InitializePlatformSpecific( 277 CallInterfaceDescriptorData* data) { 278 Register registers[] = {a1, a0}; 279 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 280 } 281 282 283 void KeyedDescriptor::InitializePlatformSpecific( 284 CallInterfaceDescriptorData* data) { 285 Register registers[] = { 286 a2, // key 287 }; 288 data->InitializePlatformSpecific(arraysize(registers), registers); 289 } 290 291 292 void NamedDescriptor::InitializePlatformSpecific( 293 CallInterfaceDescriptorData* data) { 294 Register registers[] = { 295 a2, // name 296 }; 297 data->InitializePlatformSpecific(arraysize(registers), registers); 298 } 299 300 301 void CallHandlerDescriptor::InitializePlatformSpecific( 302 CallInterfaceDescriptorData* data) { 303 Register registers[] = { 304 a0, // receiver 305 }; 306 data->InitializePlatformSpecific(arraysize(registers), registers); 307 } 308 309 310 void 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 321 void 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 332 void InterpreterDispatchDescriptor::InitializePlatformSpecific( 333 CallInterfaceDescriptorData* data) { 334 Register registers[] = { 335 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 336 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 337 data->InitializePlatformSpecific(arraysize(registers), registers); 338 } 339 340 void 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 350 void 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 362 void 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 373 void 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 383 void 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 393 void 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