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