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   using TypeInfoTraits = OperandTypeInfoTraits<OperandTypeInfo::kNone>;
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     using TypeInfoTraits = OperandTypeInfoTraits<InfoType>;   \
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