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