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