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