11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BYTECODE_OPERANDS_H_
61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_OPERANDS_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/bounds.h"
91cb0ef41Sopenharmony_ci#include "src/common/globals.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cinamespace v8 {
121cb0ef41Sopenharmony_cinamespace internal {
131cb0ef41Sopenharmony_cinamespace interpreter {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci#define REGISTER_INPUT_OPERAND_TYPE_LIST(V)        \
181cb0ef41Sopenharmony_ci  V(Reg, OperandTypeInfo::kScalableSignedByte)     \
191cb0ef41Sopenharmony_ci  V(RegList, OperandTypeInfo::kScalableSignedByte) \
201cb0ef41Sopenharmony_ci  V(RegPair, OperandTypeInfo::kScalableSignedByte)
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)          \
231cb0ef41Sopenharmony_ci  V(RegOut, OperandTypeInfo::kScalableSignedByte)     \
241cb0ef41Sopenharmony_ci  V(RegOutList, OperandTypeInfo::kScalableSignedByte) \
251cb0ef41Sopenharmony_ci  V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
261cb0ef41Sopenharmony_ci  V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci#define SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
291cb0ef41Sopenharmony_ci  V(Imm, OperandTypeInfo::kScalableSignedByte)
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci#define UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
321cb0ef41Sopenharmony_ci  V(Idx, OperandTypeInfo::kScalableUnsignedByte)      \
331cb0ef41Sopenharmony_ci  V(UImm, OperandTypeInfo::kScalableUnsignedByte)     \
341cb0ef41Sopenharmony_ci  V(RegCount, OperandTypeInfo::kScalableUnsignedByte)
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci#define UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V)    \
371cb0ef41Sopenharmony_ci  V(Flag8, OperandTypeInfo::kFixedUnsignedByte)       \
381cb0ef41Sopenharmony_ci  V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
391cb0ef41Sopenharmony_ci  V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)  \
401cb0ef41Sopenharmony_ci  V(NativeContextIndex, OperandTypeInfo::kFixedUnsignedByte)
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci// Carefully ordered for operand type range checks below.
431cb0ef41Sopenharmony_ci#define NON_REGISTER_OPERAND_TYPE_LIST(V)       \
441cb0ef41Sopenharmony_ci  INVALID_OPERAND_TYPE_LIST(V)                  \
451cb0ef41Sopenharmony_ci  UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V)    \
461cb0ef41Sopenharmony_ci  UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \
471cb0ef41Sopenharmony_ci  SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V)
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci// Carefully ordered for operand type range checks below.
501cb0ef41Sopenharmony_ci#define REGISTER_OPERAND_TYPE_LIST(V) \
511cb0ef41Sopenharmony_ci  REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
521cb0ef41Sopenharmony_ci  REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci// The list of operand types used by bytecodes.
551cb0ef41Sopenharmony_ci// Carefully ordered for operand type range checks below.
561cb0ef41Sopenharmony_ci#define OPERAND_TYPE_LIST(V)        \
571cb0ef41Sopenharmony_ci  NON_REGISTER_OPERAND_TYPE_LIST(V) \
581cb0ef41Sopenharmony_ci  REGISTER_OPERAND_TYPE_LIST(V)
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci// Enumeration of scaling factors applicable to scalable operands. Code
611cb0ef41Sopenharmony_ci// relies on being able to cast values to integer scaling values.
621cb0ef41Sopenharmony_ci#define OPERAND_SCALE_LIST(V) \
631cb0ef41Sopenharmony_ci  V(Single, 1)                \
641cb0ef41Sopenharmony_ci  V(Double, 2)                \
651cb0ef41Sopenharmony_ci  V(Quadruple, 4)
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_cienum class OperandScale : uint8_t {
681cb0ef41Sopenharmony_ci#define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
691cb0ef41Sopenharmony_ci  OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
701cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_SCALE
711cb0ef41Sopenharmony_ci      kLast = kQuadruple
721cb0ef41Sopenharmony_ci};
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci// Enumeration of the size classes of operand types used by
751cb0ef41Sopenharmony_ci// bytecodes. Code relies on being able to cast values to integer
761cb0ef41Sopenharmony_ci// types to get the size in bytes.
771cb0ef41Sopenharmony_cienum class OperandSize : uint8_t {
781cb0ef41Sopenharmony_ci  kNone = 0,
791cb0ef41Sopenharmony_ci  kByte = 1,
801cb0ef41Sopenharmony_ci  kShort = 2,
811cb0ef41Sopenharmony_ci  kQuad = 4,
821cb0ef41Sopenharmony_ci  kLast = kQuad
831cb0ef41Sopenharmony_ci};
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci// Primitive operand info used that summarize properties of operands.
861cb0ef41Sopenharmony_ci// Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
871cb0ef41Sopenharmony_ci#define OPERAND_TYPE_INFO_LIST(V)                         \
881cb0ef41Sopenharmony_ci  V(None, false, false, OperandSize::kNone)               \
891cb0ef41Sopenharmony_ci  V(ScalableSignedByte, true, false, OperandSize::kByte)  \
901cb0ef41Sopenharmony_ci  V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
911cb0ef41Sopenharmony_ci  V(FixedUnsignedByte, false, true, OperandSize::kByte)   \
921cb0ef41Sopenharmony_ci  V(FixedUnsignedShort, false, true, OperandSize::kShort)
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_cienum class OperandTypeInfo : uint8_t {
951cb0ef41Sopenharmony_ci#define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
961cb0ef41Sopenharmony_ci  OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
971cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_TYPE_INFO
981cb0ef41Sopenharmony_ci};
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci// Enumeration of operand types used by bytecodes.
1011cb0ef41Sopenharmony_cienum class OperandType : uint8_t {
1021cb0ef41Sopenharmony_ci#define DECLARE_OPERAND_TYPE(Name, _) k##Name,
1031cb0ef41Sopenharmony_ci  OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
1041cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_TYPE
1051cb0ef41Sopenharmony_ci#define COUNT_OPERAND_TYPES(x, _) +1
1061cb0ef41Sopenharmony_ci  // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
1071cb0ef41Sopenharmony_ci  // evaluate to the same value as the last operand.
1081cb0ef41Sopenharmony_ci  kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
1091cb0ef41Sopenharmony_ci#undef COUNT_OPERAND_TYPES
1101cb0ef41Sopenharmony_ci};
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_cienum class ImplicitRegisterUse : uint8_t {
1131cb0ef41Sopenharmony_ci  kNone = 0,
1141cb0ef41Sopenharmony_ci  kReadAccumulator = 1 << 0,
1151cb0ef41Sopenharmony_ci  kWriteAccumulator = 1 << 1,
1161cb0ef41Sopenharmony_ci  kWriteShortStar = 1 << 2,
1171cb0ef41Sopenharmony_ci  kReadWriteAccumulator = kReadAccumulator | kWriteAccumulator,
1181cb0ef41Sopenharmony_ci  kReadAccumulatorWriteShortStar = kReadAccumulator | kWriteShortStar
1191cb0ef41Sopenharmony_ci};
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ciconstexpr inline ImplicitRegisterUse operator&(ImplicitRegisterUse lhs,
1221cb0ef41Sopenharmony_ci                                               ImplicitRegisterUse rhs) {
1231cb0ef41Sopenharmony_ci  return static_cast<ImplicitRegisterUse>(static_cast<int>(lhs) &
1241cb0ef41Sopenharmony_ci                                          static_cast<int>(rhs));
1251cb0ef41Sopenharmony_ci}
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciconstexpr inline ImplicitRegisterUse operator|(ImplicitRegisterUse lhs,
1281cb0ef41Sopenharmony_ci                                               ImplicitRegisterUse rhs) {
1291cb0ef41Sopenharmony_ci  return static_cast<ImplicitRegisterUse>(static_cast<int>(lhs) |
1301cb0ef41Sopenharmony_ci                                          static_cast<int>(rhs));
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
1341cb0ef41Sopenharmony_ci                                           const ImplicitRegisterUse& use);
1351cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
1361cb0ef41Sopenharmony_ci                                           const OperandScale& operand_scale);
1371cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
1381cb0ef41Sopenharmony_ci                                           const OperandSize& operand_size);
1391cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
1401cb0ef41Sopenharmony_ci                                           const OperandType& operand_type);
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ciclass BytecodeOperands : public AllStatic {
1431cb0ef41Sopenharmony_ci public:
1441cb0ef41Sopenharmony_ci  // The total number of bytecode operand types used.
1451cb0ef41Sopenharmony_ci  static const int kOperandTypeCount = static_cast<int>(OperandType::kLast) + 1;
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci// The total number of bytecode operand scales used.
1481cb0ef41Sopenharmony_ci#define OPERAND_SCALE_COUNT(...) +1
1491cb0ef41Sopenharmony_ci  static const int kOperandScaleCount =
1501cb0ef41Sopenharmony_ci      0 OPERAND_SCALE_LIST(OPERAND_SCALE_COUNT);
1511cb0ef41Sopenharmony_ci#undef OPERAND_SCALE_COUNT
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  static constexpr int OperandScaleAsIndex(OperandScale operand_scale) {
1541cb0ef41Sopenharmony_ci#ifdef DEBUG
1551cb0ef41Sopenharmony_ci    int result = static_cast<int>(operand_scale) >> 1;
1561cb0ef41Sopenharmony_ci    switch (operand_scale) {
1571cb0ef41Sopenharmony_ci      case OperandScale::kSingle:
1581cb0ef41Sopenharmony_ci        DCHECK_EQ(0, result);
1591cb0ef41Sopenharmony_ci        break;
1601cb0ef41Sopenharmony_ci      case OperandScale::kDouble:
1611cb0ef41Sopenharmony_ci        DCHECK_EQ(1, result);
1621cb0ef41Sopenharmony_ci        break;
1631cb0ef41Sopenharmony_ci      case OperandScale::kQuadruple:
1641cb0ef41Sopenharmony_ci        DCHECK_EQ(2, result);
1651cb0ef41Sopenharmony_ci        break;
1661cb0ef41Sopenharmony_ci      default:
1671cb0ef41Sopenharmony_ci        UNREACHABLE();
1681cb0ef41Sopenharmony_ci    }
1691cb0ef41Sopenharmony_ci#endif
1701cb0ef41Sopenharmony_ci    return static_cast<int>(operand_scale) >> 1;
1711cb0ef41Sopenharmony_ci  }
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  // Returns true if |implicit_register_use| reads the
1741cb0ef41Sopenharmony_ci  // accumulator.
1751cb0ef41Sopenharmony_ci  static constexpr bool ReadsAccumulator(
1761cb0ef41Sopenharmony_ci      ImplicitRegisterUse implicit_register_use) {
1771cb0ef41Sopenharmony_ci    return (implicit_register_use & ImplicitRegisterUse::kReadAccumulator) ==
1781cb0ef41Sopenharmony_ci           ImplicitRegisterUse::kReadAccumulator;
1791cb0ef41Sopenharmony_ci  }
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  // Returns true if |implicit_register_use| writes the
1821cb0ef41Sopenharmony_ci  // accumulator.
1831cb0ef41Sopenharmony_ci  static constexpr bool WritesAccumulator(
1841cb0ef41Sopenharmony_ci      ImplicitRegisterUse implicit_register_use) {
1851cb0ef41Sopenharmony_ci    return (implicit_register_use & ImplicitRegisterUse::kWriteAccumulator) ==
1861cb0ef41Sopenharmony_ci           ImplicitRegisterUse::kWriteAccumulator;
1871cb0ef41Sopenharmony_ci  }
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci  // Returns true if |implicit_register_use| writes to a
1901cb0ef41Sopenharmony_ci  // register not specified by an operand.
1911cb0ef41Sopenharmony_ci  static constexpr bool WritesImplicitRegister(
1921cb0ef41Sopenharmony_ci      ImplicitRegisterUse implicit_register_use) {
1931cb0ef41Sopenharmony_ci    return (implicit_register_use & ImplicitRegisterUse::kWriteShortStar) ==
1941cb0ef41Sopenharmony_ci           ImplicitRegisterUse::kWriteShortStar;
1951cb0ef41Sopenharmony_ci  }
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  // Returns true if |operand_type| is a scalable signed byte.
1981cb0ef41Sopenharmony_ci  static constexpr bool IsScalableSignedByte(OperandType operand_type) {
1991cb0ef41Sopenharmony_ci    return base::IsInRange(operand_type, OperandType::kImm,
2001cb0ef41Sopenharmony_ci                           OperandType::kRegOutTriple);
2011cb0ef41Sopenharmony_ci  }
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  // Returns true if |operand_type| is a scalable unsigned byte.
2041cb0ef41Sopenharmony_ci  static constexpr bool IsScalableUnsignedByte(OperandType operand_type) {
2051cb0ef41Sopenharmony_ci    return base::IsInRange(operand_type, OperandType::kIdx,
2061cb0ef41Sopenharmony_ci                           OperandType::kRegCount);
2071cb0ef41Sopenharmony_ci  }
2081cb0ef41Sopenharmony_ci};
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci}  // namespace interpreter
2111cb0ef41Sopenharmony_ci}  // namespace internal
2121cb0ef41Sopenharmony_ci}  // namespace v8
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci#endif  // V8_INTERPRETER_BYTECODE_OPERANDS_H_
215