v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
register-base.h
Go to the documentation of this file.
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_CODEGEN_REGISTER_BASE_H_
6#define V8_CODEGEN_REGISTER_BASE_H_
7
8#include "src/base/bits.h"
9#include "src/base/bounds.h"
10#include "src/common/globals.h"
11
12namespace v8 {
13
14namespace internal {
15
16// Base type for CPU Registers.
17//
18// 1) We would prefer to use an enum for registers, but enum values are
19// assignment-compatible with int, which has caused code-generation bugs.
20//
21// 2) By not using an enum, we are possibly preventing the compiler from
22// doing certain constant folds, which may significantly reduce the
23// code generated for some assembly instructions (because they boil down
24// to a few constants). If this is a problem, we could change the code
25// such that we use an enum in optimized mode, and the class in debug
26// mode. This way we get the compile-time error checking in debug mode
27// and best performance in optimized code.
28template <typename SubType, int kAfterLastRegister>
30 public:
31 static constexpr int8_t kCode_no_reg = -1;
32 static constexpr int8_t kNumRegisters = kAfterLastRegister;
33
34 static constexpr SubType no_reg() { return SubType{kCode_no_reg}; }
35
36 static constexpr SubType from_code(int8_t code) {
37 V8_ASSUME(code >= 0 && code < kNumRegisters);
38 return SubType{code};
39 }
40
41 constexpr bool is_valid() const { return reg_code_ != kCode_no_reg; }
42
43 constexpr int8_t code() const {
44#if V8_TARGET_ARCH_ARM64
45 // Arm64 uses kSPRegInternalCode which is > kNumRegisters.
46 V8_ASSUME(reg_code_ >= 0);
47#else
49#endif
50 return reg_code_;
51 }
52
53 inline constexpr bool operator==(
55 return reg_code_ == other.reg_code_;
56 }
57 inline constexpr bool operator!=(
59 return reg_code_ != other.reg_code_;
60 }
61
62 // Used to print the name of some special registers.
63 static const char* GetSpecialRegisterName(int code) { return "UNKNOWN"; }
64
65 protected:
66 explicit constexpr RegisterBase(int code) : reg_code_(code) {}
67
68 private:
69 int8_t reg_code_;
70 static_assert(kAfterLastRegister <= kMaxInt8);
71};
72
73template <typename RegType,
74 typename = decltype(RegisterName(std::declval<RegType>()))>
75inline std::ostream& operator<<(std::ostream& os, RegType reg) {
76 return os << RegisterName(reg);
77}
78
79// Helper macros to define a {RegisterName} method based on a macro list
80// containing all names.
81#define DEFINE_REGISTER_NAMES_NAME(name) #name,
82#define DEFINE_REGISTER_NAMES(RegType, LIST) \
83 inline const char* RegisterName(RegType reg) { \
84 static constexpr const char* Names[] = {LIST(DEFINE_REGISTER_NAMES_NAME)}; \
85 static_assert(arraysize(Names) == RegType::kNumRegisters); \
86 return reg.is_valid() ? Names[reg.code()] : "invalid"; \
87 }
88
89} // namespace internal
90} // namespace v8
91
92#endif // V8_CODEGEN_REGISTER_BASE_H_
constexpr bool operator!=(const RegisterBase< SubType, kAfterLastRegister > &other) const
constexpr RegisterBase(int code)
static constexpr int8_t kNumRegisters
constexpr bool is_valid() const
constexpr bool operator==(const RegisterBase< SubType, kAfterLastRegister > &other) const
static constexpr SubType from_code(int8_t code)
static const char * GetSpecialRegisterName(int code)
static constexpr SubType no_reg()
static constexpr int8_t kCode_no_reg
constexpr int8_t code() const
LiftoffRegister reg
constexpr int kMaxInt8
Definition globals.h:376
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
#define V8_ASSUME
Definition v8config.h:533