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 9 namespace v8 { 10 namespace internal { 11 12 const Register CallInterfaceDescriptor::ContextRegister() { return esi; } 13 14 15 const Register LoadDescriptor::ReceiverRegister() { return edx; } 16 const Register LoadDescriptor::NameRegister() { return ecx; } 17 const Register LoadDescriptor::SlotRegister() { return eax; } 18 19 const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; } 20 21 22 const Register StoreDescriptor::ReceiverRegister() { return edx; } 23 const Register StoreDescriptor::NameRegister() { return ecx; } 24 const Register StoreDescriptor::ValueRegister() { return eax; } 25 26 27 const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return edi; } 28 29 30 const Register VectorStoreICDescriptor::VectorRegister() { return ebx; } 31 32 33 const Register VectorStoreTransitionDescriptor::SlotRegister() { 34 return no_reg; 35 } 36 37 38 const Register VectorStoreTransitionDescriptor::VectorRegister() { return ebx; } 39 40 41 const Register VectorStoreTransitionDescriptor::MapRegister() { return edi; } 42 43 44 const Register StoreTransitionDescriptor::MapRegister() { return ebx; } 45 46 47 const Register LoadGlobalViaContextDescriptor::SlotRegister() { return ebx; } 48 49 50 const Register StoreGlobalViaContextDescriptor::SlotRegister() { return ebx; } 51 const Register StoreGlobalViaContextDescriptor::ValueRegister() { return eax; } 52 53 54 const Register InstanceOfDescriptor::LeftRegister() { return edx; } 55 const Register InstanceOfDescriptor::RightRegister() { return eax; } 56 57 58 const Register StringCompareDescriptor::LeftRegister() { return edx; } 59 const Register StringCompareDescriptor::RightRegister() { return eax; } 60 61 62 const Register ArgumentsAccessReadDescriptor::index() { return edx; } 63 const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; } 64 65 66 const Register ArgumentsAccessNewDescriptor::function() { return edi; } 67 const Register ArgumentsAccessNewDescriptor::parameter_count() { return ecx; } 68 const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return edx; } 69 70 71 const Register RestParamAccessDescriptor::parameter_count() { return ecx; } 72 const Register RestParamAccessDescriptor::parameter_pointer() { return edx; } 73 const Register RestParamAccessDescriptor::rest_parameter_index() { return ebx; } 74 75 76 const Register ApiGetterDescriptor::function_address() { return edx; } 77 78 79 const Register MathPowTaggedDescriptor::exponent() { return eax; } 80 81 82 const Register MathPowIntegerDescriptor::exponent() { 83 return MathPowTaggedDescriptor::exponent(); 84 } 85 86 87 const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; } 88 const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; } 89 90 91 void FastNewClosureDescriptor::InitializePlatformSpecific( 92 CallInterfaceDescriptorData* data) { 93 Register registers[] = {ebx}; 94 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 95 } 96 97 98 void FastNewContextDescriptor::InitializePlatformSpecific( 99 CallInterfaceDescriptorData* data) { 100 Register registers[] = {edi}; 101 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 102 } 103 104 105 void ToNumberDescriptor::InitializePlatformSpecific( 106 CallInterfaceDescriptorData* data) { 107 // ToNumberStub invokes a function, and therefore needs a context. 108 Register registers[] = {eax}; 109 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 110 } 111 112 113 // static 114 const Register ToLengthDescriptor::ReceiverRegister() { return eax; } 115 116 117 // static 118 const Register ToStringDescriptor::ReceiverRegister() { return eax; } 119 120 121 // static 122 const Register ToObjectDescriptor::ReceiverRegister() { return eax; } 123 124 125 void NumberToStringDescriptor::InitializePlatformSpecific( 126 CallInterfaceDescriptorData* data) { 127 Register registers[] = {eax}; 128 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 129 } 130 131 132 void TypeofDescriptor::InitializePlatformSpecific( 133 CallInterfaceDescriptorData* data) { 134 Register registers[] = {ebx}; 135 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 136 } 137 138 139 void FastCloneRegExpDescriptor::InitializePlatformSpecific( 140 CallInterfaceDescriptorData* data) { 141 Register registers[] = {edi, eax, ecx, edx}; 142 data->InitializePlatformSpecific(arraysize(registers), registers); 143 } 144 145 146 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 147 CallInterfaceDescriptorData* data) { 148 Register registers[] = {eax, ebx, ecx}; 149 data->InitializePlatformSpecific(arraysize(registers), registers); 150 } 151 152 153 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 154 CallInterfaceDescriptorData* data) { 155 Register registers[] = {eax, ebx, ecx, edx}; 156 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 157 } 158 159 160 void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 161 CallInterfaceDescriptorData* data) { 162 Register registers[] = {ebx, edx}; 163 data->InitializePlatformSpecific(arraysize(registers), registers); 164 } 165 166 167 void CreateWeakCellDescriptor::InitializePlatformSpecific( 168 CallInterfaceDescriptorData* data) { 169 Register registers[] = {ebx, edx, edi}; 170 data->InitializePlatformSpecific(arraysize(registers), registers); 171 } 172 173 174 void StoreArrayLiteralElementDescriptor::InitializePlatformSpecific( 175 CallInterfaceDescriptorData* data) { 176 Register registers[] = {ecx, eax}; 177 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 178 } 179 180 181 void CallFunctionDescriptor::InitializePlatformSpecific( 182 CallInterfaceDescriptorData* data) { 183 Register registers[] = {edi}; 184 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 185 } 186 187 188 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific( 189 CallInterfaceDescriptorData* data) { 190 Register registers[] = {edi, edx}; 191 data->InitializePlatformSpecific(arraysize(registers), registers); 192 } 193 194 195 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific( 196 CallInterfaceDescriptorData* data) { 197 Register registers[] = {edi, edx, ebx}; 198 data->InitializePlatformSpecific(arraysize(registers), registers); 199 } 200 201 202 void CallConstructDescriptor::InitializePlatformSpecific( 203 CallInterfaceDescriptorData* data) { 204 // eax : number of arguments 205 // ebx : feedback vector 206 // ecx : new target (for IsSuperConstructorCall) 207 // edx : slot in feedback vector (Smi, for RecordCallTarget) 208 // edi : constructor function 209 // TODO(turbofan): So far we don't gather type feedback and hence skip the 210 // slot parameter, but ArrayConstructStub needs the vector to be undefined. 211 Register registers[] = {eax, edi, ecx, ebx}; 212 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 213 } 214 215 216 void CallTrampolineDescriptor::InitializePlatformSpecific( 217 CallInterfaceDescriptorData* data) { 218 // eax : number of arguments 219 // edi : the target to call 220 Register registers[] = {edi, eax}; 221 data->InitializePlatformSpecific(arraysize(registers), registers); 222 } 223 224 225 void ConstructStubDescriptor::InitializePlatformSpecific( 226 CallInterfaceDescriptorData* data) { 227 // eax : number of arguments 228 // edx : the new target 229 // edi : the target to call 230 // ebx : allocation site or undefined 231 Register registers[] = {edi, edx, eax, ebx}; 232 data->InitializePlatformSpecific(arraysize(registers), registers); 233 } 234 235 236 void ConstructTrampolineDescriptor::InitializePlatformSpecific( 237 CallInterfaceDescriptorData* data) { 238 // eax : number of arguments 239 // edx : the new target 240 // edi : the target to call 241 Register registers[] = {edi, edx, eax}; 242 data->InitializePlatformSpecific(arraysize(registers), registers); 243 } 244 245 246 void RegExpConstructResultDescriptor::InitializePlatformSpecific( 247 CallInterfaceDescriptorData* data) { 248 Register registers[] = {ecx, ebx, eax}; 249 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 250 } 251 252 253 void TransitionElementsKindDescriptor::InitializePlatformSpecific( 254 CallInterfaceDescriptorData* data) { 255 Register registers[] = {eax, ebx}; 256 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 257 } 258 259 260 void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 261 CallInterfaceDescriptorData* data) { 262 // register state 263 data->InitializePlatformSpecific(0, nullptr, nullptr); 264 } 265 266 267 void AllocateInNewSpaceDescriptor::InitializePlatformSpecific( 268 CallInterfaceDescriptorData* data) { 269 Register registers[] = {eax}; 270 data->InitializePlatformSpecific(arraysize(registers), registers); 271 } 272 273 274 void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific( 275 CallInterfaceDescriptorData* data) { 276 // register state 277 // eax -- number of arguments 278 // edi -- function 279 // ebx -- allocation site with elements kind 280 Register registers[] = {edi, ebx}; 281 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 282 } 283 284 285 void ArrayConstructorDescriptor::InitializePlatformSpecific( 286 CallInterfaceDescriptorData* data) { 287 // stack param count needs (constructor pointer, and single argument) 288 Register registers[] = {edi, ebx, eax}; 289 data->InitializePlatformSpecific(arraysize(registers), registers); 290 } 291 292 293 void InternalArrayConstructorConstantArgCountDescriptor:: 294 InitializePlatformSpecific(CallInterfaceDescriptorData* data) { 295 // register state 296 // eax -- number of arguments 297 // edi -- function 298 Register registers[] = {edi}; 299 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 300 } 301 302 303 void InternalArrayConstructorDescriptor::InitializePlatformSpecific( 304 CallInterfaceDescriptorData* data) { 305 // stack param count needs (constructor pointer, and single argument) 306 Register registers[] = {edi, eax}; 307 data->InitializePlatformSpecific(arraysize(registers), registers); 308 } 309 310 311 void CompareDescriptor::InitializePlatformSpecific( 312 CallInterfaceDescriptorData* data) { 313 Register registers[] = {edx, eax}; 314 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 315 } 316 317 318 void CompareNilDescriptor::InitializePlatformSpecific( 319 CallInterfaceDescriptorData* data) { 320 Register registers[] = {eax}; 321 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 322 } 323 324 325 void ToBooleanDescriptor::InitializePlatformSpecific( 326 CallInterfaceDescriptorData* data) { 327 Register registers[] = {eax}; 328 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 329 } 330 331 332 void BinaryOpDescriptor::InitializePlatformSpecific( 333 CallInterfaceDescriptorData* data) { 334 Register registers[] = {edx, eax}; 335 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 336 } 337 338 339 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 340 CallInterfaceDescriptorData* data) { 341 Register registers[] = {ecx, edx, eax}; 342 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 343 } 344 345 346 void StringAddDescriptor::InitializePlatformSpecific( 347 CallInterfaceDescriptorData* data) { 348 Register registers[] = {edx, eax}; 349 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 350 } 351 352 353 void KeyedDescriptor::InitializePlatformSpecific( 354 CallInterfaceDescriptorData* data) { 355 Register registers[] = { 356 ecx, // key 357 }; 358 data->InitializePlatformSpecific(arraysize(registers), registers); 359 } 360 361 362 void NamedDescriptor::InitializePlatformSpecific( 363 CallInterfaceDescriptorData* data) { 364 Register registers[] = { 365 ecx, // name 366 }; 367 data->InitializePlatformSpecific(arraysize(registers), registers); 368 } 369 370 371 void CallHandlerDescriptor::InitializePlatformSpecific( 372 CallInterfaceDescriptorData* data) { 373 Register registers[] = { 374 edx, // name 375 }; 376 data->InitializePlatformSpecific(arraysize(registers), registers); 377 } 378 379 380 void ArgumentAdaptorDescriptor::InitializePlatformSpecific( 381 CallInterfaceDescriptorData* data) { 382 Register registers[] = { 383 edi, // JSFunction 384 edx, // the new target 385 eax, // actual number of arguments 386 ebx, // expected number of arguments 387 }; 388 data->InitializePlatformSpecific(arraysize(registers), registers); 389 } 390 391 392 void ApiFunctionDescriptor::InitializePlatformSpecific( 393 CallInterfaceDescriptorData* data) { 394 Register registers[] = { 395 edi, // callee 396 ebx, // call_data 397 ecx, // holder 398 edx, // api_function_address 399 eax, // actual number of arguments 400 }; 401 data->InitializePlatformSpecific(arraysize(registers), registers); 402 } 403 404 405 void ApiAccessorDescriptor::InitializePlatformSpecific( 406 CallInterfaceDescriptorData* data) { 407 Register registers[] = { 408 edi, // callee 409 ebx, // call_data 410 ecx, // holder 411 edx, // api_function_address 412 }; 413 data->InitializePlatformSpecific(arraysize(registers), registers); 414 } 415 416 417 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( 418 CallInterfaceDescriptorData* data) { 419 Register registers[] = { 420 eax, // argument count (not including receiver) 421 ebx, // address of first argument 422 edi // the target callable to be call 423 }; 424 data->InitializePlatformSpecific(arraysize(registers), registers); 425 } 426 427 428 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( 429 CallInterfaceDescriptorData* data) { 430 Register registers[] = { 431 eax, // argument count (not including receiver) 432 edx, // new target 433 edi, // constructor 434 ebx, // address of first argument 435 }; 436 data->InitializePlatformSpecific(arraysize(registers), registers); 437 } 438 439 440 void InterpreterCEntryDescriptor::InitializePlatformSpecific( 441 CallInterfaceDescriptorData* data) { 442 Register registers[] = { 443 eax, // argument count (argc) 444 ecx, // address of first argument (argv) 445 ebx // the runtime function to call 446 }; 447 data->InitializePlatformSpecific(arraysize(registers), registers); 448 } 449 450 } // namespace internal 451 } // namespace v8 452 453 #endif // V8_TARGET_ARCH_IA32 454