LCOV - code coverage report
Current view: top level - src - register.h (source / functions) Hit Total Coverage
Test: app.info Lines: 6 6 100.0 %
Date: 2019-04-18 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_REGISTER_H_
       6             : #define V8_REGISTER_H_
       7             : 
       8             : #include "src/reglist.h"
       9             : 
      10             : namespace v8 {
      11             : 
      12             : namespace internal {
      13             : 
      14             : // Base type for CPU Registers.
      15             : //
      16             : // 1) We would prefer to use an enum for registers, but enum values are
      17             : // assignment-compatible with int, which has caused code-generation bugs.
      18             : //
      19             : // 2) By not using an enum, we are possibly preventing the compiler from
      20             : // doing certain constant folds, which may significantly reduce the
      21             : // code generated for some assembly instructions (because they boil down
      22             : // to a few constants). If this is a problem, we could change the code
      23             : // such that we use an enum in optimized mode, and the class in debug
      24             : // mode. This way we get the compile-time error checking in debug mode
      25             : // and best performance in optimized code.
      26             : template <typename SubType, int kAfterLastRegister>
      27             : class RegisterBase {
      28             :   // Internal enum class; used for calling constexpr methods, where we need to
      29             :   // pass an integral type as template parameter.
      30             :   enum class RegisterCode : int { kFirst = 0, kAfterLast = kAfterLastRegister };
      31             : 
      32             :  public:
      33             :   static constexpr int kCode_no_reg = -1;
      34             :   static constexpr int kNumRegisters = kAfterLastRegister;
      35             : 
      36             :   static constexpr SubType no_reg() { return SubType{kCode_no_reg}; }
      37             : 
      38             :   template <int code>
      39             :   static constexpr SubType from_code() {
      40             :     static_assert(code >= 0 && code < kNumRegisters, "must be valid reg code");
      41             :     return SubType{code};
      42             :   }
      43             : 
      44             :   constexpr operator RegisterCode() const {
      45             :     return static_cast<RegisterCode>(reg_code_);
      46             :   }
      47             : 
      48             :   template <RegisterCode reg_code>
      49             :   static constexpr int code() {
      50             :     static_assert(
      51             :         reg_code >= RegisterCode::kFirst && reg_code < RegisterCode::kAfterLast,
      52             :         "must be valid reg");
      53             :     return static_cast<int>(reg_code);
      54             :   }
      55             : 
      56             :   template <RegisterCode reg_code>
      57             :   static constexpr int is_valid() {
      58             :     return static_cast<int>(reg_code) != kCode_no_reg;
      59             :   }
      60             : 
      61             :   template <RegisterCode reg_code>
      62             :   static constexpr RegList bit() {
      63             :     return is_valid<reg_code>() ? RegList{1} << code<reg_code>() : RegList{};
      64             :   }
      65             : 
      66             :   static SubType from_code(int code) {
      67             :     DCHECK_LE(0, code);
      68             :     DCHECK_GT(kNumRegisters, code);
      69             :     return SubType{code};
      70             :   }
      71             : 
      72             :   // Constexpr version (pass registers as template parameters).
      73             :   template <RegisterCode... reg_codes>
      74             :   static constexpr RegList ListOf() {
      75             :     return CombineRegLists(RegisterBase::bit<reg_codes>()...);
      76             :   }
      77             : 
      78             :   // Non-constexpr version (pass registers as method parameters).
      79             :   template <typename... Register>
      80             :   static RegList ListOf(Register... regs) {
      81             :     return CombineRegLists(regs.bit()...);
      82             :   }
      83             : 
      84      615344 :   constexpr bool is_valid() const { return reg_code_ != kCode_no_reg; }
      85             : 
      86             :   int code() const {
      87             :     DCHECK(is_valid());
      88     7693555 :     return reg_code_;
      89             :   }
      90             : 
      91      614304 :   RegList bit() const { return is_valid() ? RegList{1} << code() : RegList{}; }
      92             : 
      93             :   inline constexpr bool operator==(SubType other) const {
      94      750043 :     return reg_code_ == other.reg_code_;
      95             :   }
      96             :   inline constexpr bool operator!=(SubType other) const {
      97      728973 :     return reg_code_ != other.reg_code_;
      98             :   }
      99             : 
     100             :   // Used to print the name of some special registers.
     101             :   static const char* GetSpecialRegisterName(int code) { return "UNKNOWN"; }
     102             : 
     103             :  protected:
     104             :   explicit constexpr RegisterBase(int code) : reg_code_(code) {}
     105             :   int reg_code_;
     106             : };
     107             : 
     108             : template <typename RegType,
     109             :           typename = decltype(RegisterName(std::declval<RegType>()))>
     110             : inline std::ostream& operator<<(std::ostream& os, RegType reg) {
     111         335 :   return os << RegisterName(reg);
     112             : }
     113             : 
     114             : // Helper macros to define a {RegisterName} method based on a macro list
     115             : // containing all names.
     116             : #define DEFINE_REGISTER_NAMES_NAME(name) #name,
     117             : #define DEFINE_REGISTER_NAMES(RegType, LIST)                                   \
     118             :   inline const char* RegisterName(RegType reg) {                               \
     119             :     static constexpr const char* Names[] = {LIST(DEFINE_REGISTER_NAMES_NAME)}; \
     120             :     STATIC_ASSERT(arraysize(Names) == RegType::kNumRegisters);                 \
     121             :     return reg.is_valid() ? Names[reg.code()] : "invalid";                     \
     122             :   }
     123             : 
     124             : }  // namespace internal
     125             : }  // namespace v8
     126             : #endif  // V8_REGISTER_H_

Generated by: LCOV version 1.10