11cb0ef41Sopenharmony_ci// Copyright 2015 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_REGISTER_H_ 61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_REGISTER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/base/macros.h" 111cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h" 121cb0ef41Sopenharmony_ci#include "src/common/globals.h" 131cb0ef41Sopenharmony_ci#include "src/execution/frame-constants.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace v8 { 161cb0ef41Sopenharmony_cinamespace internal { 171cb0ef41Sopenharmony_cinamespace interpreter { 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci// An interpreter Register which is located in the function's Register file 201cb0ef41Sopenharmony_ci// in its stack-frame. Register hold parameters, this, and expression values. 211cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Register final { 221cb0ef41Sopenharmony_ci public: 231cb0ef41Sopenharmony_ci constexpr explicit Register(int index = kInvalidIndex) : index_(index) {} 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci int index() const { return index_; } 261cb0ef41Sopenharmony_ci bool is_parameter() const { return index() < 0; } 271cb0ef41Sopenharmony_ci bool is_valid() const { return index_ != kInvalidIndex; } 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci static Register FromParameterIndex(int index); 301cb0ef41Sopenharmony_ci int ToParameterIndex() const; 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci // Returns an invalid register. 331cb0ef41Sopenharmony_ci static Register invalid_value() { return Register(); } 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci // Returns the register for the function's closure object. 361cb0ef41Sopenharmony_ci static Register function_closure(); 371cb0ef41Sopenharmony_ci bool is_function_closure() const; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci // Returns the register which holds the current context object. 401cb0ef41Sopenharmony_ci static Register current_context(); 411cb0ef41Sopenharmony_ci bool is_current_context() const; 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci // Returns the register for the bytecode array. 441cb0ef41Sopenharmony_ci static Register bytecode_array(); 451cb0ef41Sopenharmony_ci bool is_bytecode_array() const; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci // Returns the register for the saved bytecode offset. 481cb0ef41Sopenharmony_ci static Register bytecode_offset(); 491cb0ef41Sopenharmony_ci bool is_bytecode_offset() const; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci // Returns the register for the argument count. 521cb0ef41Sopenharmony_ci static Register argument_count(); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // Returns a register that can be used to represent the accumulator 551cb0ef41Sopenharmony_ci // within code in the interpreter, but should never be emitted in 561cb0ef41Sopenharmony_ci // bytecode. 571cb0ef41Sopenharmony_ci static Register virtual_accumulator(); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci OperandSize SizeOfOperand() const; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci constexpr int32_t ToOperand() const { 621cb0ef41Sopenharmony_ci return kRegisterFileStartOffset - index_; 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci static Register FromOperand(int32_t operand) { 651cb0ef41Sopenharmony_ci return Register(kRegisterFileStartOffset - operand); 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci static constexpr Register FromShortStar(Bytecode bytecode) { 691cb0ef41Sopenharmony_ci DCHECK(Bytecodes::IsShortStar(bytecode)); 701cb0ef41Sopenharmony_ci return Register(static_cast<int>(Bytecode::kStar0) - 711cb0ef41Sopenharmony_ci static_cast<int>(bytecode)); 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci const base::Optional<Bytecode> TryToShortStar() const { 751cb0ef41Sopenharmony_ci if (index() >= 0 && index() < Bytecodes::kShortStarCount) { 761cb0ef41Sopenharmony_ci Bytecode bytecode = 771cb0ef41Sopenharmony_ci static_cast<Bytecode>(static_cast<int>(Bytecode::kStar0) - index()); 781cb0ef41Sopenharmony_ci DCHECK_GE(bytecode, Bytecode::kFirstShortStar); 791cb0ef41Sopenharmony_ci DCHECK_LE(bytecode, Bytecode::kLastShortStar); 801cb0ef41Sopenharmony_ci return bytecode; 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci return {}; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci static bool AreContiguous(Register reg1, Register reg2, 861cb0ef41Sopenharmony_ci Register reg3 = invalid_value(), 871cb0ef41Sopenharmony_ci Register reg4 = invalid_value(), 881cb0ef41Sopenharmony_ci Register reg5 = invalid_value()); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci std::string ToString() const; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci bool operator==(const Register& other) const { 931cb0ef41Sopenharmony_ci return index() == other.index(); 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci bool operator!=(const Register& other) const { 961cb0ef41Sopenharmony_ci return index() != other.index(); 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci bool operator<(const Register& other) const { 991cb0ef41Sopenharmony_ci return index() < other.index(); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci bool operator<=(const Register& other) const { 1021cb0ef41Sopenharmony_ci return index() <= other.index(); 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci bool operator>(const Register& other) const { 1051cb0ef41Sopenharmony_ci return index() > other.index(); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci bool operator>=(const Register& other) const { 1081cb0ef41Sopenharmony_ci return index() >= other.index(); 1091cb0ef41Sopenharmony_ci } 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci private: 1121cb0ef41Sopenharmony_ci DISALLOW_NEW_AND_DELETE() 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci static const int kInvalidIndex = kMaxInt; 1151cb0ef41Sopenharmony_ci static const int kRegisterFileStartOffset = 1161cb0ef41Sopenharmony_ci InterpreterFrameConstants::kRegisterFileFromFp / kSystemPointerSize; 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci int index_; 1191cb0ef41Sopenharmony_ci}; 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ciclass RegisterList { 1221cb0ef41Sopenharmony_ci public: 1231cb0ef41Sopenharmony_ci RegisterList() 1241cb0ef41Sopenharmony_ci : first_reg_index_(Register::invalid_value().index()), 1251cb0ef41Sopenharmony_ci register_count_(0) {} 1261cb0ef41Sopenharmony_ci explicit RegisterList(Register r) : RegisterList(r.index(), 1) {} 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci // Returns a new RegisterList which is a truncated version of this list, with 1291cb0ef41Sopenharmony_ci // |count| registers. 1301cb0ef41Sopenharmony_ci const RegisterList Truncate(int new_count) { 1311cb0ef41Sopenharmony_ci DCHECK_GE(new_count, 0); 1321cb0ef41Sopenharmony_ci DCHECK_LT(new_count, register_count_); 1331cb0ef41Sopenharmony_ci return RegisterList(first_reg_index_, new_count); 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci const RegisterList PopLeft() { 1361cb0ef41Sopenharmony_ci DCHECK_GE(register_count_, 0); 1371cb0ef41Sopenharmony_ci return RegisterList(first_reg_index_ + 1, register_count_ - 1); 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci const Register operator[](size_t i) const { 1411cb0ef41Sopenharmony_ci DCHECK_LT(static_cast<int>(i), register_count_); 1421cb0ef41Sopenharmony_ci return Register(first_reg_index_ + static_cast<int>(i)); 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci const Register first_register() const { 1461cb0ef41Sopenharmony_ci return (register_count() == 0) ? Register(0) : (*this)[0]; 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci const Register last_register() const { 1501cb0ef41Sopenharmony_ci return (register_count() == 0) ? Register(0) : (*this)[register_count_ - 1]; 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci int register_count() const { return register_count_; } 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci private: 1561cb0ef41Sopenharmony_ci friend class BytecodeRegisterAllocator; 1571cb0ef41Sopenharmony_ci friend class BytecodeDecoder; 1581cb0ef41Sopenharmony_ci friend class InterpreterTester; 1591cb0ef41Sopenharmony_ci friend class BytecodeUtils; 1601cb0ef41Sopenharmony_ci friend class BytecodeArrayIterator; 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci RegisterList(int first_reg_index, int register_count) 1631cb0ef41Sopenharmony_ci : first_reg_index_(first_reg_index), register_count_(register_count) {} 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci // Increases the size of the register list by one. 1661cb0ef41Sopenharmony_ci void IncrementRegisterCount() { register_count_++; } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci int first_reg_index_; 1691cb0ef41Sopenharmony_ci int register_count_; 1701cb0ef41Sopenharmony_ci}; 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci} // namespace interpreter 1731cb0ef41Sopenharmony_ci} // namespace internal 1741cb0ef41Sopenharmony_ci} // namespace v8 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci#endif // V8_INTERPRETER_BYTECODE_REGISTER_H_ 177