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 UNSIGNED_SCALAR_OPERAND_TYPE_LIST(V)          \
27   V(Flag8, OperandTypeInfo::kFixedUnsignedByte)       \
28   V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
29   V(Idx, OperandTypeInfo::kScalableUnsignedByte)      \
30   V(UImm, OperandTypeInfo::kScalableUnsignedByte)     \
31   V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \
32   V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
33 
34 #define SIGNED_SCALAR_OPERAND_TYPE_LIST(V) \
35   V(Imm, OperandTypeInfo::kScalableSignedByte)
36 
37 #define REGISTER_OPERAND_TYPE_LIST(V) \
38   REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
39   REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
40 
41 #define NON_REGISTER_OPERAND_TYPE_LIST(V) \
42   INVALID_OPERAND_TYPE_LIST(V)            \
43   UNSIGNED_SCALAR_OPERAND_TYPE_LIST(V)    \
44   SIGNED_SCALAR_OPERAND_TYPE_LIST(V)
45 
46 // The list of operand types used by bytecodes.
47 #define OPERAND_TYPE_LIST(V)        \
48   NON_REGISTER_OPERAND_TYPE_LIST(V) \
49   REGISTER_OPERAND_TYPE_LIST(V)
50 
51 // Enumeration of scaling factors applicable to scalable operands. Code
52 // relies on being able to cast values to integer scaling values.
53 #define OPERAND_SCALE_LIST(V) \
54   V(Single, 1)                \
55   V(Double, 2)                \
56   V(Quadruple, 4)
57 
58 enum class OperandScale : uint8_t {
59 #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
60   OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
61 #undef DECLARE_OPERAND_SCALE
62       kLast = kQuadruple
63 };
64 
65 // Enumeration of the size classes of operand types used by
66 // bytecodes. Code relies on being able to cast values to integer
67 // types to get the size in bytes.
68 enum class OperandSize : uint8_t {
69   kNone = 0,
70   kByte = 1,
71   kShort = 2,
72   kQuad = 4,
73   kLast = kQuad
74 };
75 
76 // Primitive operand info used that summarize properties of operands.
77 // Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
78 #define OPERAND_TYPE_INFO_LIST(V)                         \
79   V(None, false, false, OperandSize::kNone)               \
80   V(ScalableSignedByte, true, false, OperandSize::kByte)  \
81   V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
82   V(FixedUnsignedByte, false, true, OperandSize::kByte)   \
83   V(FixedUnsignedShort, false, true, OperandSize::kShort)
84 
85 enum class OperandTypeInfo : uint8_t {
86 #define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
87   OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
88 #undef DECLARE_OPERAND_TYPE_INFO
89 };
90 
91 // Enumeration of operand types used by bytecodes.
92 enum class OperandType : uint8_t {
93 #define DECLARE_OPERAND_TYPE(Name, _) k##Name,
94   OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
95 #undef DECLARE_OPERAND_TYPE
96 #define COUNT_OPERAND_TYPES(x, _) +1
97   // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
98   // evaluate to the same value as the last operand.
99   kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
100 #undef COUNT_OPERAND_TYPES
101 };
102 
103 enum class AccumulatorUse : uint8_t {
104   kNone = 0,
105   kRead = 1 << 0,
106   kWrite = 1 << 1,
107   kReadWrite = kRead | kWrite
108 };
109 
110 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
111   int result = static_cast<int>(lhs) & static_cast<int>(rhs);
112   return static_cast<AccumulatorUse>(result);
113 }
114 
115 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
116   int result = static_cast<int>(lhs) | static_cast<int>(rhs);
117   return static_cast<AccumulatorUse>(result);
118 }
119 
120 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
121                                            const AccumulatorUse& use);
122 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
123                                            const OperandScale& operand_scale);
124 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
125                                            const OperandSize& operand_size);
126 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
127 
128 }  // namespace interpreter
129 }  // namespace internal
130 }  // namespace v8
131 
132 #endif  // V8_INTERPRETER_BYTECODE_OPERANDS_H_
133