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