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
10namespace v8 {
11namespace internal {
12namespace interpreter {
13
14template <OperandTypeInfo>
15struct 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  };
28OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
29#undef DECLARE_OPERAND_TYPE_INFO
30
31template <OperandType>
32struct 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  };
43OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
44#undef DECLARE_OPERAND_TYPE_TRAITS
45
46template <OperandType operand_type, OperandScale operand_scale>
47struct 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
68template <int... values>
69struct SumHelper;
70template <int value>
71struct SumHelper<value> {
72  static const int kValue = value;
73};
74template <int value, int... values>
75struct SumHelper<value, values...> {
76  static const int kValue = value + SumHelper<values...>::kValue;
77};
78
79template <AccumulatorUse accumulator_use, OperandType... operands>
80struct 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
96template <AccumulatorUse accumulator_use, OperandType... operands>
97STATIC_CONST_MEMBER_DEFINITION const OperandType
98    BytecodeTraits<accumulator_use, operands...>::kOperandTypes[] = {
99        operands...};
100template <AccumulatorUse accumulator_use, OperandType... operands>
101STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo
102    BytecodeTraits<accumulator_use, operands...>::kOperandTypeInfos[] = {
103        OperandTraits<operands>::kOperandTypeInfo...};
104template <AccumulatorUse accumulator_use, OperandType... operands>
105STATIC_CONST_MEMBER_DEFINITION const OperandSize
106    BytecodeTraits<accumulator_use, operands...>::kSingleScaleOperandSizes[] = {
107        OperandScaler<operands, OperandScale::kSingle>::kOperandSize...};
108template <AccumulatorUse accumulator_use, OperandType... operands>
109STATIC_CONST_MEMBER_DEFINITION const OperandSize
110    BytecodeTraits<accumulator_use, operands...>::kDoubleScaleOperandSizes[] = {
111        OperandScaler<operands, OperandScale::kDouble>::kOperandSize...};
112template <AccumulatorUse accumulator_use, OperandType... operands>
113STATIC_CONST_MEMBER_DEFINITION const OperandSize BytecodeTraits<
114    accumulator_use, operands...>::kQuadrupleScaleOperandSizes[] = {
115    OperandScaler<operands, OperandScale::kQuadruple>::kOperandSize...};
116
117template <AccumulatorUse accumulator_use>
118struct 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
131template <AccumulatorUse accumulator_use>
132STATIC_CONST_MEMBER_DEFINITION const OperandType
133    BytecodeTraits<accumulator_use>::kOperandTypes[] = {OperandType::kNone};
134template <AccumulatorUse accumulator_use>
135STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo
136    BytecodeTraits<accumulator_use>::kOperandTypeInfos[] = {
137        OperandTypeInfo::kNone};
138template <AccumulatorUse accumulator_use>
139STATIC_CONST_MEMBER_DEFINITION const OperandSize
140    BytecodeTraits<accumulator_use>::kSingleScaleOperandSizes[] = {
141        OperandSize::kNone};
142template <AccumulatorUse accumulator_use>
143STATIC_CONST_MEMBER_DEFINITION const OperandSize
144    BytecodeTraits<accumulator_use>::kDoubleScaleOperandSizes[] = {
145        OperandSize::kNone};
146template <AccumulatorUse accumulator_use>
147STATIC_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