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