Home | History | Annotate | Download | only in arm64
      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 #include "src/v8.h"
      6 
      7 #if V8_TARGET_ARCH_ARM64
      8 
      9 #include "src/interface-descriptors.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
     15 
     16 
     17 const Register LoadDescriptor::ReceiverRegister() { return x1; }
     18 const Register LoadDescriptor::NameRegister() { return x2; }
     19 
     20 
     21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; }
     22 
     23 
     24 const Register VectorLoadICDescriptor::VectorRegister() { return x3; }
     25 
     26 
     27 const Register StoreDescriptor::ReceiverRegister() { return x1; }
     28 const Register StoreDescriptor::NameRegister() { return x2; }
     29 const Register StoreDescriptor::ValueRegister() { return x0; }
     30 
     31 
     32 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; }
     33 
     34 
     35 const Register InstanceofDescriptor::left() {
     36   // Object to check (instanceof lhs).
     37   return x11;
     38 }
     39 
     40 
     41 const Register InstanceofDescriptor::right() {
     42   // Constructor function (instanceof rhs).
     43   return x10;
     44 }
     45 
     46 
     47 const Register ArgumentsAccessReadDescriptor::index() { return x1; }
     48 const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
     49 
     50 
     51 const Register ApiGetterDescriptor::function_address() { return x2; }
     52 
     53 
     54 const Register MathPowTaggedDescriptor::exponent() { return x11; }
     55 
     56 
     57 const Register MathPowIntegerDescriptor::exponent() { return x12; }
     58 
     59 
     60 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
     61   // cp: context
     62   // x2: function info
     63   Register registers[] = {cp, x2};
     64   data->Initialize(arraysize(registers), registers, NULL);
     65 }
     66 
     67 
     68 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
     69   // cp: context
     70   // x1: function
     71   Register registers[] = {cp, x1};
     72   data->Initialize(arraysize(registers), registers, NULL);
     73 }
     74 
     75 
     76 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
     77   // cp: context
     78   // x0: value
     79   Register registers[] = {cp, x0};
     80   data->Initialize(arraysize(registers), registers, NULL);
     81 }
     82 
     83 
     84 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
     85   // cp: context
     86   // x0: value
     87   Register registers[] = {cp, x0};
     88   data->Initialize(arraysize(registers), registers, NULL);
     89 }
     90 
     91 
     92 void FastCloneShallowArrayDescriptor::Initialize(
     93     CallInterfaceDescriptorData* data) {
     94   // cp: context
     95   // x3: array literals array
     96   // x2: array literal index
     97   // x1: constant elements
     98   Register registers[] = {cp, x3, x2, x1};
     99   Representation representations[] = {
    100       Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
    101       Representation::Tagged()};
    102   data->Initialize(arraysize(registers), registers, representations);
    103 }
    104 
    105 
    106 void FastCloneShallowObjectDescriptor::Initialize(
    107     CallInterfaceDescriptorData* data) {
    108   // cp: context
    109   // x3: object literals array
    110   // x2: object literal index
    111   // x1: constant properties
    112   // x0: object literal flags
    113   Register registers[] = {cp, x3, x2, x1, x0};
    114   data->Initialize(arraysize(registers), registers, NULL);
    115 }
    116 
    117 
    118 void CreateAllocationSiteDescriptor::Initialize(
    119     CallInterfaceDescriptorData* data) {
    120   // cp: context
    121   // x2: feedback vector
    122   // x3: call feedback slot
    123   Register registers[] = {cp, x2, x3};
    124   data->Initialize(arraysize(registers), registers, NULL);
    125 }
    126 
    127 
    128 void StoreArrayLiteralElementDescriptor::Initialize(
    129     CallInterfaceDescriptorData* data) {
    130   Register registers[] = {cp, x3, x0};
    131   data->Initialize(arraysize(registers), registers, NULL);
    132 }
    133 
    134 
    135 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    136   // x1  function    the function to call
    137   Register registers[] = {cp, x1};
    138   data->Initialize(arraysize(registers), registers, NULL);
    139 }
    140 
    141 
    142 void CallFunctionWithFeedbackDescriptor::Initialize(
    143     CallInterfaceDescriptorData* data) {
    144   Register registers[] = {cp, x1, x3};
    145   Representation representations[] = {Representation::Tagged(),
    146                                       Representation::Tagged(),
    147                                       Representation::Smi()};
    148   data->Initialize(arraysize(registers), registers, representations);
    149 }
    150 
    151 
    152 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    153   // x0 : number of arguments
    154   // x1 : the function to call
    155   // x2 : feedback vector
    156   // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
    157   // TODO(turbofan): So far we don't gather type feedback and hence skip the
    158   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
    159   Register registers[] = {cp, x0, x1, x2};
    160   data->Initialize(arraysize(registers), registers, NULL);
    161 }
    162 
    163 
    164 void RegExpConstructResultDescriptor::Initialize(
    165     CallInterfaceDescriptorData* data) {
    166   // cp: context
    167   // x2: length
    168   // x1: index (of last match)
    169   // x0: string
    170   Register registers[] = {cp, x2, x1, x0};
    171   data->Initialize(arraysize(registers), registers, NULL);
    172 }
    173 
    174 
    175 void TransitionElementsKindDescriptor::Initialize(
    176     CallInterfaceDescriptorData* data) {
    177   // cp: context
    178   // x0: value (js_array)
    179   // x1: to_map
    180   Register registers[] = {cp, x0, x1};
    181   data->Initialize(arraysize(registers), registers, NULL);
    182 }
    183 
    184 
    185 void ArrayConstructorConstantArgCountDescriptor::Initialize(
    186     CallInterfaceDescriptorData* data) {
    187   // cp: context
    188   // x1: function
    189   // x2: allocation site with elements kind
    190   // x0: number of arguments to the constructor function
    191   Register registers[] = {cp, x1, x2};
    192   data->Initialize(arraysize(registers), registers, NULL);
    193 }
    194 
    195 
    196 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    197   // stack param count needs (constructor pointer, and single argument)
    198   Register registers[] = {cp, x1, x2, x0};
    199   Representation representations[] = {
    200       Representation::Tagged(), Representation::Tagged(),
    201       Representation::Tagged(), Representation::Integer32()};
    202   data->Initialize(arraysize(registers), registers, representations);
    203 }
    204 
    205 
    206 void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
    207     CallInterfaceDescriptorData* data) {
    208   // cp: context
    209   // x1: constructor function
    210   // x0: number of arguments to the constructor function
    211   Register registers[] = {cp, x1};
    212   data->Initialize(arraysize(registers), registers, NULL);
    213 }
    214 
    215 
    216 void InternalArrayConstructorDescriptor::Initialize(
    217     CallInterfaceDescriptorData* data) {
    218   // stack param count needs (constructor pointer, and single argument)
    219   Register registers[] = {cp, x1, x0};
    220   Representation representations[] = {Representation::Tagged(),
    221                                       Representation::Tagged(),
    222                                       Representation::Integer32()};
    223   data->Initialize(arraysize(registers), registers, representations);
    224 }
    225 
    226 
    227 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    228   // cp: context
    229   // x0: value to compare
    230   Register registers[] = {cp, x0};
    231   data->Initialize(arraysize(registers), registers, NULL);
    232 }
    233 
    234 
    235 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    236   // cp: context
    237   // x0: value
    238   Register registers[] = {cp, x0};
    239   data->Initialize(arraysize(registers), registers, NULL);
    240 }
    241 
    242 
    243 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    244   // cp: context
    245   // x1: left operand
    246   // x0: right operand
    247   Register registers[] = {cp, x1, x0};
    248   data->Initialize(arraysize(registers), registers, NULL);
    249 }
    250 
    251 
    252 void BinaryOpWithAllocationSiteDescriptor::Initialize(
    253     CallInterfaceDescriptorData* data) {
    254   // cp: context
    255   // x2: allocation site
    256   // x1: left operand
    257   // x0: right operand
    258   Register registers[] = {cp, x2, x1, x0};
    259   data->Initialize(arraysize(registers), registers, NULL);
    260 }
    261 
    262 
    263 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    264   // cp: context
    265   // x1: left operand
    266   // x0: right operand
    267   Register registers[] = {cp, x1, x0};
    268   data->Initialize(arraysize(registers), registers, NULL);
    269 }
    270 
    271 
    272 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    273   static PlatformInterfaceDescriptor noInlineDescriptor =
    274       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
    275 
    276   Register registers[] = {
    277       cp,  // context
    278       x2,  // key
    279   };
    280   Representation representations[] = {
    281       Representation::Tagged(),  // context
    282       Representation::Tagged(),  // key
    283   };
    284   data->Initialize(arraysize(registers), registers, representations,
    285                    &noInlineDescriptor);
    286 }
    287 
    288 
    289 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    290   static PlatformInterfaceDescriptor noInlineDescriptor =
    291       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
    292 
    293   Register registers[] = {
    294       cp,  // context
    295       x2,  // name
    296   };
    297   Representation representations[] = {
    298       Representation::Tagged(),  // context
    299       Representation::Tagged(),  // name
    300   };
    301   data->Initialize(arraysize(registers), registers, representations,
    302                    &noInlineDescriptor);
    303 }
    304 
    305 
    306 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    307   static PlatformInterfaceDescriptor default_descriptor =
    308       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
    309 
    310   Register registers[] = {
    311       cp,  // context
    312       x0,  // receiver
    313   };
    314   Representation representations[] = {
    315       Representation::Tagged(),  // context
    316       Representation::Tagged(),  // receiver
    317   };
    318   data->Initialize(arraysize(registers), registers, representations,
    319                    &default_descriptor);
    320 }
    321 
    322 
    323 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    324   static PlatformInterfaceDescriptor default_descriptor =
    325       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
    326 
    327   Register registers[] = {
    328       cp,  // context
    329       x1,  // JSFunction
    330       x0,  // actual number of arguments
    331       x2,  // expected number of arguments
    332   };
    333   Representation representations[] = {
    334       Representation::Tagged(),     // context
    335       Representation::Tagged(),     // JSFunction
    336       Representation::Integer32(),  // actual number of arguments
    337       Representation::Integer32(),  // expected number of arguments
    338   };
    339   data->Initialize(arraysize(registers), registers, representations,
    340                    &default_descriptor);
    341 }
    342 
    343 
    344 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
    345   static PlatformInterfaceDescriptor default_descriptor =
    346       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
    347 
    348   Register registers[] = {
    349       cp,  // context
    350       x0,  // callee
    351       x4,  // call_data
    352       x2,  // holder
    353       x1,  // api_function_address
    354   };
    355   Representation representations[] = {
    356       Representation::Tagged(),    // context
    357       Representation::Tagged(),    // callee
    358       Representation::Tagged(),    // call_data
    359       Representation::Tagged(),    // holder
    360       Representation::External(),  // api_function_address
    361   };
    362   data->Initialize(arraysize(registers), registers, representations,
    363                    &default_descriptor);
    364 }
    365 }
    366 }  // namespace v8::internal
    367 
    368 #endif  // V8_TARGET_ARCH_ARM64
    369