Home | History | Annotate | Download | only in x64
      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_X64
      6 
      7 #include "src/interface-descriptors.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 
     12 const Register CallInterfaceDescriptor::ContextRegister() { return rsi; }
     13 
     14 void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
     15     CallInterfaceDescriptorData* data, int register_parameter_count) {
     16   const Register default_stub_registers[] = {rax, rbx, rcx, rdx, rdi};
     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 rdi;
     25 }
     26 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return rax; }
     27 
     28 const Register LoadDescriptor::ReceiverRegister() { return rdx; }
     29 const Register LoadDescriptor::NameRegister() { return rcx; }
     30 const Register LoadDescriptor::SlotRegister() { return rax; }
     31 
     32 const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
     33 
     34 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return rdi; }
     35 
     36 const Register StoreDescriptor::ReceiverRegister() { return rdx; }
     37 const Register StoreDescriptor::NameRegister() { return rcx; }
     38 const Register StoreDescriptor::ValueRegister() { return rax; }
     39 const Register StoreDescriptor::SlotRegister() { return rdi; }
     40 
     41 const Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
     42 
     43 const Register StoreTransitionDescriptor::SlotRegister() { return rdi; }
     44 const Register StoreTransitionDescriptor::VectorRegister() { return rbx; }
     45 const Register StoreTransitionDescriptor::MapRegister() { return r11; }
     46 
     47 const Register StringCompareDescriptor::LeftRegister() { return rdx; }
     48 const Register StringCompareDescriptor::RightRegister() { return rax; }
     49 
     50 const Register ApiGetterDescriptor::HolderRegister() { return rcx; }
     51 const Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
     52 
     53 const Register MathPowTaggedDescriptor::exponent() { return rdx; }
     54 
     55 
     56 const Register MathPowIntegerDescriptor::exponent() {
     57   return MathPowTaggedDescriptor::exponent();
     58 }
     59 
     60 
     61 const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
     62 const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
     63 
     64 
     65 void FastNewClosureDescriptor::InitializePlatformSpecific(
     66     CallInterfaceDescriptorData* data) {
     67   Register registers[] = {rbx};
     68   data->InitializePlatformSpecific(arraysize(registers), registers);
     69 }
     70 
     71 void FastNewObjectDescriptor::InitializePlatformSpecific(
     72     CallInterfaceDescriptorData* data) {
     73   Register registers[] = {rdi, rdx};
     74   data->InitializePlatformSpecific(arraysize(registers), registers);
     75 }
     76 
     77 void FastNewRestParameterDescriptor::InitializePlatformSpecific(
     78     CallInterfaceDescriptorData* data) {
     79   Register registers[] = {rdi};
     80   data->InitializePlatformSpecific(arraysize(registers), registers);
     81 }
     82 
     83 void FastNewSloppyArgumentsDescriptor::InitializePlatformSpecific(
     84     CallInterfaceDescriptorData* data) {
     85   Register registers[] = {rdi};
     86   data->InitializePlatformSpecific(arraysize(registers), registers);
     87 }
     88 
     89 void FastNewStrictArgumentsDescriptor::InitializePlatformSpecific(
     90     CallInterfaceDescriptorData* data) {
     91   Register registers[] = {rdi};
     92   data->InitializePlatformSpecific(arraysize(registers), registers);
     93 }
     94 
     95 
     96 void TypeofDescriptor::InitializePlatformSpecific(
     97     CallInterfaceDescriptorData* data) {
     98   Register registers[] = {rbx};
     99   data->InitializePlatformSpecific(arraysize(registers), registers);
    100 }
    101 
    102 
    103 // static
    104 const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
    105 
    106 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
    107     CallInterfaceDescriptorData* data) {
    108   Register registers[] = {rdi, rax, rcx, rdx};
    109   data->InitializePlatformSpecific(arraysize(registers), registers);
    110 }
    111 
    112 
    113 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
    114     CallInterfaceDescriptorData* data) {
    115   Register registers[] = {rax, rbx, rcx};
    116   data->InitializePlatformSpecific(arraysize(registers), registers);
    117 }
    118 
    119 
    120 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
    121     CallInterfaceDescriptorData* data) {
    122   Register registers[] = {rax, rbx, rcx, rdx};
    123   data->InitializePlatformSpecific(arraysize(registers), registers);
    124 }
    125 
    126 
    127 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
    128     CallInterfaceDescriptorData* data) {
    129   Register registers[] = {rbx, rdx};
    130   data->InitializePlatformSpecific(arraysize(registers), registers);
    131 }
    132 
    133 
    134 void CreateWeakCellDescriptor::InitializePlatformSpecific(
    135     CallInterfaceDescriptorData* data) {
    136   Register registers[] = {rbx, rdx, rdi};
    137   data->InitializePlatformSpecific(arraysize(registers), registers);
    138 }
    139 
    140 
    141 void CallFunctionDescriptor::InitializePlatformSpecific(
    142     CallInterfaceDescriptorData* data) {
    143   Register registers[] = {rdi};
    144   data->InitializePlatformSpecific(arraysize(registers), registers);
    145 }
    146 
    147 
    148 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
    149     CallInterfaceDescriptorData* data) {
    150   Register registers[] = {rdi, rdx};
    151   data->InitializePlatformSpecific(arraysize(registers), registers);
    152 }
    153 
    154 
    155 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
    156     CallInterfaceDescriptorData* data) {
    157   Register registers[] = {rdi, rax, rdx, rbx};
    158   data->InitializePlatformSpecific(arraysize(registers), registers);
    159 }
    160 
    161 
    162 void CallConstructDescriptor::InitializePlatformSpecific(
    163     CallInterfaceDescriptorData* data) {
    164   // rax : number of arguments
    165   // rbx : feedback vector
    166   // rdx : slot in feedback vector (Smi, for RecordCallTarget)
    167   // rdi : constructor function
    168   // TODO(turbofan): So far we don't gather type feedback and hence skip the
    169   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
    170   Register registers[] = {rax, rdi, rbx};
    171   data->InitializePlatformSpecific(arraysize(registers), registers);
    172 }
    173 
    174 
    175 void CallTrampolineDescriptor::InitializePlatformSpecific(
    176     CallInterfaceDescriptorData* data) {
    177   // rax : number of arguments
    178   // rdi : the target to call
    179   Register registers[] = {rdi, rax};
    180   data->InitializePlatformSpecific(arraysize(registers), registers);
    181 }
    182 
    183 
    184 void ConstructStubDescriptor::InitializePlatformSpecific(
    185     CallInterfaceDescriptorData* data) {
    186   // rax : number of arguments
    187   // rdx : the new target
    188   // rdi : the target to call
    189   // rbx : allocation site or undefined
    190   Register registers[] = {rdi, rdx, rax, rbx};
    191   data->InitializePlatformSpecific(arraysize(registers), registers);
    192 }
    193 
    194 
    195 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
    196     CallInterfaceDescriptorData* data) {
    197   // rax : number of arguments
    198   // rdx : the new target
    199   // rdi : the target to call
    200   Register registers[] = {rdi, rdx, rax};
    201   data->InitializePlatformSpecific(arraysize(registers), registers);
    202 }
    203 
    204 
    205 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
    206     CallInterfaceDescriptorData* data) {
    207   Register registers[] = {rax, rbx};
    208   data->InitializePlatformSpecific(arraysize(registers), registers);
    209 }
    210 
    211 
    212 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
    213     CallInterfaceDescriptorData* data) {
    214   data->InitializePlatformSpecific(0, nullptr, nullptr);
    215 }
    216 
    217 #define SIMD128_ALLOC_DESC(TYPE, Type, type, lane_count, lane_type) \
    218   void Allocate##Type##Descriptor::InitializePlatformSpecific(      \
    219       CallInterfaceDescriptorData* data) {                          \
    220     data->InitializePlatformSpecific(0, nullptr, nullptr);          \
    221   }
    222 SIMD128_TYPES(SIMD128_ALLOC_DESC)
    223 #undef SIMD128_ALLOC_DESC
    224 
    225 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
    226     CallInterfaceDescriptorData* data) {
    227   // register state
    228   // rax -- number of arguments
    229   // rdi -- function
    230   // rbx -- allocation site with elements kind
    231   Register registers[] = {rdi, rbx, rax};
    232   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    233 }
    234 
    235 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
    236     CallInterfaceDescriptorData* data) {
    237   // register state
    238   // rax -- number of arguments
    239   // rdi -- function
    240   // rbx -- allocation site with elements kind
    241   Register registers[] = {rdi, rbx, rax};
    242   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    243 }
    244 
    245 void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
    246     CallInterfaceDescriptorData* data) {
    247   // register state
    248   // rax -- number of arguments
    249   // rdi -- function
    250   // rbx -- allocation site with elements kind
    251   Register registers[] = {rdi, rbx, rax};
    252   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    253 }
    254 
    255 void VarArgFunctionDescriptor::InitializePlatformSpecific(
    256     CallInterfaceDescriptorData* data) {
    257   // stack param count needs (arg count)
    258   Register registers[] = {rax};
    259   data->InitializePlatformSpecific(arraysize(registers), registers);
    260 }
    261 
    262 void CompareDescriptor::InitializePlatformSpecific(
    263     CallInterfaceDescriptorData* data) {
    264   Register registers[] = {rdx, rax};
    265   data->InitializePlatformSpecific(arraysize(registers), registers);
    266 }
    267 
    268 
    269 void BinaryOpDescriptor::InitializePlatformSpecific(
    270     CallInterfaceDescriptorData* data) {
    271   Register registers[] = {rdx, rax};
    272   data->InitializePlatformSpecific(arraysize(registers), registers);
    273 }
    274 
    275 
    276 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
    277     CallInterfaceDescriptorData* data) {
    278   Register registers[] = {rcx, rdx, rax};
    279   data->InitializePlatformSpecific(arraysize(registers), registers);
    280 }
    281 
    282 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
    283     CallInterfaceDescriptorData* data) {
    284   // register state
    285   // rdx -- lhs
    286   // rax -- rhs
    287   // rdi -- slot id
    288   // rbx -- vector
    289   Register registers[] = {rdx, rax, rdi, rbx};
    290   data->InitializePlatformSpecific(arraysize(registers), registers);
    291 }
    292 
    293 void CountOpDescriptor::InitializePlatformSpecific(
    294     CallInterfaceDescriptorData* data) {
    295   Register registers[] = {rax};
    296   data->InitializePlatformSpecific(arraysize(registers), registers);
    297 }
    298 
    299 void StringAddDescriptor::InitializePlatformSpecific(
    300     CallInterfaceDescriptorData* data) {
    301   Register registers[] = {rdx, rax};
    302   data->InitializePlatformSpecific(arraysize(registers), registers);
    303 }
    304 
    305 
    306 void KeyedDescriptor::InitializePlatformSpecific(
    307     CallInterfaceDescriptorData* data) {
    308   Register registers[] = {
    309       rcx,  // key
    310   };
    311   data->InitializePlatformSpecific(arraysize(registers), registers);
    312 }
    313 
    314 
    315 void NamedDescriptor::InitializePlatformSpecific(
    316     CallInterfaceDescriptorData* data) {
    317   Register registers[] = {
    318       rcx,  // name
    319   };
    320   data->InitializePlatformSpecific(arraysize(registers), registers);
    321 }
    322 
    323 
    324 void CallHandlerDescriptor::InitializePlatformSpecific(
    325     CallInterfaceDescriptorData* data) {
    326   Register registers[] = {
    327       rdx,  // receiver
    328   };
    329   data->InitializePlatformSpecific(arraysize(registers), registers);
    330 }
    331 
    332 
    333 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    334     CallInterfaceDescriptorData* data) {
    335   Register registers[] = {
    336       rdi,  // JSFunction
    337       rdx,  // the new target
    338       rax,  // actual number of arguments
    339       rbx,  // expected number of arguments
    340   };
    341   data->InitializePlatformSpecific(arraysize(registers), registers);
    342 }
    343 
    344 void ApiCallbackDescriptor::InitializePlatformSpecific(
    345     CallInterfaceDescriptorData* data) {
    346   Register registers[] = {
    347       rdi,  // callee
    348       rbx,  // call_data
    349       rcx,  // holder
    350       rdx,  // api_function_address
    351   };
    352   data->InitializePlatformSpecific(arraysize(registers), registers);
    353 }
    354 
    355 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
    356     CallInterfaceDescriptorData* data) {
    357   Register registers[] = {
    358       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
    359       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
    360   data->InitializePlatformSpecific(arraysize(registers), registers);
    361 }
    362 
    363 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
    364     CallInterfaceDescriptorData* data) {
    365   Register registers[] = {
    366       rax,  // argument count (not including receiver)
    367       rbx,  // address of first argument
    368       rdi   // the target callable to be call
    369   };
    370   data->InitializePlatformSpecific(arraysize(registers), registers);
    371 }
    372 
    373 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
    374     CallInterfaceDescriptorData* data) {
    375   Register registers[] = {
    376       rax,  // argument count (not including receiver)
    377       rdx,  // new target
    378       rdi,  // constructor
    379       rbx,  // allocation site feedback if available, undefined otherwise
    380       rcx,  // address of first argument
    381   };
    382   data->InitializePlatformSpecific(arraysize(registers), registers);
    383 }
    384 
    385 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
    386     CallInterfaceDescriptorData* data) {
    387   Register registers[] = {
    388       rax,  // argument count (not including receiver)
    389       rdx,  // target to the call. It is checked to be Array function.
    390       rbx,  // allocation site feedback
    391       rcx,  // address of first argument
    392   };
    393   data->InitializePlatformSpecific(arraysize(registers), registers);
    394 }
    395 
    396 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
    397     CallInterfaceDescriptorData* data) {
    398   Register registers[] = {
    399       rax,  // argument count (argc)
    400       r15,  // address of first argument (argv)
    401       rbx   // the runtime function to call
    402   };
    403   data->InitializePlatformSpecific(arraysize(registers), registers);
    404 }
    405 
    406 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
    407     CallInterfaceDescriptorData* data) {
    408   Register registers[] = {
    409       rax,  // the value to pass to the generator
    410       rbx,  // the JSGeneratorObject to resume
    411       rdx   // the resume mode (tagged)
    412   };
    413   data->InitializePlatformSpecific(arraysize(registers), registers);
    414 }
    415 
    416 }  // namespace internal
    417 }  // namespace v8
    418 
    419 #endif  // V8_TARGET_ARCH_X64
    420