• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/register-configuration.h"
6 #include "src/globals.h"
7 #include "src/macro-assembler.h"
8 
9 namespace v8 {
10 namespace internal {
11 
12 namespace {
13 
14 #define REGISTER_COUNT(R) 1 +
15 static const int kMaxAllocatableGeneralRegisterCount =
16     ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0;
17 static const int kMaxAllocatableDoubleRegisterCount =
18     ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_COUNT)0;
19 
20 static const int kAllocatableGeneralCodes[] = {
21 #define REGISTER_CODE(R) Register::kCode_##R,
22     ALLOCATABLE_GENERAL_REGISTERS(REGISTER_CODE)};
23 #undef REGISTER_CODE
24 
25 static const int kAllocatableDoubleCodes[] = {
26 #define REGISTER_CODE(R) DoubleRegister::kCode_##R,
27     ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_CODE)};
28 #undef REGISTER_CODE
29 
30 static const char* const kGeneralRegisterNames[] = {
31 #define REGISTER_NAME(R) #R,
32     GENERAL_REGISTERS(REGISTER_NAME)
33 #undef REGISTER_NAME
34 };
35 
36 static const char* const kFloatRegisterNames[] = {
37 #define REGISTER_NAME(R) #R,
38     FLOAT_REGISTERS(REGISTER_NAME)
39 #undef REGISTER_NAME
40 };
41 
42 static const char* const kDoubleRegisterNames[] = {
43 #define REGISTER_NAME(R) #R,
44     DOUBLE_REGISTERS(REGISTER_NAME)
45 #undef REGISTER_NAME
46 };
47 
48 STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
49               Register::kNumRegisters);
50 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
51               DoubleRegister::kMaxNumRegisters);
52 
53 enum CompilerSelector { CRANKSHAFT, TURBOFAN };
54 
55 class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
56  public:
ArchDefaultRegisterConfiguration(CompilerSelector compiler)57   explicit ArchDefaultRegisterConfiguration(CompilerSelector compiler)
58       : RegisterConfiguration(
59             Register::kNumRegisters, DoubleRegister::kMaxNumRegisters,
60 #if V8_TARGET_ARCH_IA32
61             kMaxAllocatableGeneralRegisterCount,
62             kMaxAllocatableDoubleRegisterCount,
63 #elif V8_TARGET_ARCH_X87
64             kMaxAllocatableGeneralRegisterCount,
65             compiler == TURBOFAN ? 1 : kMaxAllocatableDoubleRegisterCount,
66 #elif V8_TARGET_ARCH_X64
67             kMaxAllocatableGeneralRegisterCount,
68             kMaxAllocatableDoubleRegisterCount,
69 #elif V8_TARGET_ARCH_ARM
70             FLAG_enable_embedded_constant_pool
71                 ? (kMaxAllocatableGeneralRegisterCount - 1)
72                 : kMaxAllocatableGeneralRegisterCount,
73             CpuFeatures::IsSupported(VFP32DREGS)
74                 ? kMaxAllocatableDoubleRegisterCount
75                 : (ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_COUNT) 0),
76 #elif V8_TARGET_ARCH_ARM64
77             kMaxAllocatableGeneralRegisterCount,
78             kMaxAllocatableDoubleRegisterCount,
79 #elif V8_TARGET_ARCH_MIPS
80             kMaxAllocatableGeneralRegisterCount,
81             kMaxAllocatableDoubleRegisterCount,
82 #elif V8_TARGET_ARCH_MIPS64
83             kMaxAllocatableGeneralRegisterCount,
84             kMaxAllocatableDoubleRegisterCount,
85 #elif V8_TARGET_ARCH_PPC
86             kMaxAllocatableGeneralRegisterCount,
87             kMaxAllocatableDoubleRegisterCount,
88 #elif V8_TARGET_ARCH_S390
89             kMaxAllocatableGeneralRegisterCount,
90             kMaxAllocatableDoubleRegisterCount,
91 #else
92 #error Unsupported target architecture.
93 #endif
94             kAllocatableGeneralCodes, kAllocatableDoubleCodes,
95             kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE,
96             kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames) {
97   }
98 };
99 
100 template <CompilerSelector compiler>
101 struct RegisterConfigurationInitializer {
Constructv8::internal::__anon464ea5840111::RegisterConfigurationInitializer102   static void Construct(ArchDefaultRegisterConfiguration* config) {
103     new (config) ArchDefaultRegisterConfiguration(compiler);
104   }
105 };
106 
107 static base::LazyInstance<ArchDefaultRegisterConfiguration,
108                           RegisterConfigurationInitializer<CRANKSHAFT>>::type
109     kDefaultRegisterConfigurationForCrankshaft = LAZY_INSTANCE_INITIALIZER;
110 
111 static base::LazyInstance<ArchDefaultRegisterConfiguration,
112                           RegisterConfigurationInitializer<TURBOFAN>>::type
113     kDefaultRegisterConfigurationForTurboFan = LAZY_INSTANCE_INITIALIZER;
114 
115 }  // namespace
116 
Crankshaft()117 const RegisterConfiguration* RegisterConfiguration::Crankshaft() {
118   return &kDefaultRegisterConfigurationForCrankshaft.Get();
119 }
120 
Turbofan()121 const RegisterConfiguration* RegisterConfiguration::Turbofan() {
122   return &kDefaultRegisterConfigurationForTurboFan.Get();
123 }
124 
RegisterConfiguration(int num_general_registers,int num_double_registers,int num_allocatable_general_registers,int num_allocatable_double_registers,const int * allocatable_general_codes,const int * allocatable_double_codes,AliasingKind fp_aliasing_kind,const char * const * general_register_names,const char * const * float_register_names,const char * const * double_register_names)125 RegisterConfiguration::RegisterConfiguration(
126     int num_general_registers, int num_double_registers,
127     int num_allocatable_general_registers, int num_allocatable_double_registers,
128     const int* allocatable_general_codes, const int* allocatable_double_codes,
129     AliasingKind fp_aliasing_kind, const char* const* general_register_names,
130     const char* const* float_register_names,
131     const char* const* double_register_names)
132     : num_general_registers_(num_general_registers),
133       num_float_registers_(0),
134       num_double_registers_(num_double_registers),
135       num_allocatable_general_registers_(num_allocatable_general_registers),
136       num_allocatable_double_registers_(num_allocatable_double_registers),
137       num_allocatable_float_registers_(0),
138       allocatable_general_codes_mask_(0),
139       allocatable_double_codes_mask_(0),
140       allocatable_float_codes_mask_(0),
141       allocatable_general_codes_(allocatable_general_codes),
142       allocatable_double_codes_(allocatable_double_codes),
143       fp_aliasing_kind_(fp_aliasing_kind),
144       general_register_names_(general_register_names),
145       float_register_names_(float_register_names),
146       double_register_names_(double_register_names) {
147   DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters);
148   DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters);
149   for (int i = 0; i < num_allocatable_general_registers_; ++i) {
150     allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[i]);
151   }
152   for (int i = 0; i < num_allocatable_double_registers_; ++i) {
153     allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[i]);
154   }
155 
156   if (fp_aliasing_kind_ == COMBINE) {
157     num_float_registers_ = num_double_registers_ * 2 <= kMaxFPRegisters
158                                ? num_double_registers_ * 2
159                                : kMaxFPRegisters;
160     num_allocatable_float_registers_ = 0;
161     for (int i = 0; i < num_allocatable_double_registers_; i++) {
162       int base_code = allocatable_double_codes_[i] * 2;
163       if (base_code >= kMaxFPRegisters) continue;
164       allocatable_float_codes_[num_allocatable_float_registers_++] = base_code;
165       allocatable_float_codes_[num_allocatable_float_registers_++] =
166           base_code + 1;
167       allocatable_float_codes_mask_ |= (0x3 << base_code);
168     }
169   } else {
170     DCHECK(fp_aliasing_kind_ == OVERLAP);
171     num_float_registers_ = num_double_registers_;
172     num_allocatable_float_registers_ = num_allocatable_double_registers_;
173     for (int i = 0; i < num_allocatable_float_registers_; ++i) {
174       allocatable_float_codes_[i] = allocatable_double_codes_[i];
175     }
176     allocatable_float_codes_mask_ = allocatable_double_codes_mask_;
177   }
178 }
179 
GetAliases(MachineRepresentation rep,int index,MachineRepresentation other_rep,int * alias_base_index) const180 int RegisterConfiguration::GetAliases(MachineRepresentation rep, int index,
181                                       MachineRepresentation other_rep,
182                                       int* alias_base_index) const {
183   DCHECK(fp_aliasing_kind_ == COMBINE);
184   DCHECK(rep == MachineRepresentation::kFloat32 ||
185          rep == MachineRepresentation::kFloat64);
186   DCHECK(other_rep == MachineRepresentation::kFloat32 ||
187          other_rep == MachineRepresentation::kFloat64);
188   if (rep == other_rep) {
189     *alias_base_index = index;
190     return 1;
191   }
192   if (rep == MachineRepresentation::kFloat32) {
193     DCHECK(other_rep == MachineRepresentation::kFloat64);
194     DCHECK(index < num_allocatable_float_registers_);
195     *alias_base_index = index / 2;
196     return 1;
197   }
198   DCHECK(rep == MachineRepresentation::kFloat64);
199   DCHECK(other_rep == MachineRepresentation::kFloat32);
200   if (index * 2 >= kMaxFPRegisters) {
201     // Alias indices are out of float register range.
202     return 0;
203   }
204   *alias_base_index = index * 2;
205   return 2;
206 }
207 
AreAliases(MachineRepresentation rep,int index,MachineRepresentation other_rep,int other_index) const208 bool RegisterConfiguration::AreAliases(MachineRepresentation rep, int index,
209                                        MachineRepresentation other_rep,
210                                        int other_index) const {
211   DCHECK(fp_aliasing_kind_ == COMBINE);
212   DCHECK(rep == MachineRepresentation::kFloat32 ||
213          rep == MachineRepresentation::kFloat64);
214   DCHECK(other_rep == MachineRepresentation::kFloat32 ||
215          other_rep == MachineRepresentation::kFloat64);
216   if (rep == other_rep) {
217     return index == other_index;
218   }
219   if (rep == MachineRepresentation::kFloat32) {
220     DCHECK(other_rep == MachineRepresentation::kFloat64);
221     return index / 2 == other_index;
222   }
223   DCHECK(rep == MachineRepresentation::kFloat64);
224   DCHECK(other_rep == MachineRepresentation::kFloat32);
225   if (index * 2 >= kMaxFPRegisters) {
226     // Alias indices are out of float register range.
227     return false;
228   }
229   return index == other_index / 2;
230 }
231 
232 #undef REGISTER_COUNT
233 
234 }  // namespace internal
235 }  // namespace v8
236