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 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