Line data Source code
1 : // Copyright 2014 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_CONFIGURATION_H_
6 : #define V8_REGISTER_CONFIGURATION_H_
7 :
8 : #include "src/base/macros.h"
9 : #include "src/globals.h"
10 : #include "src/machine-type.h"
11 : #include "src/reglist.h"
12 : #include "src/utils.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // An architecture independent representation of the sets of registers available
18 : // for instruction creation.
19 : class V8_EXPORT_PRIVATE RegisterConfiguration {
20 : public:
21 : enum AliasingKind {
22 : // Registers alias a single register of every other size (e.g. Intel).
23 : OVERLAP,
24 : // Registers alias two registers of the next smaller size (e.g. ARM).
25 : COMBINE
26 : };
27 :
28 : // Architecture independent maxes.
29 : static constexpr int kMaxGeneralRegisters = 32;
30 : static constexpr int kMaxFPRegisters = 32;
31 : static constexpr int kMaxRegisters =
32 : Max(kMaxFPRegisters, kMaxGeneralRegisters);
33 :
34 : // Default RegisterConfigurations for the target architecture.
35 : static const RegisterConfiguration* Default();
36 :
37 : // Register configuration with reserved masking register.
38 : static const RegisterConfiguration* Poisoning();
39 :
40 : static const RegisterConfiguration* RestrictGeneralRegisters(
41 : RegList registers);
42 :
43 : RegisterConfiguration(int num_general_registers, int num_double_registers,
44 : int num_allocatable_general_registers,
45 : int num_allocatable_double_registers,
46 : const int* allocatable_general_codes,
47 : const int* allocatable_double_codes,
48 : AliasingKind fp_aliasing_kind);
49 :
50 : int num_general_registers() const { return num_general_registers_; }
51 : int num_float_registers() const { return num_float_registers_; }
52 : int num_double_registers() const { return num_double_registers_; }
53 : int num_simd128_registers() const { return num_simd128_registers_; }
54 : int num_allocatable_general_registers() const {
55 : return num_allocatable_general_registers_;
56 : }
57 : int num_allocatable_float_registers() const {
58 : return num_allocatable_float_registers_;
59 : }
60 : int num_allocatable_double_registers() const {
61 : return num_allocatable_double_registers_;
62 : }
63 : int num_allocatable_simd128_registers() const {
64 : return num_allocatable_simd128_registers_;
65 : }
66 : AliasingKind fp_aliasing_kind() const { return fp_aliasing_kind_; }
67 : int32_t allocatable_general_codes_mask() const {
68 : return allocatable_general_codes_mask_;
69 : }
70 : int32_t allocatable_double_codes_mask() const {
71 : return allocatable_double_codes_mask_;
72 : }
73 : int32_t allocatable_float_codes_mask() const {
74 : return allocatable_float_codes_mask_;
75 : }
76 : int GetAllocatableGeneralCode(int index) const {
77 : DCHECK(index >= 0 && index < num_allocatable_general_registers());
78 73149619 : return allocatable_general_codes_[index];
79 : }
80 : bool IsAllocatableGeneralCode(int index) const {
81 704 : return ((1 << index) & allocatable_general_codes_mask_) != 0;
82 : }
83 : int GetAllocatableFloatCode(int index) const {
84 : DCHECK(index >= 0 && index < num_allocatable_float_registers());
85 790798 : return allocatable_float_codes_[index];
86 : }
87 : bool IsAllocatableFloatCode(int index) const {
88 : return ((1 << index) & allocatable_float_codes_mask_) != 0;
89 : }
90 : int GetAllocatableDoubleCode(int index) const {
91 : DCHECK(index >= 0 && index < num_allocatable_double_registers());
92 92450365 : return allocatable_double_codes_[index];
93 : }
94 : bool IsAllocatableDoubleCode(int index) const {
95 : return ((1 << index) & allocatable_double_codes_mask_) != 0;
96 : }
97 : int GetAllocatableSimd128Code(int index) const {
98 : DCHECK(index >= 0 && index < num_allocatable_simd128_registers());
99 117752 : return allocatable_simd128_codes_[index];
100 : }
101 : bool IsAllocatableSimd128Code(int index) const {
102 : return ((1 << index) & allocatable_simd128_codes_mask_) != 0;
103 : }
104 :
105 : const int* allocatable_general_codes() const {
106 : return allocatable_general_codes_;
107 : }
108 : const int* allocatable_float_codes() const {
109 4 : return allocatable_float_codes_;
110 : }
111 : const int* allocatable_double_codes() const {
112 : return allocatable_double_codes_;
113 : }
114 : const int* allocatable_simd128_codes() const {
115 0 : return allocatable_simd128_codes_;
116 : }
117 :
118 : // Aliasing calculations for floating point registers, when fp_aliasing_kind()
119 : // is COMBINE. Currently only implemented for kFloat32, kFloat64, or kSimd128
120 : // reps. Returns the number of aliases, and if > 0, alias_base_index is set to
121 : // the index of the first alias.
122 : int GetAliases(MachineRepresentation rep, int index,
123 : MachineRepresentation other_rep, int* alias_base_index) const;
124 : // Returns a value indicating whether two registers alias each other, when
125 : // fp_aliasing_kind() is COMBINE. Currently implemented for kFloat32,
126 : // kFloat64, or kSimd128 reps.
127 : bool AreAliases(MachineRepresentation rep, int index,
128 : MachineRepresentation other_rep, int other_index) const;
129 :
130 406 : virtual ~RegisterConfiguration() = default;
131 :
132 : private:
133 : const int num_general_registers_;
134 : int num_float_registers_;
135 : const int num_double_registers_;
136 : int num_simd128_registers_;
137 : int num_allocatable_general_registers_;
138 : int num_allocatable_float_registers_;
139 : int num_allocatable_double_registers_;
140 : int num_allocatable_simd128_registers_;
141 : int32_t allocatable_general_codes_mask_;
142 : int32_t allocatable_float_codes_mask_;
143 : int32_t allocatable_double_codes_mask_;
144 : int32_t allocatable_simd128_codes_mask_;
145 : const int* allocatable_general_codes_;
146 : int allocatable_float_codes_[kMaxFPRegisters];
147 : const int* allocatable_double_codes_;
148 : int allocatable_simd128_codes_[kMaxFPRegisters];
149 : AliasingKind fp_aliasing_kind_;
150 : };
151 :
152 : } // namespace internal
153 : } // namespace v8
154 :
155 : #endif // V8_REGISTER_CONFIGURATION_H_
|