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
10namespace v8 {
11namespace internal {
12namespace 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
58enum 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.
68enum 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
85enum 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.
92enum 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
103enum class AccumulatorUse : uint8_t {
104  kNone = 0,
105  kRead = 1 << 0,
106  kWrite = 1 << 1,
107  kReadWrite = kRead | kWrite
108};
109
110inline 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
115inline 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
120V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
121                                           const AccumulatorUse& use);
122V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
123                                           const OperandScale& operand_scale);
124V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
125                                           const OperandSize& operand_size);
126std::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