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