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 
     15 const Register LoadDescriptor::ReceiverRegister() { return rdx; }
     16 const Register LoadDescriptor::NameRegister() { return rcx; }
     17 const Register LoadDescriptor::SlotRegister() { return rax; }
     18 
     19 
     20 const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
     21 
     22 
     23 const Register StoreDescriptor::ReceiverRegister() { return rdx; }
     24 const Register StoreDescriptor::NameRegister() { return rcx; }
     25 const Register StoreDescriptor::ValueRegister() { return rax; }
     26 
     27 
     28 const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return rdi; }
     29 
     30 
     31 const Register VectorStoreICDescriptor::VectorRegister() { return rbx; }
     32 
     33 
     34 const Register VectorStoreTransitionDescriptor::SlotRegister() { return rdi; }
     35 const Register VectorStoreTransitionDescriptor::VectorRegister() { return rbx; }
     36 const Register VectorStoreTransitionDescriptor::MapRegister() { return r11; }
     37 
     38 
     39 const Register StoreTransitionDescriptor::MapRegister() { return rbx; }
     40 
     41 
     42 const Register LoadGlobalViaContextDescriptor::SlotRegister() { return rbx; }
     43 
     44 
     45 const Register StoreGlobalViaContextDescriptor::SlotRegister() { return rbx; }
     46 const Register StoreGlobalViaContextDescriptor::ValueRegister() { return rax; }
     47 
     48 
     49 const Register InstanceOfDescriptor::LeftRegister() { return rdx; }
     50 const Register InstanceOfDescriptor::RightRegister() { return rax; }
     51 
     52 
     53 const Register StringCompareDescriptor::LeftRegister() { return rdx; }
     54 const Register StringCompareDescriptor::RightRegister() { return rax; }
     55 
     56 
     57 const Register ArgumentsAccessReadDescriptor::index() { return rdx; }
     58 const Register ArgumentsAccessReadDescriptor::parameter_count() { return rax; }
     59 
     60 
     61 const Register ArgumentsAccessNewDescriptor::function() { return rdi; }
     62 const Register ArgumentsAccessNewDescriptor::parameter_count() { return rcx; }
     63 const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return rdx; }
     64 
     65 
     66 const Register RestParamAccessDescriptor::parameter_count() { return rcx; }
     67 const Register RestParamAccessDescriptor::parameter_pointer() { return rdx; }
     68 const Register RestParamAccessDescriptor::rest_parameter_index() { return rbx; }
     69 
     70 
     71 const Register ApiGetterDescriptor::function_address() { return r8; }
     72 
     73 
     74 const Register MathPowTaggedDescriptor::exponent() { return rdx; }
     75 
     76 
     77 const Register MathPowIntegerDescriptor::exponent() {
     78   return MathPowTaggedDescriptor::exponent();
     79 }
     80 
     81 
     82 const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
     83 const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
     84 
     85 
     86 void FastNewClosureDescriptor::InitializePlatformSpecific(
     87     CallInterfaceDescriptorData* data) {
     88   Register registers[] = {rbx};
     89   data->InitializePlatformSpecific(arraysize(registers), registers);
     90 }
     91 
     92 
     93 void FastNewContextDescriptor::InitializePlatformSpecific(
     94     CallInterfaceDescriptorData* data) {
     95   Register registers[] = {rdi};
     96   data->InitializePlatformSpecific(arraysize(registers), registers);
     97 }
     98 
     99 
    100 void TypeofDescriptor::InitializePlatformSpecific(
    101     CallInterfaceDescriptorData* data) {
    102   Register registers[] = {rbx};
    103   data->InitializePlatformSpecific(arraysize(registers), registers);
    104 }
    105 
    106 
    107 void ToNumberDescriptor::InitializePlatformSpecific(
    108     CallInterfaceDescriptorData* data) {
    109   // ToNumberStub invokes a function, and therefore needs a context.
    110   Register registers[] = {rax};
    111   data->InitializePlatformSpecific(arraysize(registers), registers);
    112 }
    113 
    114 
    115 // static
    116 const Register ToLengthDescriptor::ReceiverRegister() { return rax; }
    117 
    118 
    119 // static
    120 const Register ToStringDescriptor::ReceiverRegister() { return rax; }
    121 
    122 
    123 // static
    124 const Register ToObjectDescriptor::ReceiverRegister() { return rax; }
    125 
    126 
    127 void NumberToStringDescriptor::InitializePlatformSpecific(
    128     CallInterfaceDescriptorData* data) {
    129   Register registers[] = {rax};
    130   data->InitializePlatformSpecific(arraysize(registers), registers);
    131 }
    132 
    133 
    134 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
    135     CallInterfaceDescriptorData* data) {
    136   Register registers[] = {rdi, rax, rcx, rdx};
    137   data->InitializePlatformSpecific(arraysize(registers), registers);
    138 }
    139 
    140 
    141 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
    142     CallInterfaceDescriptorData* data) {
    143   Register registers[] = {rax, rbx, rcx};
    144   data->InitializePlatformSpecific(arraysize(registers), registers);
    145 }
    146 
    147 
    148 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
    149     CallInterfaceDescriptorData* data) {
    150   Register registers[] = {rax, rbx, rcx, rdx};
    151   data->InitializePlatformSpecific(arraysize(registers), registers);
    152 }
    153 
    154 
    155 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
    156     CallInterfaceDescriptorData* data) {
    157   Register registers[] = {rbx, rdx};
    158   data->InitializePlatformSpecific(arraysize(registers), registers);
    159 }
    160 
    161 
    162 void CreateWeakCellDescriptor::InitializePlatformSpecific(
    163     CallInterfaceDescriptorData* data) {
    164   Register registers[] = {rbx, rdx, rdi};
    165   data->InitializePlatformSpecific(arraysize(registers), registers);
    166 }
    167 
    168 
    169 void StoreArrayLiteralElementDescriptor::InitializePlatformSpecific(
    170     CallInterfaceDescriptorData* data) {
    171   Register registers[] = {rcx, rax};
    172   data->InitializePlatformSpecific(arraysize(registers), registers);
    173 }
    174 
    175 
    176 void CallFunctionDescriptor::InitializePlatformSpecific(
    177     CallInterfaceDescriptorData* data) {
    178   Register registers[] = {rdi};
    179   data->InitializePlatformSpecific(arraysize(registers), registers);
    180 }
    181 
    182 
    183 void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
    184     CallInterfaceDescriptorData* data) {
    185   Register registers[] = {rdi, rdx};
    186   data->InitializePlatformSpecific(arraysize(registers), registers);
    187 }
    188 
    189 
    190 void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
    191     CallInterfaceDescriptorData* data) {
    192   Register registers[] = {rdi, rdx, rbx};
    193   data->InitializePlatformSpecific(arraysize(registers), registers);
    194 }
    195 
    196 
    197 void CallConstructDescriptor::InitializePlatformSpecific(
    198     CallInterfaceDescriptorData* data) {
    199   // rax : number of arguments
    200   // rbx : feedback vector
    201   // rdx : slot in feedback vector (Smi, for RecordCallTarget)
    202   // rdi : constructor function
    203   // TODO(turbofan): So far we don't gather type feedback and hence skip the
    204   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
    205   Register registers[] = {rax, rdi, rbx};
    206   data->InitializePlatformSpecific(arraysize(registers), registers);
    207 }
    208 
    209 
    210 void CallTrampolineDescriptor::InitializePlatformSpecific(
    211     CallInterfaceDescriptorData* data) {
    212   // rax : number of arguments
    213   // rdi : the target to call
    214   Register registers[] = {rdi, rax};
    215   data->InitializePlatformSpecific(arraysize(registers), registers);
    216 }
    217 
    218 
    219 void ConstructStubDescriptor::InitializePlatformSpecific(
    220     CallInterfaceDescriptorData* data) {
    221   // rax : number of arguments
    222   // rdx : the new target
    223   // rdi : the target to call
    224   // rbx : allocation site or undefined
    225   Register registers[] = {rdi, rdx, rax, rbx};
    226   data->InitializePlatformSpecific(arraysize(registers), registers);
    227 }
    228 
    229 
    230 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
    231     CallInterfaceDescriptorData* data) {
    232   // rax : number of arguments
    233   // rdx : the new target
    234   // rdi : the target to call
    235   Register registers[] = {rdi, rdx, rax};
    236   data->InitializePlatformSpecific(arraysize(registers), registers);
    237 }
    238 
    239 
    240 void RegExpConstructResultDescriptor::InitializePlatformSpecific(
    241     CallInterfaceDescriptorData* data) {
    242   Register registers[] = {rcx, rbx, rax};
    243   data->InitializePlatformSpecific(arraysize(registers), registers);
    244 }
    245 
    246 
    247 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
    248     CallInterfaceDescriptorData* data) {
    249   Register registers[] = {rax, rbx};
    250   data->InitializePlatformSpecific(arraysize(registers), registers);
    251 }
    252 
    253 
    254 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
    255     CallInterfaceDescriptorData* data) {
    256   data->InitializePlatformSpecific(0, nullptr, nullptr);
    257 }
    258 
    259 
    260 void AllocateInNewSpaceDescriptor::InitializePlatformSpecific(
    261     CallInterfaceDescriptorData* data) {
    262   Register registers[] = {rax};
    263   data->InitializePlatformSpecific(arraysize(registers), registers);
    264 }
    265 
    266 
    267 void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
    268     CallInterfaceDescriptorData* data) {
    269   // register state
    270   // rax -- number of arguments
    271   // rdi -- function
    272   // rbx -- allocation site with elements kind
    273   Register registers[] = {rdi, rbx};
    274   data->InitializePlatformSpecific(arraysize(registers), registers);
    275 }
    276 
    277 
    278 void ArrayConstructorDescriptor::InitializePlatformSpecific(
    279     CallInterfaceDescriptorData* data) {
    280   // stack param count needs (constructor pointer, and single argument)
    281   Register registers[] = {rdi, rbx, rax};
    282   data->InitializePlatformSpecific(arraysize(registers), registers);
    283 }
    284 
    285 
    286 void InternalArrayConstructorConstantArgCountDescriptor::
    287     InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
    288   // register state
    289   // rax -- number of arguments
    290   // rdi -- constructor function
    291   Register registers[] = {rdi};
    292   data->InitializePlatformSpecific(arraysize(registers), registers);
    293 }
    294 
    295 
    296 void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
    297     CallInterfaceDescriptorData* data) {
    298   // stack param count needs (constructor pointer, and single argument)
    299   Register registers[] = {rdi, rax};
    300   data->InitializePlatformSpecific(arraysize(registers), registers);
    301 }
    302 
    303 
    304 void CompareDescriptor::InitializePlatformSpecific(
    305     CallInterfaceDescriptorData* data) {
    306   Register registers[] = {rdx, rax};
    307   data->InitializePlatformSpecific(arraysize(registers), registers);
    308 }
    309 
    310 
    311 void CompareNilDescriptor::InitializePlatformSpecific(
    312     CallInterfaceDescriptorData* data) {
    313   Register registers[] = {rax};
    314   data->InitializePlatformSpecific(arraysize(registers), registers);
    315 }
    316 
    317 
    318 void ToBooleanDescriptor::InitializePlatformSpecific(
    319     CallInterfaceDescriptorData* data) {
    320   Register registers[] = {rax};
    321   data->InitializePlatformSpecific(arraysize(registers), registers);
    322 }
    323 
    324 
    325 void BinaryOpDescriptor::InitializePlatformSpecific(
    326     CallInterfaceDescriptorData* data) {
    327   Register registers[] = {rdx, rax};
    328   data->InitializePlatformSpecific(arraysize(registers), registers);
    329 }
    330 
    331 
    332 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
    333     CallInterfaceDescriptorData* data) {
    334   Register registers[] = {rcx, rdx, rax};
    335   data->InitializePlatformSpecific(arraysize(registers), registers);
    336 }
    337 
    338 
    339 void StringAddDescriptor::InitializePlatformSpecific(
    340     CallInterfaceDescriptorData* data) {
    341   Register registers[] = {rdx, rax};
    342   data->InitializePlatformSpecific(arraysize(registers), registers);
    343 }
    344 
    345 
    346 void KeyedDescriptor::InitializePlatformSpecific(
    347     CallInterfaceDescriptorData* data) {
    348   Register registers[] = {
    349       rcx,  // key
    350   };
    351   data->InitializePlatformSpecific(arraysize(registers), registers);
    352 }
    353 
    354 
    355 void NamedDescriptor::InitializePlatformSpecific(
    356     CallInterfaceDescriptorData* data) {
    357   Register registers[] = {
    358       rcx,  // name
    359   };
    360   data->InitializePlatformSpecific(arraysize(registers), registers);
    361 }
    362 
    363 
    364 void CallHandlerDescriptor::InitializePlatformSpecific(
    365     CallInterfaceDescriptorData* data) {
    366   Register registers[] = {
    367       rdx,  // receiver
    368   };
    369   data->InitializePlatformSpecific(arraysize(registers), registers);
    370 }
    371 
    372 
    373 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    374     CallInterfaceDescriptorData* data) {
    375   Register registers[] = {
    376       rdi,  // JSFunction
    377       rdx,  // the new target
    378       rax,  // actual number of arguments
    379       rbx,  // expected number of arguments
    380   };
    381   data->InitializePlatformSpecific(arraysize(registers), registers);
    382 }
    383 
    384 
    385 void ApiFunctionDescriptor::InitializePlatformSpecific(
    386     CallInterfaceDescriptorData* data) {
    387   Register registers[] = {
    388       rdi,  // callee
    389       rbx,  // call_data
    390       rcx,  // holder
    391       rdx,  // api_function_address
    392       rax,  // actual number of arguments
    393   };
    394   data->InitializePlatformSpecific(arraysize(registers), registers);
    395 }
    396 
    397 
    398 void ApiAccessorDescriptor::InitializePlatformSpecific(
    399     CallInterfaceDescriptorData* data) {
    400   Register registers[] = {
    401       rdi,  // callee
    402       rbx,  // call_data
    403       rcx,  // holder
    404       rdx,  // api_function_address
    405   };
    406   data->InitializePlatformSpecific(arraysize(registers), registers);
    407 }
    408 
    409 
    410 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
    411     CallInterfaceDescriptorData* data) {
    412   Register registers[] = {
    413       rax,  // argument count (not including receiver)
    414       rbx,  // address of first argument
    415       rdi   // the target callable to be call
    416   };
    417   data->InitializePlatformSpecific(arraysize(registers), registers);
    418 }
    419 
    420 
    421 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
    422     CallInterfaceDescriptorData* data) {
    423   Register registers[] = {
    424       rax,  // argument count (not including receiver)
    425       rdx,  // new target
    426       rdi,  // constructor
    427       rbx,  // address of first argument
    428   };
    429   data->InitializePlatformSpecific(arraysize(registers), registers);
    430 }
    431 
    432 
    433 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
    434     CallInterfaceDescriptorData* data) {
    435   Register registers[] = {
    436       rax,  // argument count (argc)
    437       r15,  // address of first argument (argv)
    438       rbx   // the runtime function to call
    439   };
    440   data->InitializePlatformSpecific(arraysize(registers), registers);
    441 }
    442 
    443 }  // namespace internal
    444 }  // namespace v8
    445 
    446 #endif  // V8_TARGET_ARCH_X64
    447