11cb0ef41Sopenharmony_ci// Copyright 2017 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_NODE_H_
61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_NODE_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <algorithm>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/common/globals.h"
111cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-source-info.h"
121cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8 {
151cb0ef41Sopenharmony_cinamespace internal {
161cb0ef41Sopenharmony_cinamespace interpreter {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci// A container for a generated bytecode, it's operands, and source information.
191cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE BytecodeNode final {
201cb0ef41Sopenharmony_ci public:
211cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode,
221cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info = BytecodeSourceInfo())
231cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
241cb0ef41Sopenharmony_ci        operand_count_(0),
251cb0ef41Sopenharmony_ci        operand_scale_(OperandScale::kSingle),
261cb0ef41Sopenharmony_ci        source_info_(source_info) {
271cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
281cb0ef41Sopenharmony_ci  }
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
311cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info = BytecodeSourceInfo())
321cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
331cb0ef41Sopenharmony_ci        operand_count_(1),
341cb0ef41Sopenharmony_ci        operand_scale_(OperandScale::kSingle),
351cb0ef41Sopenharmony_ci        source_info_(source_info) {
361cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
371cb0ef41Sopenharmony_ci    SetOperand(0, operand0);
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
411cb0ef41Sopenharmony_ci                         uint32_t operand1,
421cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info = BytecodeSourceInfo())
431cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
441cb0ef41Sopenharmony_ci        operand_count_(2),
451cb0ef41Sopenharmony_ci        operand_scale_(OperandScale::kSingle),
461cb0ef41Sopenharmony_ci        source_info_(source_info) {
471cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
481cb0ef41Sopenharmony_ci    SetOperand(0, operand0);
491cb0ef41Sopenharmony_ci    SetOperand(1, operand1);
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
531cb0ef41Sopenharmony_ci                         uint32_t operand1, uint32_t operand2,
541cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info = BytecodeSourceInfo())
551cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
561cb0ef41Sopenharmony_ci        operand_count_(3),
571cb0ef41Sopenharmony_ci        operand_scale_(OperandScale::kSingle),
581cb0ef41Sopenharmony_ci        source_info_(source_info) {
591cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
601cb0ef41Sopenharmony_ci    SetOperand(0, operand0);
611cb0ef41Sopenharmony_ci    SetOperand(1, operand1);
621cb0ef41Sopenharmony_ci    SetOperand(2, operand2);
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
661cb0ef41Sopenharmony_ci                         uint32_t operand1, uint32_t operand2,
671cb0ef41Sopenharmony_ci                         uint32_t operand3,
681cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info = BytecodeSourceInfo())
691cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
701cb0ef41Sopenharmony_ci        operand_count_(4),
711cb0ef41Sopenharmony_ci        operand_scale_(OperandScale::kSingle),
721cb0ef41Sopenharmony_ci        source_info_(source_info) {
731cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
741cb0ef41Sopenharmony_ci    SetOperand(0, operand0);
751cb0ef41Sopenharmony_ci    SetOperand(1, operand1);
761cb0ef41Sopenharmony_ci    SetOperand(2, operand2);
771cb0ef41Sopenharmony_ci    SetOperand(3, operand3);
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
811cb0ef41Sopenharmony_ci                         uint32_t operand1, uint32_t operand2,
821cb0ef41Sopenharmony_ci                         uint32_t operand3, uint32_t operand4,
831cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info = BytecodeSourceInfo())
841cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
851cb0ef41Sopenharmony_ci        operand_count_(5),
861cb0ef41Sopenharmony_ci        operand_scale_(OperandScale::kSingle),
871cb0ef41Sopenharmony_ci        source_info_(source_info) {
881cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
891cb0ef41Sopenharmony_ci    SetOperand(0, operand0);
901cb0ef41Sopenharmony_ci    SetOperand(1, operand1);
911cb0ef41Sopenharmony_ci    SetOperand(2, operand2);
921cb0ef41Sopenharmony_ci    SetOperand(3, operand3);
931cb0ef41Sopenharmony_ci    SetOperand(4, operand4);
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci#define DEFINE_BYTECODE_NODE_CREATOR(Name, ...)                              \
971cb0ef41Sopenharmony_ci  template <typename... Operands>                                            \
981cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Name(BytecodeSourceInfo source_info,         \
991cb0ef41Sopenharmony_ci                                     Operands... operands) {                 \
1001cb0ef41Sopenharmony_ci    return Create<Bytecode::k##Name, __VA_ARGS__>(source_info, operands...); \
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci  BYTECODE_LIST(DEFINE_BYTECODE_NODE_CREATOR)
1031cb0ef41Sopenharmony_ci#undef DEFINE_BYTECODE_NODE_CREATOR
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  // Print to stream |os|.
1061cb0ef41Sopenharmony_ci  void Print(std::ostream& os) const;
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  Bytecode bytecode() const { return bytecode_; }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  uint32_t operand(int i) const {
1111cb0ef41Sopenharmony_ci    DCHECK_LT(i, operand_count());
1121cb0ef41Sopenharmony_ci    return operands_[i];
1131cb0ef41Sopenharmony_ci  }
1141cb0ef41Sopenharmony_ci  const uint32_t* operands() const { return operands_; }
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  void update_operand0(uint32_t operand0) { SetOperand(0, operand0); }
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  int operand_count() const { return operand_count_; }
1191cb0ef41Sopenharmony_ci  OperandScale operand_scale() const { return operand_scale_; }
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  const BytecodeSourceInfo& source_info() const { return source_info_; }
1221cb0ef41Sopenharmony_ci  void set_source_info(BytecodeSourceInfo source_info) {
1231cb0ef41Sopenharmony_ci    source_info_ = source_info;
1241cb0ef41Sopenharmony_ci  }
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  bool operator==(const BytecodeNode& other) const;
1271cb0ef41Sopenharmony_ci  bool operator!=(const BytecodeNode& other) const { return !(*this == other); }
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci private:
1301cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse implicit_register_use,
1311cb0ef41Sopenharmony_ci            OperandType... operand_types>
1321cb0ef41Sopenharmony_ci  friend class BytecodeNodeBuilder;
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  V8_INLINE BytecodeNode(Bytecode bytecode, int operand_count,
1351cb0ef41Sopenharmony_ci                         OperandScale operand_scale,
1361cb0ef41Sopenharmony_ci                         BytecodeSourceInfo source_info, uint32_t operand0 = 0,
1371cb0ef41Sopenharmony_ci                         uint32_t operand1 = 0, uint32_t operand2 = 0,
1381cb0ef41Sopenharmony_ci                         uint32_t operand3 = 0, uint32_t operand4 = 0)
1391cb0ef41Sopenharmony_ci      : bytecode_(bytecode),
1401cb0ef41Sopenharmony_ci        operand_count_(operand_count),
1411cb0ef41Sopenharmony_ci        operand_scale_(operand_scale),
1421cb0ef41Sopenharmony_ci        source_info_(source_info) {
1431cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count);
1441cb0ef41Sopenharmony_ci    operands_[0] = operand0;
1451cb0ef41Sopenharmony_ci    operands_[1] = operand1;
1461cb0ef41Sopenharmony_ci    operands_[2] = operand2;
1471cb0ef41Sopenharmony_ci    operands_[3] = operand3;
1481cb0ef41Sopenharmony_ci    operands_[4] = operand4;
1491cb0ef41Sopenharmony_ci  }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse accum_use>
1521cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info) {
1531cb0ef41Sopenharmony_ci    return BytecodeNode(bytecode, 0, OperandScale::kSingle, source_info);
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse accum_use,
1571cb0ef41Sopenharmony_ci            OperandType operand0_type>
1581cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
1591cb0ef41Sopenharmony_ci                                       uint32_t operand0) {
1601cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
1611cb0ef41Sopenharmony_ci    OperandScale scale = OperandScale::kSingle;
1621cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
1631cb0ef41Sopenharmony_ci    return BytecodeNode(bytecode, 1, scale, source_info, operand0);
1641cb0ef41Sopenharmony_ci  }
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse accum_use,
1671cb0ef41Sopenharmony_ci            OperandType operand0_type, OperandType operand1_type>
1681cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
1691cb0ef41Sopenharmony_ci                                       uint32_t operand0, uint32_t operand1) {
1701cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
1711cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
1721cb0ef41Sopenharmony_ci    OperandScale scale = OperandScale::kSingle;
1731cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
1741cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
1751cb0ef41Sopenharmony_ci    return BytecodeNode(bytecode, 2, scale, source_info, operand0, operand1);
1761cb0ef41Sopenharmony_ci  }
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse accum_use,
1791cb0ef41Sopenharmony_ci            OperandType operand0_type, OperandType operand1_type,
1801cb0ef41Sopenharmony_ci            OperandType operand2_type>
1811cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
1821cb0ef41Sopenharmony_ci                                       uint32_t operand0, uint32_t operand1,
1831cb0ef41Sopenharmony_ci                                       uint32_t operand2) {
1841cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
1851cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
1861cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
1871cb0ef41Sopenharmony_ci    OperandScale scale = OperandScale::kSingle;
1881cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
1891cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
1901cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
1911cb0ef41Sopenharmony_ci    return BytecodeNode(bytecode, 3, scale, source_info, operand0, operand1,
1921cb0ef41Sopenharmony_ci                        operand2);
1931cb0ef41Sopenharmony_ci  }
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse accum_use,
1961cb0ef41Sopenharmony_ci            OperandType operand0_type, OperandType operand1_type,
1971cb0ef41Sopenharmony_ci            OperandType operand2_type, OperandType operand3_type>
1981cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
1991cb0ef41Sopenharmony_ci                                       uint32_t operand0, uint32_t operand1,
2001cb0ef41Sopenharmony_ci                                       uint32_t operand2, uint32_t operand3) {
2011cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
2021cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
2031cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
2041cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
2051cb0ef41Sopenharmony_ci    OperandScale scale = OperandScale::kSingle;
2061cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
2071cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
2081cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
2091cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
2101cb0ef41Sopenharmony_ci    return BytecodeNode(bytecode, 4, scale, source_info, operand0, operand1,
2111cb0ef41Sopenharmony_ci                        operand2, operand3);
2121cb0ef41Sopenharmony_ci  }
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  template <Bytecode bytecode, ImplicitRegisterUse accum_use,
2151cb0ef41Sopenharmony_ci            OperandType operand0_type, OperandType operand1_type,
2161cb0ef41Sopenharmony_ci            OperandType operand2_type, OperandType operand3_type,
2171cb0ef41Sopenharmony_ci            OperandType operand4_type>
2181cb0ef41Sopenharmony_ci  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
2191cb0ef41Sopenharmony_ci                                       uint32_t operand0, uint32_t operand1,
2201cb0ef41Sopenharmony_ci                                       uint32_t operand2, uint32_t operand3,
2211cb0ef41Sopenharmony_ci                                       uint32_t operand4) {
2221cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
2231cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
2241cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
2251cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
2261cb0ef41Sopenharmony_ci    DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 4), operand4_type);
2271cb0ef41Sopenharmony_ci    OperandScale scale = OperandScale::kSingle;
2281cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
2291cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
2301cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
2311cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
2321cb0ef41Sopenharmony_ci    scale = std::max(scale, ScaleForOperand<operand4_type>(operand4));
2331cb0ef41Sopenharmony_ci    return BytecodeNode(bytecode, 5, scale, source_info, operand0, operand1,
2341cb0ef41Sopenharmony_ci                        operand2, operand3, operand4);
2351cb0ef41Sopenharmony_ci  }
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci  template <OperandType operand_type>
2381cb0ef41Sopenharmony_ci  V8_INLINE static OperandScale ScaleForOperand(uint32_t operand) {
2391cb0ef41Sopenharmony_ci    if (BytecodeOperands::IsScalableUnsignedByte(operand_type)) {
2401cb0ef41Sopenharmony_ci      return Bytecodes::ScaleForUnsignedOperand(operand);
2411cb0ef41Sopenharmony_ci    } else if (BytecodeOperands::IsScalableSignedByte(operand_type)) {
2421cb0ef41Sopenharmony_ci      return Bytecodes::ScaleForSignedOperand(operand);
2431cb0ef41Sopenharmony_ci    } else {
2441cb0ef41Sopenharmony_ci      return OperandScale::kSingle;
2451cb0ef41Sopenharmony_ci    }
2461cb0ef41Sopenharmony_ci  }
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci  V8_INLINE void UpdateScaleForOperand(int operand_index, uint32_t operand) {
2491cb0ef41Sopenharmony_ci    if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) {
2501cb0ef41Sopenharmony_ci      operand_scale_ =
2511cb0ef41Sopenharmony_ci          std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand));
2521cb0ef41Sopenharmony_ci    } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(),
2531cb0ef41Sopenharmony_ci                                                        operand_index)) {
2541cb0ef41Sopenharmony_ci      operand_scale_ =
2551cb0ef41Sopenharmony_ci          std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand));
2561cb0ef41Sopenharmony_ci    }
2571cb0ef41Sopenharmony_ci  }
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci  V8_INLINE void SetOperand(int operand_index, uint32_t operand) {
2601cb0ef41Sopenharmony_ci    operands_[operand_index] = operand;
2611cb0ef41Sopenharmony_ci    UpdateScaleForOperand(operand_index, operand);
2621cb0ef41Sopenharmony_ci  }
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci  Bytecode bytecode_;
2651cb0ef41Sopenharmony_ci  uint32_t operands_[Bytecodes::kMaxOperands];
2661cb0ef41Sopenharmony_ci  int operand_count_;
2671cb0ef41Sopenharmony_ci  OperandScale operand_scale_;
2681cb0ef41Sopenharmony_ci  BytecodeSourceInfo source_info_;
2691cb0ef41Sopenharmony_ci};
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
2721cb0ef41Sopenharmony_ci                                           const BytecodeNode& node);
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci}  // namespace interpreter
2751cb0ef41Sopenharmony_ci}  // namespace internal
2761cb0ef41Sopenharmony_ci}  // namespace v8
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci#endif  // V8_INTERPRETER_BYTECODE_NODE_H_
279