Line data Source code
1 : // Copyright 2016 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_OPERANDS_H_
6 : #define V8_INTERPRETER_BYTECODE_OPERANDS_H_
7 :
8 : #include "src/globals.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 : namespace interpreter {
13 :
14 : #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
15 :
16 : #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
17 : V(Reg, OperandTypeInfo::kScalableSignedByte) \
18 : V(RegList, OperandTypeInfo::kScalableSignedByte) \
19 : V(RegPair, OperandTypeInfo::kScalableSignedByte)
20 :
21 : #define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \
22 : V(RegOut, OperandTypeInfo::kScalableSignedByte) \
23 : V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
24 : V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
25 :
26 : #define SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
27 : V(Imm, OperandTypeInfo::kScalableSignedByte)
28 :
29 : #define UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
30 : V(Idx, OperandTypeInfo::kScalableUnsignedByte) \
31 : V(UImm, OperandTypeInfo::kScalableUnsignedByte) \
32 : V(RegCount, OperandTypeInfo::kScalableUnsignedByte)
33 :
34 : #define UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V) \
35 : V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \
36 : V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
37 : V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
38 :
39 : // Carefully ordered for operand type range checks below.
40 : #define NON_REGISTER_OPERAND_TYPE_LIST(V) \
41 : INVALID_OPERAND_TYPE_LIST(V) \
42 : UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V) \
43 : UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
44 : SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V)
45 :
46 : // Carefully ordered for operand type range checks below.
47 : #define REGISTER_OPERAND_TYPE_LIST(V) \
48 : REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
49 : REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
50 :
51 : // The list of operand types used by bytecodes.
52 : // Carefully ordered for operand type range checks below.
53 : #define OPERAND_TYPE_LIST(V) \
54 : NON_REGISTER_OPERAND_TYPE_LIST(V) \
55 : REGISTER_OPERAND_TYPE_LIST(V)
56 :
57 : // Enumeration of scaling factors applicable to scalable operands. Code
58 : // relies on being able to cast values to integer scaling values.
59 : #define OPERAND_SCALE_LIST(V) \
60 : V(Single, 1) \
61 : V(Double, 2) \
62 : V(Quadruple, 4)
63 :
64 : enum class OperandScale : uint8_t {
65 : #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
66 : OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
67 : #undef DECLARE_OPERAND_SCALE
68 : kLast = kQuadruple
69 : };
70 :
71 : // Enumeration of the size classes of operand types used by
72 : // bytecodes. Code relies on being able to cast values to integer
73 : // types to get the size in bytes.
74 : enum class OperandSize : uint8_t {
75 : kNone = 0,
76 : kByte = 1,
77 : kShort = 2,
78 : kQuad = 4,
79 : kLast = kQuad
80 : };
81 :
82 : // Primitive operand info used that summarize properties of operands.
83 : // Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
84 : #define OPERAND_TYPE_INFO_LIST(V) \
85 : V(None, false, false, OperandSize::kNone) \
86 : V(ScalableSignedByte, true, false, OperandSize::kByte) \
87 : V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
88 : V(FixedUnsignedByte, false, true, OperandSize::kByte) \
89 : V(FixedUnsignedShort, false, true, OperandSize::kShort)
90 :
91 : enum class OperandTypeInfo : uint8_t {
92 : #define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
93 : OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
94 : #undef DECLARE_OPERAND_TYPE_INFO
95 : };
96 :
97 : // Enumeration of operand types used by bytecodes.
98 : enum class OperandType : uint8_t {
99 : #define DECLARE_OPERAND_TYPE(Name, _) k##Name,
100 : OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
101 : #undef DECLARE_OPERAND_TYPE
102 : #define COUNT_OPERAND_TYPES(x, _) +1
103 : // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
104 : // evaluate to the same value as the last operand.
105 : kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
106 : #undef COUNT_OPERAND_TYPES
107 : };
108 :
109 : enum class AccumulatorUse : uint8_t {
110 : kNone = 0,
111 : kRead = 1 << 0,
112 : kWrite = 1 << 1,
113 : kReadWrite = kRead | kWrite
114 : };
115 :
116 : inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
117 : int result = static_cast<int>(lhs) & static_cast<int>(rhs);
118 : return static_cast<AccumulatorUse>(result);
119 : }
120 :
121 : inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
122 30097 : int result = static_cast<int>(lhs) | static_cast<int>(rhs);
123 : return static_cast<AccumulatorUse>(result);
124 : }
125 :
126 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
127 : const AccumulatorUse& use);
128 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
129 : const OperandScale& operand_scale);
130 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
131 : const OperandSize& operand_size);
132 : std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
133 :
134 : class BytecodeOperands {
135 : public:
136 : // Returns true if |accumulator_use| reads the accumulator.
137 47544533 : static constexpr bool ReadsAccumulator(AccumulatorUse accumulator_use) {
138 63980538 : return accumulator_use == AccumulatorUse::kRead ||
139 63980538 : accumulator_use == AccumulatorUse::kReadWrite;
140 : }
141 :
142 : // Returns true if |accumulator_use| writes the accumulator.
143 47544513 : static constexpr bool WritesAccumulator(AccumulatorUse accumulator_use) {
144 63980543 : return accumulator_use == AccumulatorUse::kWrite ||
145 47544513 : accumulator_use == AccumulatorUse::kReadWrite;
146 : }
147 :
148 : // Returns true if |operand_type| is a scalable signed byte.
149 57263791 : static constexpr bool IsScalableSignedByte(OperandType operand_type) {
150 57263791 : return operand_type >= OperandType::kImm &&
151 57263791 : operand_type <= OperandType::kRegOutTriple;
152 : }
153 :
154 : // Returns true if |operand_type| is a scalable unsigned byte.
155 86985358 : static constexpr bool IsScalableUnsignedByte(OperandType operand_type) {
156 86985358 : return operand_type >= OperandType::kIdx &&
157 86985358 : operand_type <= OperandType::kRegCount;
158 : }
159 : };
160 :
161 : } // namespace interpreter
162 : } // namespace internal
163 : } // namespace v8
164 :
165 : #endif // V8_INTERPRETER_BYTECODE_OPERANDS_H_
|