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 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. ReadsAccumulator(AccumulatorUse accumulator_use)137 static constexpr bool ReadsAccumulator(AccumulatorUse accumulator_use) { 138 return accumulator_use == AccumulatorUse::kRead || 139 accumulator_use == AccumulatorUse::kReadWrite; 140 } 141 142 // Returns true if |accumulator_use| writes the accumulator. WritesAccumulator(AccumulatorUse accumulator_use)143 static constexpr bool WritesAccumulator(AccumulatorUse accumulator_use) { 144 return accumulator_use == AccumulatorUse::kWrite || 145 accumulator_use == AccumulatorUse::kReadWrite; 146 } 147 148 // Returns true if |operand_type| is a scalable signed byte. IsScalableSignedByte(OperandType operand_type)149 static constexpr bool IsScalableSignedByte(OperandType operand_type) { 150 return operand_type >= OperandType::kImm && 151 operand_type <= OperandType::kRegOutTriple; 152 } 153 154 // Returns true if |operand_type| is a scalable unsigned byte. IsScalableUnsignedByte(OperandType operand_type)155 static constexpr bool IsScalableUnsignedByte(OperandType operand_type) { 156 return operand_type >= OperandType::kIdx && 157 operand_type <= OperandType::kRegCount; 158 } 159 }; 160 161 } // namespace interpreter 162 } // namespace internal 163 } // namespace v8 164 165 #endif // V8_INTERPRETER_BYTECODE_OPERANDS_H_ 166