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