Home | History | Annotate | Download | only in x87
      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