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