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_MIPS 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, t0}; 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 t0; } 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 t0; } 40 41 const Register StoreWithVectorDescriptor::VectorRegister() { return a3; } 42 43 const Register StoreTransitionDescriptor::SlotRegister() { return t0; } 44 const Register StoreTransitionDescriptor::VectorRegister() { return a3; } 45 const Register StoreTransitionDescriptor::MapRegister() { return t1; } 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 116 void CallFunctionDescriptor::InitializePlatformSpecific( 117 CallInterfaceDescriptorData* data) { 118 Register registers[] = {a1}; 119 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 120 } 121 122 void CallICTrampolineDescriptor::InitializePlatformSpecific( 123 CallInterfaceDescriptorData* data) { 124 Register registers[] = {a1, a0, a3}; 125 data->InitializePlatformSpecific(arraysize(registers), registers); 126 } 127 128 void CallICDescriptor::InitializePlatformSpecific( 129 CallInterfaceDescriptorData* data) { 130 Register registers[] = {a1, a0, a3, a2}; 131 data->InitializePlatformSpecific(arraysize(registers), registers); 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 // t0 : 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, t0, 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 240 void CompareDescriptor::InitializePlatformSpecific( 241 CallInterfaceDescriptorData* data) { 242 Register registers[] = {a1, a0}; 243 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 244 } 245 246 247 void BinaryOpDescriptor::InitializePlatformSpecific( 248 CallInterfaceDescriptorData* data) { 249 Register registers[] = {a1, a0}; 250 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 251 } 252 253 254 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 255 CallInterfaceDescriptorData* data) { 256 Register registers[] = {a2, a1, a0}; 257 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 258 } 259 260 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific( 261 CallInterfaceDescriptorData* data) { 262 // register state 263 // a1 -- lhs 264 // a0 -- rhs 265 // t0 -- slot id 266 // a3 -- vector 267 Register registers[] = {a1, a0, t0, a3}; 268 data->InitializePlatformSpecific(arraysize(registers), registers); 269 } 270 271 void CountOpDescriptor::InitializePlatformSpecific( 272 CallInterfaceDescriptorData* data) { 273 Register registers[] = {a1}; 274 data->InitializePlatformSpecific(arraysize(registers), registers); 275 } 276 277 void StringAddDescriptor::InitializePlatformSpecific( 278 CallInterfaceDescriptorData* data) { 279 Register registers[] = {a1, a0}; 280 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 281 } 282 283 284 void KeyedDescriptor::InitializePlatformSpecific( 285 CallInterfaceDescriptorData* data) { 286 Register registers[] = { 287 a2, // key 288 }; 289 data->InitializePlatformSpecific(arraysize(registers), registers); 290 } 291 292 293 void NamedDescriptor::InitializePlatformSpecific( 294 CallInterfaceDescriptorData* data) { 295 Register registers[] = { 296 a2, // name 297 }; 298 data->InitializePlatformSpecific(arraysize(registers), registers); 299 } 300 301 302 void CallHandlerDescriptor::InitializePlatformSpecific( 303 CallInterfaceDescriptorData* data) { 304 Register registers[] = { 305 a0, // receiver 306 }; 307 data->InitializePlatformSpecific(arraysize(registers), registers); 308 } 309 310 311 void ArgumentAdaptorDescriptor::InitializePlatformSpecific( 312 CallInterfaceDescriptorData* data) { 313 Register registers[] = { 314 a1, // JSFunction 315 a3, // the new target 316 a0, // actual number of arguments 317 a2, // expected number of arguments 318 }; 319 data->InitializePlatformSpecific(arraysize(registers), registers); 320 } 321 322 void ApiCallbackDescriptor::InitializePlatformSpecific( 323 CallInterfaceDescriptorData* data) { 324 Register registers[] = { 325 a0, // callee 326 t0, // call_data 327 a2, // holder 328 a1, // api_function_address 329 }; 330 data->InitializePlatformSpecific(arraysize(registers), registers); 331 } 332 333 void InterpreterDispatchDescriptor::InitializePlatformSpecific( 334 CallInterfaceDescriptorData* data) { 335 Register registers[] = { 336 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 337 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 338 data->InitializePlatformSpecific(arraysize(registers), registers); 339 } 340 341 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( 342 CallInterfaceDescriptorData* data) { 343 Register registers[] = { 344 a0, // argument count (not including receiver) 345 a2, // address of first argument 346 a1 // the target callable to be call 347 }; 348 data->InitializePlatformSpecific(arraysize(registers), registers); 349 } 350 351 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( 352 CallInterfaceDescriptorData* data) { 353 Register registers[] = { 354 a0, // argument count (not including receiver) 355 a3, // new target 356 a1, // constructor to call 357 a2, // allocation site feedback if available, undefined otherwise. 358 t4 // address of the first argument 359 }; 360 data->InitializePlatformSpecific(arraysize(registers), registers); 361 } 362 363 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( 364 CallInterfaceDescriptorData* data) { 365 Register registers[] = { 366 a0, // argument count (not including receiver) 367 a1, // the target to call verified to be Array function 368 a2, // allocation site feedback 369 a3, // address of first argument 370 }; 371 data->InitializePlatformSpecific(arraysize(registers), registers); 372 } 373 374 void InterpreterCEntryDescriptor::InitializePlatformSpecific( 375 CallInterfaceDescriptorData* data) { 376 Register registers[] = { 377 a0, // argument count (argc) 378 a2, // address of first argument (argv) 379 a1 // the runtime function to call 380 }; 381 data->InitializePlatformSpecific(arraysize(registers), registers); 382 } 383 384 void ResumeGeneratorDescriptor::InitializePlatformSpecific( 385 CallInterfaceDescriptorData* data) { 386 Register registers[] = { 387 v0, // the value to pass to the generator 388 a1, // the JSGeneratorObject to resume 389 a2 // the resume mode (tagged) 390 }; 391 data->InitializePlatformSpecific(arraysize(registers), registers); 392 } 393 394 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific( 395 CallInterfaceDescriptorData* data) { 396 Register registers[] = { 397 a1, // loaded new FP 398 }; 399 data->InitializePlatformSpecific(arraysize(registers), registers); 400 } 401 402 } // namespace internal 403 } // namespace v8 404 405 #endif // V8_TARGET_ARCH_MIPS 406