blob: c724827356a3d020384386e7b875545c29f9b569 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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/bytecodes.h"
9
10namespace v8 {
11namespace internal {
12namespace interpreter {
13
Ben Murdochda12d292016-06-02 14:46:10 +010014template <OperandTypeInfo>
15struct OperandTypeInfoTraits {
16 static const bool kIsScalable = false;
17 static const bool kIsUnsigned = false;
18 static const OperandSize kUnscaledSize = OperandSize::kNone;
19};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020
Ben Murdochda12d292016-06-02 14:46:10 +010021#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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030
31template <OperandType>
Ben Murdochda12d292016-06-02 14:46:10 +010032struct OperandTraits {
33 typedef OperandTypeInfoTraits<OperandTypeInfo::kNone> TypeInfo;
34};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035
Ben Murdochda12d292016-06-02 14:46:10 +010036#define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \
37 template <> \
38 struct OperandTraits<OperandType::k##Name> { \
39 typedef OperandTypeInfoTraits<InfoType> TypeInfo; \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 };
Ben Murdochda12d292016-06-02 14:46:10 +010041OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
42#undef DECLARE_OPERAND_TYPE_TRAITS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043
Ben Murdoch097c5b22016-05-18 11:27:45 +010044template <OperandType>
45struct RegisterOperandTraits {
46 static const int kIsRegisterOperand = 0;
47};
48
49#define DECLARE_REGISTER_OPERAND(Name, _) \
50 template <> \
51 struct RegisterOperandTraits<OperandType::k##Name> { \
52 static const int kIsRegisterOperand = 1; \
53 };
54REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND)
55#undef DECLARE_REGISTER_OPERAND
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056
Ben Murdochda12d292016-06-02 14:46:10 +010057template <AccumulatorUse, OperandType...>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058struct BytecodeTraits {};
59
Ben Murdochda12d292016-06-02 14:46:10 +010060template <AccumulatorUse accumulator_use, OperandType operand_0,
61 OperandType operand_1, OperandType operand_2, OperandType operand_3>
62struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2,
63 operand_3> {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 static OperandType GetOperandType(int i) {
65 DCHECK(0 <= i && i < kOperandCount);
66 const OperandType kOperands[] = {operand_0, operand_1, operand_2,
67 operand_3};
68 return kOperands[i];
69 }
70
Ben Murdoch097c5b22016-05-18 11:27:45 +010071 template <OperandType ot>
72 static inline bool HasAnyOperandsOfType() {
73 return operand_0 == ot || operand_1 == ot || operand_2 == ot ||
74 operand_3 == ot;
75 }
76
Ben Murdochda12d292016-06-02 14:46:10 +010077 static inline bool IsScalable() {
78 return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
79 OperandTraits<operand_1>::TypeInfo::kIsScalable |
80 OperandTraits<operand_2>::TypeInfo::kIsScalable |
81 OperandTraits<operand_3>::TypeInfo::kIsScalable);
82 }
83
84 static const AccumulatorUse kAccumulatorUse = accumulator_use;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 static const int kOperandCount = 4;
Ben Murdoch097c5b22016-05-18 11:27:45 +010086 static const int kRegisterOperandCount =
87 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
88 RegisterOperandTraits<operand_1>::kIsRegisterOperand +
89 RegisterOperandTraits<operand_2>::kIsRegisterOperand +
90 RegisterOperandTraits<operand_3>::kIsRegisterOperand;
91 static const int kRegisterOperandBitmap =
92 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
93 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) +
94 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2) +
95 (RegisterOperandTraits<operand_3>::kIsRegisterOperand << 3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000096};
97
Ben Murdochda12d292016-06-02 14:46:10 +010098template <AccumulatorUse accumulator_use, OperandType operand_0,
99 OperandType operand_1, OperandType operand_2>
100struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 static inline OperandType GetOperandType(int i) {
102 DCHECK(0 <= i && i <= 2);
103 const OperandType kOperands[] = {operand_0, operand_1, operand_2};
104 return kOperands[i];
105 }
106
Ben Murdoch097c5b22016-05-18 11:27:45 +0100107 template <OperandType ot>
108 static inline bool HasAnyOperandsOfType() {
109 return operand_0 == ot || operand_1 == ot || operand_2 == ot;
110 }
111
Ben Murdochda12d292016-06-02 14:46:10 +0100112 static inline bool IsScalable() {
113 return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
114 OperandTraits<operand_1>::TypeInfo::kIsScalable |
115 OperandTraits<operand_2>::TypeInfo::kIsScalable);
116 }
117
118 static const AccumulatorUse kAccumulatorUse = accumulator_use;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 static const int kOperandCount = 3;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100120 static const int kRegisterOperandCount =
121 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
122 RegisterOperandTraits<operand_1>::kIsRegisterOperand +
123 RegisterOperandTraits<operand_2>::kIsRegisterOperand;
124 static const int kRegisterOperandBitmap =
125 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
126 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) +
127 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128};
129
Ben Murdochda12d292016-06-02 14:46:10 +0100130template <AccumulatorUse accumulator_use, OperandType operand_0,
131 OperandType operand_1>
132struct BytecodeTraits<accumulator_use, operand_0, operand_1> {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133 static inline OperandType GetOperandType(int i) {
134 DCHECK(0 <= i && i < kOperandCount);
135 const OperandType kOperands[] = {operand_0, operand_1};
136 return kOperands[i];
137 }
138
Ben Murdoch097c5b22016-05-18 11:27:45 +0100139 template <OperandType ot>
140 static inline bool HasAnyOperandsOfType() {
141 return operand_0 == ot || operand_1 == ot;
142 }
143
Ben Murdochda12d292016-06-02 14:46:10 +0100144 static inline bool IsScalable() {
145 return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
146 OperandTraits<operand_1>::TypeInfo::kIsScalable);
147 }
148
149 static const AccumulatorUse kAccumulatorUse = accumulator_use;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150 static const int kOperandCount = 2;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100151 static const int kRegisterOperandCount =
152 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
153 RegisterOperandTraits<operand_1>::kIsRegisterOperand;
154 static const int kRegisterOperandBitmap =
155 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
156 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157};
158
Ben Murdochda12d292016-06-02 14:46:10 +0100159template <AccumulatorUse accumulator_use, OperandType operand_0>
160struct BytecodeTraits<accumulator_use, operand_0> {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161 static inline OperandType GetOperandType(int i) {
162 DCHECK(i == 0);
163 return operand_0;
164 }
165
Ben Murdoch097c5b22016-05-18 11:27:45 +0100166 template <OperandType ot>
167 static inline bool HasAnyOperandsOfType() {
168 return operand_0 == ot;
169 }
170
Ben Murdochda12d292016-06-02 14:46:10 +0100171 static inline bool IsScalable() {
172 return OperandTraits<operand_0>::TypeInfo::kIsScalable;
173 }
174
175 static const AccumulatorUse kAccumulatorUse = accumulator_use;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 static const int kOperandCount = 1;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100177 static const int kRegisterOperandCount =
178 RegisterOperandTraits<operand_0>::kIsRegisterOperand;
179 static const int kRegisterOperandBitmap =
180 RegisterOperandTraits<operand_0>::kIsRegisterOperand;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181};
182
Ben Murdochda12d292016-06-02 14:46:10 +0100183template <AccumulatorUse accumulator_use>
184struct BytecodeTraits<accumulator_use> {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000185 static inline OperandType GetOperandType(int i) {
186 UNREACHABLE();
187 return OperandType::kNone;
188 }
189
Ben Murdoch097c5b22016-05-18 11:27:45 +0100190 template <OperandType ot>
191 static inline bool HasAnyOperandsOfType() {
192 return false;
193 }
194
Ben Murdochda12d292016-06-02 14:46:10 +0100195 static inline bool IsScalable() { return false; }
196
197 static const AccumulatorUse kAccumulatorUse = accumulator_use;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198 static const int kOperandCount = 0;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100199 static const int kRegisterOperandCount = 0;
200 static const int kRegisterOperandBitmap = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201};
202
Ben Murdochda12d292016-06-02 14:46:10 +0100203template <bool>
204struct OperandScaler {
205 static int Multiply(int size, int operand_scale) { return 0; }
206};
207
208template <>
209struct OperandScaler<false> {
210 static int Multiply(int size, int operand_scale) { return size; }
211};
212
213template <>
214struct OperandScaler<true> {
215 static int Multiply(int size, int operand_scale) {
216 return size * operand_scale;
217 }
218};
219
220static OperandSize ScaledOperandSize(OperandType operand_type,
221 OperandScale operand_scale) {
222 switch (operand_type) {
223#define CASE(Name, TypeInfo) \
224 case OperandType::k##Name: { \
225 OperandSize base_size = OperandTypeInfoTraits<TypeInfo>::kUnscaledSize; \
226 int size = \
227 OperandScaler<OperandTypeInfoTraits<TypeInfo>::kIsScalable>::Multiply( \
228 static_cast<int>(base_size), static_cast<int>(operand_scale)); \
229 OperandSize operand_size = static_cast<OperandSize>(size); \
230 DCHECK(operand_size == OperandSize::kByte || \
231 operand_size == OperandSize::kShort || \
232 operand_size == OperandSize::kQuad); \
233 return operand_size; \
234 }
235 OPERAND_TYPE_LIST(CASE)
236#undef CASE
237 }
238 UNREACHABLE();
239 return OperandSize::kNone;
240}
241
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242} // namespace interpreter
243} // namespace internal
244} // namespace v8
245
246#endif // V8_INTERPRETER_BYTECODE_TRAITS_H_