V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
bytecode-operands.h
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(RegOutList, OperandTypeInfo::kScalableSignedByte) \
24  V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
25  V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
26 
27 #define SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
28  V(Imm, OperandTypeInfo::kScalableSignedByte)
29 
30 #define UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
31  V(Idx, OperandTypeInfo::kScalableUnsignedByte) \
32  V(UImm, OperandTypeInfo::kScalableUnsignedByte) \
33  V(RegCount, OperandTypeInfo::kScalableUnsignedByte)
34 
35 #define UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V) \
36  V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \
37  V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
38  V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort) \
39  V(NativeContextIndex, OperandTypeInfo::kScalableUnsignedByte)
40 
41 // Carefully ordered for operand type range checks below.
42 #define NON_REGISTER_OPERAND_TYPE_LIST(V) \
43  INVALID_OPERAND_TYPE_LIST(V) \
44  UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V) \
45  UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
46  SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V)
47 
48 // Carefully ordered for operand type range checks below.
49 #define REGISTER_OPERAND_TYPE_LIST(V) \
50  REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
51  REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
52 
53 // The list of operand types used by bytecodes.
54 // Carefully ordered for operand type range checks below.
55 #define OPERAND_TYPE_LIST(V) \
56  NON_REGISTER_OPERAND_TYPE_LIST(V) \
57  REGISTER_OPERAND_TYPE_LIST(V)
58 
59 // Enumeration of scaling factors applicable to scalable operands. Code
60 // relies on being able to cast values to integer scaling values.
61 #define OPERAND_SCALE_LIST(V) \
62  V(Single, 1) \
63  V(Double, 2) \
64  V(Quadruple, 4)
65 
66 enum class OperandScale : uint8_t {
67 #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
68  OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
69 #undef DECLARE_OPERAND_SCALE
70  kLast = kQuadruple
71 };
72 
73 // Enumeration of the size classes of operand types used by
74 // bytecodes. Code relies on being able to cast values to integer
75 // types to get the size in bytes.
76 enum class OperandSize : uint8_t {
77  kNone = 0,
78  kByte = 1,
79  kShort = 2,
80  kQuad = 4,
81  kLast = kQuad
82 };
83 
84 // Primitive operand info used that summarize properties of operands.
85 // Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
86 #define OPERAND_TYPE_INFO_LIST(V) \
87  V(None, false, false, OperandSize::kNone) \
88  V(ScalableSignedByte, true, false, OperandSize::kByte) \
89  V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
90  V(FixedUnsignedByte, false, true, OperandSize::kByte) \
91  V(FixedUnsignedShort, false, true, OperandSize::kShort)
92 
93 enum class OperandTypeInfo : uint8_t {
94 #define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
95  OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
96 #undef DECLARE_OPERAND_TYPE_INFO
97 };
98 
99 // Enumeration of operand types used by bytecodes.
100 enum class OperandType : uint8_t {
101 #define DECLARE_OPERAND_TYPE(Name, _) k##Name,
102  OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
103 #undef DECLARE_OPERAND_TYPE
104 #define COUNT_OPERAND_TYPES(x, _) +1
105  // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
106  // evaluate to the same value as the last operand.
107  kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
108 #undef COUNT_OPERAND_TYPES
109 };
110 
111 enum class AccumulatorUse : uint8_t {
112  kNone = 0,
113  kRead = 1 << 0,
114  kWrite = 1 << 1,
115  kReadWrite = kRead | kWrite
116 };
117 
118 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
119  int result = static_cast<int>(lhs) & static_cast<int>(rhs);
120  return static_cast<AccumulatorUse>(result);
121 }
122 
123 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
124  int result = static_cast<int>(lhs) | static_cast<int>(rhs);
125  return static_cast<AccumulatorUse>(result);
126 }
127 
128 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
129  const AccumulatorUse& use);
130 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
131  const OperandScale& operand_scale);
132 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
133  const OperandSize& operand_size);
134 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
135  const OperandType& operand_type);
136 
137 class BytecodeOperands : public AllStatic {
138  public:
139  // The total number of bytecode operand types used.
140  static const int kOperandTypeCount = static_cast<int>(OperandType::kLast) + 1;
141 
142 // The total number of bytecode operand scales used.
143 #define OPERAND_SCALE_COUNT(...) +1
144  static const int kOperandScaleCount =
145  0 OPERAND_SCALE_LIST(OPERAND_SCALE_COUNT);
146 #undef OPERAND_SCALE_COUNT
147 
148  static int OperandScaleAsIndex(OperandScale operand_scale) {
149  switch (operand_scale) {
150  case OperandScale::kSingle:
151  return 0;
152  case OperandScale::kDouble:
153  return 1;
154  case OperandScale::kQuadruple:
155  return 2;
156  default:
157  UNREACHABLE();
158  }
159  }
160 
161  // Returns true if |accumulator_use| reads the accumulator.
162  static constexpr bool ReadsAccumulator(AccumulatorUse accumulator_use) {
163  return accumulator_use == AccumulatorUse::kRead ||
164  accumulator_use == AccumulatorUse::kReadWrite;
165  }
166 
167  // Returns true if |accumulator_use| writes the accumulator.
168  static constexpr bool WritesAccumulator(AccumulatorUse accumulator_use) {
169  return accumulator_use == AccumulatorUse::kWrite ||
170  accumulator_use == AccumulatorUse::kReadWrite;
171  }
172 
173  // Returns true if |operand_type| is a scalable signed byte.
174  static constexpr bool IsScalableSignedByte(OperandType operand_type) {
175  return operand_type >= OperandType::kImm &&
176  operand_type <= OperandType::kRegOutTriple;
177  }
178 
179  // Returns true if |operand_type| is a scalable unsigned byte.
180  static constexpr bool IsScalableUnsignedByte(OperandType operand_type) {
181  return operand_type >= OperandType::kIdx &&
182  operand_type <= OperandType::kRegCount;
183  }
184 };
185 
186 } // namespace interpreter
187 } // namespace internal
188 } // namespace v8
189 
190 #endif // V8_INTERPRETER_BYTECODE_OPERANDS_H_
Definition: libplatform.h:13