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 FastNewFunctionContextDescriptor::FunctionRegister() { 24 return edi; 25 } 26 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return eax; } 27 28 const Register LoadDescriptor::ReceiverRegister() { return edx; } 29 const Register LoadDescriptor::NameRegister() { return ecx; } 30 const Register LoadDescriptor::SlotRegister() { return eax; } 31 32 const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; } 33 34 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; } 35 36 const Register StoreDescriptor::ReceiverRegister() { return edx; } 37 const Register StoreDescriptor::NameRegister() { return ecx; } 38 const Register StoreDescriptor::ValueRegister() { return eax; } 39 const Register StoreDescriptor::SlotRegister() { return edi; } 40 41 const Register StoreWithVectorDescriptor::VectorRegister() { return ebx; } 42 43 const Register StoreTransitionDescriptor::SlotRegister() { return no_reg; } 44 const Register StoreTransitionDescriptor::VectorRegister() { return ebx; } 45 const Register StoreTransitionDescriptor::MapRegister() { return edi; } 46 47 const Register StringCompareDescriptor::LeftRegister() { return edx; } 48 const Register StringCompareDescriptor::RightRegister() { return eax; } 49 50 const Register ApiGetterDescriptor::HolderRegister() { return ecx; } 51 const Register ApiGetterDescriptor::CallbackRegister() { return eax; } 52 53 const Register MathPowTaggedDescriptor::exponent() { return eax; } 54 55 56 const Register MathPowIntegerDescriptor::exponent() { 57 return MathPowTaggedDescriptor::exponent(); 58 } 59 60 61 const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; } 62 const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; } 63 64 65 void 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 void FastNewRestParameterDescriptor::InitializePlatformSpecific( 73 CallInterfaceDescriptorData* data) { 74 Register registers[] = {edi}; 75 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 76 } 77 78 void FastNewSloppyArgumentsDescriptor::InitializePlatformSpecific( 79 CallInterfaceDescriptorData* data) { 80 Register registers[] = {edi}; 81 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 82 } 83 84 void FastNewStrictArgumentsDescriptor::InitializePlatformSpecific( 85 CallInterfaceDescriptorData* data) { 86 Register registers[] = {edi}; 87 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 88 } 89 90 91 // static 92 const Register TypeConversionDescriptor::ArgumentRegister() { return eax; } 93 94 void TypeofDescriptor::InitializePlatformSpecific( 95 CallInterfaceDescriptorData* data) { 96 Register registers[] = {ebx}; 97 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 98 } 99 100 101 void FastCloneRegExpDescriptor::InitializePlatformSpecific( 102 CallInterfaceDescriptorData* data) { 103 Register registers[] = {edi, eax, ecx, edx}; 104 data->InitializePlatformSpecific(arraysize(registers), registers); 105 } 106 107 108 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 109 CallInterfaceDescriptorData* data) { 110 Register registers[] = {eax, ebx, ecx}; 111 data->InitializePlatformSpecific(arraysize(registers), registers); 112 } 113 114 115 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 116 CallInterfaceDescriptorData* data) { 117 Register registers[] = {eax, ebx, ecx, edx}; 118 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 119 } 120 121 122 void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 123 CallInterfaceDescriptorData* data) { 124 Register registers[] = {ebx, edx}; 125 data->InitializePlatformSpecific(arraysize(registers), registers); 126 } 127 128 129 void CreateWeakCellDescriptor::InitializePlatformSpecific( 130 CallInterfaceDescriptorData* data) { 131 Register registers[] = {ebx, edx, edi}; 132 data->InitializePlatformSpecific(arraysize(registers), registers); 133 } 134 135 136 void CallFunctionDescriptor::InitializePlatformSpecific( 137 CallInterfaceDescriptorData* data) { 138 Register registers[] = {edi}; 139 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 140 } 141 142 void CallICTrampolineDescriptor::InitializePlatformSpecific( 143 CallInterfaceDescriptorData* data) { 144 Register registers[] = {edi, eax, edx}; 145 data->InitializePlatformSpecific(arraysize(registers), registers); 146 } 147 148 void CallICDescriptor::InitializePlatformSpecific( 149 CallInterfaceDescriptorData* data) { 150 Register registers[] = {edi, eax, edx, ebx}; 151 data->InitializePlatformSpecific(arraysize(registers), registers); 152 } 153 154 155 void 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 169 void 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 178 void 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 189 void 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 199 void TransitionElementsKindDescriptor::InitializePlatformSpecific( 200 CallInterfaceDescriptorData* data) { 201 Register registers[] = {eax, ebx}; 202 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 203 } 204 205 206 void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 207 CallInterfaceDescriptorData* data) { 208 // register state 209 data->InitializePlatformSpecific(0, nullptr, nullptr); 210 } 211 212 void 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 222 void 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 232 void 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 242 void VarArgFunctionDescriptor::InitializePlatformSpecific( 243 CallInterfaceDescriptorData* data) { 244 // stack param count needs (arg count) 245 Register registers[] = {eax}; 246 data->InitializePlatformSpecific(arraysize(registers), registers); 247 } 248 249 void CompareDescriptor::InitializePlatformSpecific( 250 CallInterfaceDescriptorData* data) { 251 Register registers[] = {edx, eax}; 252 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 253 } 254 255 256 void BinaryOpDescriptor::InitializePlatformSpecific( 257 CallInterfaceDescriptorData* data) { 258 Register registers[] = {edx, eax}; 259 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 260 } 261 262 263 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 264 CallInterfaceDescriptorData* data) { 265 Register registers[] = {ecx, edx, eax}; 266 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 267 } 268 269 void 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 280 void CountOpDescriptor::InitializePlatformSpecific( 281 CallInterfaceDescriptorData* data) { 282 Register registers[] = {eax}; 283 data->InitializePlatformSpecific(arraysize(registers), registers); 284 } 285 286 void StringAddDescriptor::InitializePlatformSpecific( 287 CallInterfaceDescriptorData* data) { 288 Register registers[] = {edx, eax}; 289 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 290 } 291 292 293 void KeyedDescriptor::InitializePlatformSpecific( 294 CallInterfaceDescriptorData* data) { 295 Register registers[] = { 296 ecx, // key 297 }; 298 data->InitializePlatformSpecific(arraysize(registers), registers); 299 } 300 301 302 void NamedDescriptor::InitializePlatformSpecific( 303 CallInterfaceDescriptorData* data) { 304 Register registers[] = { 305 ecx, // name 306 }; 307 data->InitializePlatformSpecific(arraysize(registers), registers); 308 } 309 310 311 void CallHandlerDescriptor::InitializePlatformSpecific( 312 CallInterfaceDescriptorData* data) { 313 Register registers[] = { 314 edx, // name 315 }; 316 data->InitializePlatformSpecific(arraysize(registers), registers); 317 } 318 319 320 void 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 331 void 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 342 void InterpreterDispatchDescriptor::InitializePlatformSpecific( 343 CallInterfaceDescriptorData* data) { 344 Register registers[] = { 345 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 346 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 347 data->InitializePlatformSpecific(arraysize(registers), registers); 348 } 349 350 void 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 360 void 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 372 void 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 383 void 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 393 void 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