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 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 // static 73 const Register TypeConversionDescriptor::ArgumentRegister() { return eax; } 74 75 void TypeofDescriptor::InitializePlatformSpecific( 76 CallInterfaceDescriptorData* data) { 77 Register registers[] = {ebx}; 78 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 79 } 80 81 82 void FastCloneRegExpDescriptor::InitializePlatformSpecific( 83 CallInterfaceDescriptorData* data) { 84 Register registers[] = {edi, eax, ecx, edx}; 85 data->InitializePlatformSpecific(arraysize(registers), registers); 86 } 87 88 89 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 90 CallInterfaceDescriptorData* data) { 91 Register registers[] = {eax, ebx, ecx}; 92 data->InitializePlatformSpecific(arraysize(registers), registers); 93 } 94 95 96 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 97 CallInterfaceDescriptorData* data) { 98 Register registers[] = {eax, ebx, ecx, edx}; 99 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 100 } 101 102 103 void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 104 CallInterfaceDescriptorData* data) { 105 Register registers[] = {ebx, edx}; 106 data->InitializePlatformSpecific(arraysize(registers), registers); 107 } 108 109 110 void CreateWeakCellDescriptor::InitializePlatformSpecific( 111 CallInterfaceDescriptorData* data) { 112 Register registers[] = {ebx, edx, edi}; 113 data->InitializePlatformSpecific(arraysize(registers), registers); 114 } 115 116 117 void CallFunctionDescriptor::InitializePlatformSpecific( 118 CallInterfaceDescriptorData* data) { 119 Register registers[] = {edi}; 120 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 121 } 122 123 void CallICTrampolineDescriptor::InitializePlatformSpecific( 124 CallInterfaceDescriptorData* data) { 125 Register registers[] = {edi, eax, edx}; 126 data->InitializePlatformSpecific(arraysize(registers), registers); 127 } 128 129 void CallICDescriptor::InitializePlatformSpecific( 130 CallInterfaceDescriptorData* data) { 131 Register registers[] = {edi, eax, edx, ebx}; 132 data->InitializePlatformSpecific(arraysize(registers), registers); 133 } 134 135 136 void 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 150 void 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 158 void 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 166 void 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 177 void 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 187 void TransitionElementsKindDescriptor::InitializePlatformSpecific( 188 CallInterfaceDescriptorData* data) { 189 Register registers[] = {eax, ebx}; 190 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 191 } 192 193 194 void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 195 CallInterfaceDescriptorData* data) { 196 // register state 197 data->InitializePlatformSpecific(0, nullptr, nullptr); 198 } 199 200 void 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 207 void 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 217 void 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 227 void 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 237 void VarArgFunctionDescriptor::InitializePlatformSpecific( 238 CallInterfaceDescriptorData* data) { 239 // stack param count needs (arg count) 240 Register registers[] = {eax}; 241 data->InitializePlatformSpecific(arraysize(registers), registers); 242 } 243 244 void CompareDescriptor::InitializePlatformSpecific( 245 CallInterfaceDescriptorData* data) { 246 Register registers[] = {edx, eax}; 247 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 248 } 249 250 251 void BinaryOpDescriptor::InitializePlatformSpecific( 252 CallInterfaceDescriptorData* data) { 253 Register registers[] = {edx, eax}; 254 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 255 } 256 257 258 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 259 CallInterfaceDescriptorData* data) { 260 Register registers[] = {ecx, edx, eax}; 261 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 262 } 263 264 void 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 275 void CountOpDescriptor::InitializePlatformSpecific( 276 CallInterfaceDescriptorData* data) { 277 Register registers[] = {eax}; 278 data->InitializePlatformSpecific(arraysize(registers), registers); 279 } 280 281 void StringAddDescriptor::InitializePlatformSpecific( 282 CallInterfaceDescriptorData* data) { 283 Register registers[] = {edx, eax}; 284 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 285 } 286 287 288 void KeyedDescriptor::InitializePlatformSpecific( 289 CallInterfaceDescriptorData* data) { 290 Register registers[] = { 291 ecx, // key 292 }; 293 data->InitializePlatformSpecific(arraysize(registers), registers); 294 } 295 296 297 void NamedDescriptor::InitializePlatformSpecific( 298 CallInterfaceDescriptorData* data) { 299 Register registers[] = { 300 ecx, // name 301 }; 302 data->InitializePlatformSpecific(arraysize(registers), registers); 303 } 304 305 306 void CallHandlerDescriptor::InitializePlatformSpecific( 307 CallInterfaceDescriptorData* data) { 308 Register registers[] = { 309 edx, // name 310 }; 311 data->InitializePlatformSpecific(arraysize(registers), registers); 312 } 313 314 315 void 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 326 void 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 337 void InterpreterDispatchDescriptor::InitializePlatformSpecific( 338 CallInterfaceDescriptorData* data) { 339 Register registers[] = { 340 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 341 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 342 data->InitializePlatformSpecific(arraysize(registers), registers); 343 } 344 345 void 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 355 void 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 367 void 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 378 void 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 388 void 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 398 void 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