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 | return allocatable_general_codes_[index]; |
79 | } |
80 | bool IsAllocatableGeneralCode(int index) const { |
81 | 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 | 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 | 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 | 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 | 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 | 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 | 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_ |
156 | |