Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 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 #ifndef V8_INTERPRETER_BYTECODE_TRAITS_H_
      6 #define V8_INTERPRETER_BYTECODE_TRAITS_H_
      7 
      8 #include "src/interpreter/bytecode-operands.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 namespace interpreter {
     13 
     14 template <OperandTypeInfo>
     15 struct OperandTypeInfoTraits {
     16   static const bool kIsScalable = false;
     17   static const bool kIsUnsigned = false;
     18   static const OperandSize kUnscaledSize = OperandSize::kNone;
     19 };
     20 
     21 #define DECLARE_OPERAND_TYPE_INFO(Name, Scalable, Unsigned, BaseSize) \
     22   template <>                                                         \
     23   struct OperandTypeInfoTraits<OperandTypeInfo::k##Name> {            \
     24     static const bool kIsScalable = Scalable;                         \
     25     static const bool kIsUnsigned = Unsigned;                         \
     26     static const OperandSize kUnscaledSize = BaseSize;                \
     27   };
     28 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
     29 #undef DECLARE_OPERAND_TYPE_INFO
     30 
     31 template <OperandType>
     32 struct OperandTraits {
     33   typedef OperandTypeInfoTraits<OperandTypeInfo::kNone> TypeInfoTraits;
     34   static const OperandTypeInfo kOperandTypeInfo = OperandTypeInfo::kNone;
     35 };
     36 
     37 #define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType)           \
     38   template <>                                                 \
     39   struct OperandTraits<OperandType::k##Name> {                \
     40     typedef OperandTypeInfoTraits<InfoType> TypeInfoTraits;   \
     41     static const OperandTypeInfo kOperandTypeInfo = InfoType; \
     42   };
     43 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
     44 #undef DECLARE_OPERAND_TYPE_TRAITS
     45 
     46 template <OperandType operand_type, OperandScale operand_scale>
     47 struct OperandScaler {
     48   template <bool, OperandSize, OperandScale>
     49   struct Helper {
     50     static const int kSize = 0;
     51   };
     52   template <OperandSize size, OperandScale scale>
     53   struct Helper<false, size, scale> {
     54     static const int kSize = static_cast<int>(size);
     55   };
     56   template <OperandSize size, OperandScale scale>
     57   struct Helper<true, size, scale> {
     58     static const int kSize = static_cast<int>(size) * static_cast<int>(scale);
     59   };
     60 
     61   static const int kSize =
     62       Helper<OperandTraits<operand_type>::TypeInfoTraits::kIsScalable,
     63              OperandTraits<operand_type>::TypeInfoTraits::kUnscaledSize,
     64              operand_scale>::kSize;
     65   static const OperandSize kOperandSize = static_cast<OperandSize>(kSize);
     66 };
     67 
     68 template <int... values>
     69 struct SumHelper;
     70 template <int value>
     71 struct SumHelper<value> {
     72   static const int kValue = value;
     73 };
     74 template <int value, int... values>
     75 struct SumHelper<value, values...> {
     76   static const int kValue = value + SumHelper<values...>::kValue;
     77 };
     78 
     79 template <AccumulatorUse accumulator_use, OperandType... operands>
     80 struct BytecodeTraits {
     81   static const OperandType kOperandTypes[];
     82   static const OperandTypeInfo kOperandTypeInfos[];
     83   static const OperandSize kSingleScaleOperandSizes[];
     84   static const OperandSize kDoubleScaleOperandSizes[];
     85   static const OperandSize kQuadrupleScaleOperandSizes[];
     86   static const int kSingleScaleSize = SumHelper<
     87       1, OperandScaler<operands, OperandScale::kSingle>::kSize...>::kValue;
     88   static const int kDoubleScaleSize = SumHelper<
     89       1, OperandScaler<operands, OperandScale::kDouble>::kSize...>::kValue;
     90   static const int kQuadrupleScaleSize = SumHelper<
     91       1, OperandScaler<operands, OperandScale::kQuadruple>::kSize...>::kValue;
     92   static const AccumulatorUse kAccumulatorUse = accumulator_use;
     93   static const int kOperandCount = sizeof...(operands);
     94 };
     95 
     96 template <AccumulatorUse accumulator_use, OperandType... operands>
     97 STATIC_CONST_MEMBER_DEFINITION const OperandType
     98     BytecodeTraits<accumulator_use, operands...>::kOperandTypes[] = {
     99         operands...};
    100 template <AccumulatorUse accumulator_use, OperandType... operands>
    101 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo
    102     BytecodeTraits<accumulator_use, operands...>::kOperandTypeInfos[] = {
    103         OperandTraits<operands>::kOperandTypeInfo...};
    104 template <AccumulatorUse accumulator_use, OperandType... operands>
    105 STATIC_CONST_MEMBER_DEFINITION const OperandSize
    106     BytecodeTraits<accumulator_use, operands...>::kSingleScaleOperandSizes[] = {
    107         OperandScaler<operands, OperandScale::kSingle>::kOperandSize...};
    108 template <AccumulatorUse accumulator_use, OperandType... operands>
    109 STATIC_CONST_MEMBER_DEFINITION const OperandSize
    110     BytecodeTraits<accumulator_use, operands...>::kDoubleScaleOperandSizes[] = {
    111         OperandScaler<operands, OperandScale::kDouble>::kOperandSize...};
    112 template <AccumulatorUse accumulator_use, OperandType... operands>
    113 STATIC_CONST_MEMBER_DEFINITION const OperandSize BytecodeTraits<
    114     accumulator_use, operands...>::kQuadrupleScaleOperandSizes[] = {
    115     OperandScaler<operands, OperandScale::kQuadruple>::kOperandSize...};
    116 
    117 template <AccumulatorUse accumulator_use>
    118 struct BytecodeTraits<accumulator_use> {
    119   static const OperandType kOperandTypes[];
    120   static const OperandTypeInfo kOperandTypeInfos[];
    121   static const OperandSize kSingleScaleOperandSizes[];
    122   static const OperandSize kDoubleScaleOperandSizes[];
    123   static const OperandSize kQuadrupleScaleOperandSizes[];
    124   static const int kSingleScaleSize = 1;
    125   static const int kDoubleScaleSize = 1;
    126   static const int kQuadrupleScaleSize = 1;
    127   static const AccumulatorUse kAccumulatorUse = accumulator_use;
    128   static const int kOperandCount = 0;
    129 };
    130 
    131 template <AccumulatorUse accumulator_use>
    132 STATIC_CONST_MEMBER_DEFINITION const OperandType
    133     BytecodeTraits<accumulator_use>::kOperandTypes[] = {OperandType::kNone};
    134 template <AccumulatorUse accumulator_use>
    135 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo
    136     BytecodeTraits<accumulator_use>::kOperandTypeInfos[] = {
    137         OperandTypeInfo::kNone};
    138 template <AccumulatorUse accumulator_use>
    139 STATIC_CONST_MEMBER_DEFINITION const OperandSize
    140     BytecodeTraits<accumulator_use>::kSingleScaleOperandSizes[] = {
    141         OperandSize::kNone};
    142 template <AccumulatorUse accumulator_use>
    143 STATIC_CONST_MEMBER_DEFINITION const OperandSize
    144     BytecodeTraits<accumulator_use>::kDoubleScaleOperandSizes[] = {
    145         OperandSize::kNone};
    146 template <AccumulatorUse accumulator_use>
    147 STATIC_CONST_MEMBER_DEFINITION const OperandSize
    148     BytecodeTraits<accumulator_use>::kQuadrupleScaleOperandSizes[] = {
    149         OperandSize::kNone};
    150 
    151 }  // namespace interpreter
    152 }  // namespace internal
    153 }  // namespace v8
    154 
    155 #endif  // V8_INTERPRETER_BYTECODE_TRAITS_H_
    156