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