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   // SharedFunctionInfo, vector, slot index.
     68   Register registers[] = {rbx, rcx, rdx};
     69   data->InitializePlatformSpecific(arraysize(registers), registers);
     70 }
     71 
     72 void TypeofDescriptor::InitializePlatformSpecific(
     73     CallInterfaceDescriptorData* data) {
     74   Register registers[] = {rbx};
     75   data->InitializePlatformSpecific(arraysize(registers), registers);
     76 }
     77 
     78 
     79 // static
     80 const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
     81 
     82 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
     83     CallInterfaceDescriptorData* data) {
     84   Register registers[] = {rdi, rax, rcx, rdx};
     85   data->InitializePlatformSpecific(arraysize(registers), registers);
     86 }
     87 
     88 
     89 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
     90     CallInterfaceDescriptorData* data) {
     91   Register registers[] = {rax, rbx, rcx};
     92   data->InitializePlatformSpecific(arraysize(registers), registers);
     93 }
     94 
     95 
     96 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
     97     CallInterfaceDescriptorData* data) {
     98   Register registers[] = {rax, rbx, rcx, rdx};
     99   data->InitializePlatformSpecific(arraysize(registers), registers);
    100 }
    101 
    102 
    103 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
    104     CallInterfaceDescriptorData* data) {
    105   Register registers[] = {rbx, rdx};
    106   data->InitializePlatformSpecific(arraysize(registers), registers);
    107 }
    108 
    109 
    110 void CreateWeakCellDescriptor::InitializePlatformSpecific(
    111     CallInterfaceDescriptorData* data) {
    112   Register registers[] = {rbx, rdx, rdi};
    113   data->InitializePlatformSpecific(arraysize(registers), registers);
    114 }
    115 
    116 
    117 void CallFunctionDescriptor::InitializePlatformSpecific(
    118     CallInterfaceDescriptorData* data) {
    119   Register registers[] = {rdi};
    120   data->InitializePlatformSpecific(arraysize(registers), registers);
    121 }
    122 
    123 void CallICTrampolineDescriptor::InitializePlatformSpecific(
    124     CallInterfaceDescriptorData* data) {
    125   Register registers[] = {rdi, rax, rdx};
    126   data->InitializePlatformSpecific(arraysize(registers), registers);
    127 }
    128 
    129 void CallICDescriptor::InitializePlatformSpecific(
    130     CallInterfaceDescriptorData* data) {
    131   Register registers[] = {rdi, rax, rdx, rbx};
    132   data->InitializePlatformSpecific(arraysize(registers), registers);
    133 }
    134 
    135 
    136 void CallConstructDescriptor::InitializePlatformSpecific(
    137     CallInterfaceDescriptorData* data) {
    138   // rax : number of arguments
    139   // rbx : feedback vector
    140   // rdx : slot in feedback vector (Smi, for RecordCallTarget)
    141   // rdi : constructor function
    142   // TODO(turbofan): So far we don't gather type feedback and hence skip the
    143   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
    144   Register registers[] = {rax, rdi, rbx};
    145   data->InitializePlatformSpecific(arraysize(registers), registers);
    146 }
    147 
    148 
    149 void CallTrampolineDescriptor::InitializePlatformSpecific(
    150     CallInterfaceDescriptorData* data) {
    151   // rax : number of arguments
    152   // rdi : the target to call
    153   Register registers[] = {rdi, rax};
    154   data->InitializePlatformSpecific(arraysize(registers), registers);
    155 }
    156 
    157 void CallForwardVarargsDescriptor::InitializePlatformSpecific(
    158     CallInterfaceDescriptorData* data) {
    159   // rcx : start index (to support rest parameters)
    160   // rdi : the target to call
    161   Register registers[] = {rdi, rcx};
    162   data->InitializePlatformSpecific(arraysize(registers), registers);
    163 }
    164 
    165 void ConstructStubDescriptor::InitializePlatformSpecific(
    166     CallInterfaceDescriptorData* data) {
    167   // rax : number of arguments
    168   // rdx : the new target
    169   // rdi : the target to call
    170   // rbx : allocation site or undefined
    171   Register registers[] = {rdi, rdx, rax, rbx};
    172   data->InitializePlatformSpecific(arraysize(registers), registers);
    173 }
    174 
    175 
    176 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
    177     CallInterfaceDescriptorData* data) {
    178   // rax : number of arguments
    179   // rdx : the new target
    180   // rdi : the target to call
    181   Register registers[] = {rdi, rdx, rax};
    182   data->InitializePlatformSpecific(arraysize(registers), registers);
    183 }
    184 
    185 
    186 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
    187     CallInterfaceDescriptorData* data) {
    188   Register registers[] = {rax, rbx};
    189   data->InitializePlatformSpecific(arraysize(registers), registers);
    190 }
    191 
    192 
    193 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
    194     CallInterfaceDescriptorData* data) {
    195   data->InitializePlatformSpecific(0, nullptr, nullptr);
    196 }
    197 
    198 void ArrayConstructorDescriptor::InitializePlatformSpecific(
    199     CallInterfaceDescriptorData* data) {
    200   // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite
    201   Register registers[] = {rdi, rdx, rax, rbx};
    202   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    203 }
    204 
    205 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
    206     CallInterfaceDescriptorData* data) {
    207   // register state
    208   // rax -- number of arguments
    209   // rdi -- function
    210   // rbx -- allocation site with elements kind
    211   Register registers[] = {rdi, rbx, rax};
    212   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    213 }
    214 
    215 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
    216     CallInterfaceDescriptorData* data) {
    217   // register state
    218   // rax -- number of arguments
    219   // rdi -- function
    220   // rbx -- allocation site with elements kind
    221   Register registers[] = {rdi, rbx, rax};
    222   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    223 }
    224 
    225 void ArrayNArgumentsConstructorDescriptor::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 VarArgFunctionDescriptor::InitializePlatformSpecific(
    236     CallInterfaceDescriptorData* data) {
    237   // stack param count needs (arg count)
    238   Register registers[] = {rax};
    239   data->InitializePlatformSpecific(arraysize(registers), registers);
    240 }
    241 
    242 void CompareDescriptor::InitializePlatformSpecific(
    243     CallInterfaceDescriptorData* data) {
    244   Register registers[] = {rdx, rax};
    245   data->InitializePlatformSpecific(arraysize(registers), registers);
    246 }
    247 
    248 
    249 void BinaryOpDescriptor::InitializePlatformSpecific(
    250     CallInterfaceDescriptorData* data) {
    251   Register registers[] = {rdx, rax};
    252   data->InitializePlatformSpecific(arraysize(registers), registers);
    253 }
    254 
    255 
    256 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
    257     CallInterfaceDescriptorData* data) {
    258   Register registers[] = {rcx, rdx, rax};
    259   data->InitializePlatformSpecific(arraysize(registers), registers);
    260 }
    261 
    262 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
    263     CallInterfaceDescriptorData* data) {
    264   // register state
    265   // rdx -- lhs
    266   // rax -- rhs
    267   // rdi -- slot id
    268   // rbx -- vector
    269   Register registers[] = {rdx, rax, rdi, rbx};
    270   data->InitializePlatformSpecific(arraysize(registers), registers);
    271 }
    272 
    273 void CountOpDescriptor::InitializePlatformSpecific(
    274     CallInterfaceDescriptorData* data) {
    275   Register registers[] = {rax};
    276   data->InitializePlatformSpecific(arraysize(registers), registers);
    277 }
    278 
    279 void StringAddDescriptor::InitializePlatformSpecific(
    280     CallInterfaceDescriptorData* data) {
    281   Register registers[] = {rdx, rax};
    282   data->InitializePlatformSpecific(arraysize(registers), registers);
    283 }
    284 
    285 
    286 void KeyedDescriptor::InitializePlatformSpecific(
    287     CallInterfaceDescriptorData* data) {
    288   Register registers[] = {
    289       rcx,  // key
    290   };
    291   data->InitializePlatformSpecific(arraysize(registers), registers);
    292 }
    293 
    294 
    295 void NamedDescriptor::InitializePlatformSpecific(
    296     CallInterfaceDescriptorData* data) {
    297   Register registers[] = {
    298       rcx,  // name
    299   };
    300   data->InitializePlatformSpecific(arraysize(registers), registers);
    301 }
    302 
    303 
    304 void CallHandlerDescriptor::InitializePlatformSpecific(
    305     CallInterfaceDescriptorData* data) {
    306   Register registers[] = {
    307       rdx,  // receiver
    308   };
    309   data->InitializePlatformSpecific(arraysize(registers), registers);
    310 }
    311 
    312 
    313 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    314     CallInterfaceDescriptorData* data) {
    315   Register registers[] = {
    316       rdi,  // JSFunction
    317       rdx,  // the new target
    318       rax,  // actual number of arguments
    319       rbx,  // expected number of arguments
    320   };
    321   data->InitializePlatformSpecific(arraysize(registers), registers);
    322 }
    323 
    324 void ApiCallbackDescriptor::InitializePlatformSpecific(
    325     CallInterfaceDescriptorData* data) {
    326   Register registers[] = {
    327       rdi,  // callee
    328       rbx,  // call_data
    329       rcx,  // holder
    330       rdx,  // api_function_address
    331   };
    332   data->InitializePlatformSpecific(arraysize(registers), registers);
    333 }
    334 
    335 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
    336     CallInterfaceDescriptorData* data) {
    337   Register registers[] = {
    338       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
    339       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
    340   data->InitializePlatformSpecific(arraysize(registers), registers);
    341 }
    342 
    343 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
    344     CallInterfaceDescriptorData* data) {
    345   Register registers[] = {
    346       rax,  // argument count (not including receiver)
    347       rbx,  // address of first argument
    348       rdi   // the target callable to be call
    349   };
    350   data->InitializePlatformSpecific(arraysize(registers), registers);
    351 }
    352 
    353 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
    354     CallInterfaceDescriptorData* data) {
    355   Register registers[] = {
    356       rax,  // argument count (not including receiver)
    357       rdx,  // new target
    358       rdi,  // constructor
    359       rbx,  // allocation site feedback if available, undefined otherwise
    360       rcx,  // address of first argument
    361   };
    362   data->InitializePlatformSpecific(arraysize(registers), registers);
    363 }
    364 
    365 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
    366     CallInterfaceDescriptorData* data) {
    367   Register registers[] = {
    368       rax,  // argument count (not including receiver)
    369       rdx,  // target to the call. It is checked to be Array function.
    370       rbx,  // allocation site feedback
    371       rcx,  // address of first argument
    372   };
    373   data->InitializePlatformSpecific(arraysize(registers), registers);
    374 }
    375 
    376 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
    377     CallInterfaceDescriptorData* data) {
    378   Register registers[] = {
    379       rax,  // argument count (argc)
    380       r15,  // address of first argument (argv)
    381       rbx   // the runtime function to call
    382   };
    383   data->InitializePlatformSpecific(arraysize(registers), registers);
    384 }
    385 
    386 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
    387     CallInterfaceDescriptorData* data) {
    388   Register registers[] = {
    389       rax,  // the value to pass to the generator
    390       rbx,  // the JSGeneratorObject to resume
    391       rdx   // the resume mode (tagged)
    392   };
    393   data->InitializePlatformSpecific(arraysize(registers), registers);
    394 }
    395 
    396 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
    397     CallInterfaceDescriptorData* data) {
    398   Register registers[] = {
    399       rbx,  // loaded new FP
    400   };
    401   data->InitializePlatformSpecific(arraysize(registers), registers);
    402 }
    403 
    404 }  // namespace internal
    405 }  // namespace v8
    406 
    407 #endif  // V8_TARGET_ARCH_X64
    408