Home | History | Annotate | Download | only in arm
      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/arm/interface-descriptors-arm.h"
      6 
      7 #if V8_TARGET_ARCH_ARM
      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[] = {r0, r1, r2, r3, r4};
     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 FastNewFunctionContextDescriptor::FunctionRegister() {
     26   return r1;
     27 }
     28 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return r0; }
     29 
     30 const Register LoadDescriptor::ReceiverRegister() { return r1; }
     31 const Register LoadDescriptor::NameRegister() { return r2; }
     32 const Register LoadDescriptor::SlotRegister() { return r0; }
     33 
     34 const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
     35 
     36 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r4; }
     37 
     38 const Register StoreDescriptor::ReceiverRegister() { return r1; }
     39 const Register StoreDescriptor::NameRegister() { return r2; }
     40 const Register StoreDescriptor::ValueRegister() { return r0; }
     41 const Register StoreDescriptor::SlotRegister() { return r4; }
     42 
     43 const Register StoreWithVectorDescriptor::VectorRegister() { return r3; }
     44 
     45 const Register StoreTransitionDescriptor::SlotRegister() { return r4; }
     46 const Register StoreTransitionDescriptor::VectorRegister() { return r3; }
     47 const Register StoreTransitionDescriptor::MapRegister() { return r5; }
     48 
     49 const Register StringCompareDescriptor::LeftRegister() { return r1; }
     50 const Register StringCompareDescriptor::RightRegister() { return r0; }
     51 
     52 const Register ApiGetterDescriptor::HolderRegister() { return r0; }
     53 const Register ApiGetterDescriptor::CallbackRegister() { return r3; }
     54 
     55 const Register MathPowTaggedDescriptor::exponent() { return r2; }
     56 
     57 
     58 const Register MathPowIntegerDescriptor::exponent() {
     59   return MathPowTaggedDescriptor::exponent();
     60 }
     61 
     62 
     63 const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
     64 const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
     65 
     66 
     67 void FastNewClosureDescriptor::InitializePlatformSpecific(
     68     CallInterfaceDescriptorData* data) {
     69   Register registers[] = {r1, r2, r3};
     70   data->InitializePlatformSpecific(arraysize(registers), registers);
     71 }
     72 
     73 // static
     74 const Register TypeConversionDescriptor::ArgumentRegister() { return r0; }
     75 
     76 void TypeofDescriptor::InitializePlatformSpecific(
     77     CallInterfaceDescriptorData* data) {
     78   Register registers[] = {r3};
     79   data->InitializePlatformSpecific(arraysize(registers), registers);
     80 }
     81 
     82 
     83 void FastCloneRegExpDescriptor::InitializePlatformSpecific(
     84     CallInterfaceDescriptorData* data) {
     85   Register registers[] = {r3, r2, r1, r0};
     86   data->InitializePlatformSpecific(arraysize(registers), registers);
     87 }
     88 
     89 
     90 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
     91     CallInterfaceDescriptorData* data) {
     92   Register registers[] = {r3, r2, r1};
     93   data->InitializePlatformSpecific(arraysize(registers), registers);
     94 }
     95 
     96 
     97 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
     98     CallInterfaceDescriptorData* data) {
     99   Register registers[] = {r3, r2, r1, r0};
    100   data->InitializePlatformSpecific(arraysize(registers), registers);
    101 }
    102 
    103 
    104 void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
    105     CallInterfaceDescriptorData* data) {
    106   Register registers[] = {r2, r3};
    107   data->InitializePlatformSpecific(arraysize(registers), registers);
    108 }
    109 
    110 
    111 void CreateWeakCellDescriptor::InitializePlatformSpecific(
    112     CallInterfaceDescriptorData* data) {
    113   Register registers[] = {r2, r3, r1};
    114   data->InitializePlatformSpecific(arraysize(registers), registers);
    115 }
    116 
    117 
    118 void CallFunctionDescriptor::InitializePlatformSpecific(
    119     CallInterfaceDescriptorData* data) {
    120   Register registers[] = {r1};
    121   data->InitializePlatformSpecific(arraysize(registers), registers);
    122 }
    123 
    124 void CallICTrampolineDescriptor::InitializePlatformSpecific(
    125     CallInterfaceDescriptorData* data) {
    126   Register registers[] = {r1, r0, r3};
    127   data->InitializePlatformSpecific(arraysize(registers), registers);
    128 }
    129 
    130 void CallICDescriptor::InitializePlatformSpecific(
    131     CallInterfaceDescriptorData* data) {
    132   Register registers[] = {r1, r0, r3, r2};
    133   data->InitializePlatformSpecific(arraysize(registers), registers);
    134 }
    135 
    136 
    137 void CallConstructDescriptor::InitializePlatformSpecific(
    138     CallInterfaceDescriptorData* data) {
    139   // r0 : number of arguments
    140   // r1 : the function to call
    141   // r2 : feedback vector
    142   // r3 : slot in feedback vector (Smi, for RecordCallTarget)
    143   // r4 : new target (for IsSuperConstructorCall)
    144   // TODO(turbofan): So far we don't gather type feedback and hence skip the
    145   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
    146   Register registers[] = {r0, r1, r4, r2};
    147   data->InitializePlatformSpecific(arraysize(registers), registers);
    148 }
    149 
    150 
    151 void CallTrampolineDescriptor::InitializePlatformSpecific(
    152     CallInterfaceDescriptorData* data) {
    153   // r0 : number of arguments
    154   // r1 : the target to call
    155   Register registers[] = {r1, r0};
    156   data->InitializePlatformSpecific(arraysize(registers), registers);
    157 }
    158 
    159 void CallForwardVarargsDescriptor::InitializePlatformSpecific(
    160     CallInterfaceDescriptorData* data) {
    161   // r2 : start index (to support rest parameters)
    162   // r1 : the target to call
    163   Register registers[] = {r1, r2};
    164   data->InitializePlatformSpecific(arraysize(registers), registers);
    165 }
    166 
    167 void ConstructStubDescriptor::InitializePlatformSpecific(
    168     CallInterfaceDescriptorData* data) {
    169   // r0 : number of arguments
    170   // r1 : the target to call
    171   // r3 : the new target
    172   // r2 : allocation site or undefined
    173   Register registers[] = {r1, r3, r0, r2};
    174   data->InitializePlatformSpecific(arraysize(registers), registers);
    175 }
    176 
    177 
    178 void ConstructTrampolineDescriptor::InitializePlatformSpecific(
    179     CallInterfaceDescriptorData* data) {
    180   // r0 : number of arguments
    181   // r1 : the target to call
    182   // r3 : the new target
    183   Register registers[] = {r1, r3, r0};
    184   data->InitializePlatformSpecific(arraysize(registers), registers);
    185 }
    186 
    187 
    188 void TransitionElementsKindDescriptor::InitializePlatformSpecific(
    189     CallInterfaceDescriptorData* data) {
    190   Register registers[] = {r0, r1};
    191   data->InitializePlatformSpecific(arraysize(registers), registers);
    192 }
    193 
    194 
    195 void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
    196     CallInterfaceDescriptorData* data) {
    197   data->InitializePlatformSpecific(0, nullptr, nullptr);
    198 }
    199 
    200 void ArrayConstructorDescriptor::InitializePlatformSpecific(
    201     CallInterfaceDescriptorData* data) {
    202   // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite
    203   Register registers[] = {r1, r3, r0, r2};
    204   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    205 }
    206 
    207 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
    208     CallInterfaceDescriptorData* data) {
    209   // register state
    210   // r0 -- number of arguments
    211   // r1 -- function
    212   // r2 -- allocation site with elements kind
    213   Register registers[] = {r1, r2, r0};
    214   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    215 }
    216 
    217 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
    218     CallInterfaceDescriptorData* data) {
    219   // register state
    220   // r0 -- number of arguments
    221   // r1 -- function
    222   // r2 -- allocation site with elements kind
    223   Register registers[] = {r1, r2, r0};
    224   data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
    225 }
    226 
    227 void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
    228     CallInterfaceDescriptorData* data) {
    229   // stack param count needs (constructor pointer, and single argument)
    230   Register registers[] = {r1, r2, r0};
    231   data->InitializePlatformSpecific(arraysize(registers), registers);
    232 }
    233 
    234 
    235 void VarArgFunctionDescriptor::InitializePlatformSpecific(
    236     CallInterfaceDescriptorData* data) {
    237   // stack param count needs (arg count)
    238   Register registers[] = {r0};
    239   data->InitializePlatformSpecific(arraysize(registers), registers);
    240 }
    241 
    242 void CompareDescriptor::InitializePlatformSpecific(
    243     CallInterfaceDescriptorData* data) {
    244   Register registers[] = {r1, r0};
    245   data->InitializePlatformSpecific(arraysize(registers), registers);
    246 }
    247 
    248 
    249 void BinaryOpDescriptor::InitializePlatformSpecific(
    250     CallInterfaceDescriptorData* data) {
    251   Register registers[] = {r1, r0};
    252   data->InitializePlatformSpecific(arraysize(registers), registers);
    253 }
    254 
    255 
    256 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
    257     CallInterfaceDescriptorData* data) {
    258   Register registers[] = {r2, r1, r0};
    259   data->InitializePlatformSpecific(arraysize(registers), registers);
    260 }
    261 
    262 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
    263     CallInterfaceDescriptorData* data) {
    264   // register state
    265   // r1 -- lhs
    266   // r0 -- rhs
    267   // r4 -- slot id
    268   // r3 -- vector
    269   Register registers[] = {r1, r0, r4, r3};
    270   data->InitializePlatformSpecific(arraysize(registers), registers);
    271 }
    272 
    273 void CountOpDescriptor::InitializePlatformSpecific(
    274     CallInterfaceDescriptorData* data) {
    275   Register registers[] = {r1};
    276   data->InitializePlatformSpecific(arraysize(registers), registers);
    277 }
    278 
    279 void StringAddDescriptor::InitializePlatformSpecific(
    280     CallInterfaceDescriptorData* data) {
    281   Register registers[] = {r1, r0};
    282   data->InitializePlatformSpecific(arraysize(registers), registers);
    283 }
    284 
    285 
    286 void KeyedDescriptor::InitializePlatformSpecific(
    287     CallInterfaceDescriptorData* data) {
    288   static PlatformInterfaceDescriptor noInlineDescriptor =
    289       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
    290 
    291   Register registers[] = {
    292       r2,  // key
    293   };
    294   data->InitializePlatformSpecific(arraysize(registers), registers,
    295                                    &noInlineDescriptor);
    296 }
    297 
    298 
    299 void NamedDescriptor::InitializePlatformSpecific(
    300     CallInterfaceDescriptorData* data) {
    301   static PlatformInterfaceDescriptor noInlineDescriptor =
    302       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
    303 
    304   Register registers[] = {
    305       r2,  // name
    306   };
    307   data->InitializePlatformSpecific(arraysize(registers), registers,
    308                                    &noInlineDescriptor);
    309 }
    310 
    311 
    312 void CallHandlerDescriptor::InitializePlatformSpecific(
    313     CallInterfaceDescriptorData* data) {
    314   static PlatformInterfaceDescriptor default_descriptor =
    315       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
    316 
    317   Register registers[] = {
    318       r0,  // receiver
    319   };
    320   data->InitializePlatformSpecific(arraysize(registers), registers,
    321                                    &default_descriptor);
    322 }
    323 
    324 
    325 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    326     CallInterfaceDescriptorData* data) {
    327   static PlatformInterfaceDescriptor default_descriptor =
    328       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
    329 
    330   Register registers[] = {
    331       r1,  // JSFunction
    332       r3,  // the new target
    333       r0,  // actual number of arguments
    334       r2,  // expected number of arguments
    335   };
    336   data->InitializePlatformSpecific(arraysize(registers), registers,
    337                                    &default_descriptor);
    338 }
    339 
    340 void ApiCallbackDescriptor::InitializePlatformSpecific(
    341     CallInterfaceDescriptorData* data) {
    342   static PlatformInterfaceDescriptor default_descriptor =
    343       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
    344 
    345   Register registers[] = {
    346       r0,  // callee
    347       r4,  // call_data
    348       r2,  // holder
    349       r1,  // api_function_address
    350   };
    351   data->InitializePlatformSpecific(arraysize(registers), registers,
    352                                    &default_descriptor);
    353 }
    354 
    355 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
    356     CallInterfaceDescriptorData* data) {
    357   Register registers[] = {
    358       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
    359       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
    360   data->InitializePlatformSpecific(arraysize(registers), registers);
    361 }
    362 
    363 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
    364     CallInterfaceDescriptorData* data) {
    365   Register registers[] = {
    366       r0,  // argument count (not including receiver)
    367       r2,  // address of first argument
    368       r1   // the target callable to be call
    369   };
    370   data->InitializePlatformSpecific(arraysize(registers), registers);
    371 }
    372 
    373 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
    374     CallInterfaceDescriptorData* data) {
    375   Register registers[] = {
    376       r0,  // argument count (not including receiver)
    377       r3,  // new target
    378       r1,  // constructor to call
    379       r2,  // allocation site feedback if available, undefined otherwise
    380       r4   // address of the first argument
    381   };
    382   data->InitializePlatformSpecific(arraysize(registers), registers);
    383 }
    384 
    385 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
    386     CallInterfaceDescriptorData* data) {
    387   Register registers[] = {
    388       r0,  // argument count (not including receiver)
    389       r1,  // target to call checked to be Array function
    390       r2,  // allocation site feedback if available, undefined otherwise
    391       r3   // address of the first argument
    392   };
    393   data->InitializePlatformSpecific(arraysize(registers), registers);
    394 }
    395 
    396 void InterpreterCEntryDescriptor::InitializePlatformSpecific(
    397     CallInterfaceDescriptorData* data) {
    398   Register registers[] = {
    399       r0,  // argument count (argc)
    400       r2,  // address of first argument (argv)
    401       r1   // the runtime function to call
    402   };
    403   data->InitializePlatformSpecific(arraysize(registers), registers);
    404 }
    405 
    406 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
    407     CallInterfaceDescriptorData* data) {
    408   Register registers[] = {
    409       r0,  // the value to pass to the generator
    410       r1,  // the JSGeneratorObject to resume
    411       r2   // the resume mode (tagged)
    412   };
    413   data->InitializePlatformSpecific(arraysize(registers), registers);
    414 }
    415 
    416 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
    417     CallInterfaceDescriptorData* data) {
    418   Register registers[] = {
    419       r1,  // loaded new FP
    420   };
    421   data->InitializePlatformSpecific(arraysize(registers), registers);
    422 }
    423 
    424 }  // namespace internal
    425 }  // namespace v8
    426 
    427 #endif  // V8_TARGET_ARCH_ARM
    428