blob: 148c3fc212732a8da8dfa856979ea01f75781510 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
9namespace v8 {
10namespace internal {
11
12namespace {
13
14#define REGISTER_COUNT(R) 1 +
15static const int kMaxAllocatableGeneralRegisterCount =
16 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0;
17static const int kMaxAllocatableDoubleRegisterCount =
18 ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_COUNT)0;
19
20static const int kAllocatableGeneralCodes[] = {
21#define REGISTER_CODE(R) Register::kCode_##R,
22 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_CODE)};
23#undef REGISTER_CODE
24
25static const int kAllocatableDoubleCodes[] = {
26#define REGISTER_CODE(R) DoubleRegister::kCode_##R,
27 ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_CODE)};
28#undef REGISTER_CODE
29
30static const char* const kGeneralRegisterNames[] = {
31#define REGISTER_NAME(R) #R,
32 GENERAL_REGISTERS(REGISTER_NAME)
33#undef REGISTER_NAME
34};
35
Ben Murdoch61f157c2016-09-16 13:49:30 +010036static const char* const kFloatRegisterNames[] = {
37#define REGISTER_NAME(R) #R,
38 FLOAT_REGISTERS(REGISTER_NAME)
39#undef REGISTER_NAME
40};
41
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042static const char* const kDoubleRegisterNames[] = {
43#define REGISTER_NAME(R) #R,
44 DOUBLE_REGISTERS(REGISTER_NAME)
45#undef REGISTER_NAME
46};
47
48STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
49 Register::kNumRegisters);
Ben Murdochc5610432016-08-08 18:44:38 +010050STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 DoubleRegister::kMaxNumRegisters);
52
Ben Murdoch61f157c2016-09-16 13:49:30 +010053enum CompilerSelector { CRANKSHAFT, TURBOFAN };
54
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
56 public:
57 explicit ArchDefaultRegisterConfiguration(CompilerSelector compiler)
Ben Murdoch61f157c2016-09-16 13:49:30 +010058 : RegisterConfiguration(
59 Register::kNumRegisters, DoubleRegister::kMaxNumRegisters,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060#if V8_TARGET_ARCH_IA32
Ben Murdoch61f157c2016-09-16 13:49:30 +010061 kMaxAllocatableGeneralRegisterCount,
62 kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063#elif V8_TARGET_ARCH_X87
Ben Murdoch61f157c2016-09-16 13:49:30 +010064 kMaxAllocatableGeneralRegisterCount,
65 compiler == TURBOFAN ? 1 : kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066#elif V8_TARGET_ARCH_X64
Ben Murdoch61f157c2016-09-16 13:49:30 +010067 kMaxAllocatableGeneralRegisterCount,
68 kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069#elif V8_TARGET_ARCH_ARM
Ben Murdoch61f157c2016-09-16 13:49:30 +010070 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),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076#elif V8_TARGET_ARCH_ARM64
Ben Murdoch61f157c2016-09-16 13:49:30 +010077 kMaxAllocatableGeneralRegisterCount,
78 kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079#elif V8_TARGET_ARCH_MIPS
Ben Murdoch61f157c2016-09-16 13:49:30 +010080 kMaxAllocatableGeneralRegisterCount,
81 kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082#elif V8_TARGET_ARCH_MIPS64
Ben Murdoch61f157c2016-09-16 13:49:30 +010083 kMaxAllocatableGeneralRegisterCount,
84 kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085#elif V8_TARGET_ARCH_PPC
Ben Murdoch61f157c2016-09-16 13:49:30 +010086 kMaxAllocatableGeneralRegisterCount,
87 kMaxAllocatableDoubleRegisterCount,
Ben Murdochda12d292016-06-02 14:46:10 +010088#elif V8_TARGET_ARCH_S390
Ben Murdoch61f157c2016-09-16 13:49:30 +010089 kMaxAllocatableGeneralRegisterCount,
90 kMaxAllocatableDoubleRegisterCount,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000091#else
92#error Unsupported target architecture.
93#endif
Ben Murdoch61f157c2016-09-16 13:49:30 +010094 kAllocatableGeneralCodes, kAllocatableDoubleCodes,
95 kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE,
96 kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 }
98};
99
Ben Murdoch61f157c2016-09-16 13:49:30 +0100100template <CompilerSelector compiler>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101struct RegisterConfigurationInitializer {
102 static void Construct(ArchDefaultRegisterConfiguration* config) {
103 new (config) ArchDefaultRegisterConfiguration(compiler);
104 }
105};
106
Ben Murdoch61f157c2016-09-16 13:49:30 +0100107static base::LazyInstance<ArchDefaultRegisterConfiguration,
108 RegisterConfigurationInitializer<CRANKSHAFT>>::type
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109 kDefaultRegisterConfigurationForCrankshaft = LAZY_INSTANCE_INITIALIZER;
110
Ben Murdoch61f157c2016-09-16 13:49:30 +0100111static base::LazyInstance<ArchDefaultRegisterConfiguration,
112 RegisterConfigurationInitializer<TURBOFAN>>::type
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113 kDefaultRegisterConfigurationForTurboFan = LAZY_INSTANCE_INITIALIZER;
114
115} // namespace
116
Ben Murdoch61f157c2016-09-16 13:49:30 +0100117const RegisterConfiguration* RegisterConfiguration::Crankshaft() {
118 return &kDefaultRegisterConfigurationForCrankshaft.Get();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119}
120
Ben Murdoch61f157c2016-09-16 13:49:30 +0100121const RegisterConfiguration* RegisterConfiguration::Turbofan() {
122 return &kDefaultRegisterConfigurationForTurboFan.Get();
123}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124
125RegisterConfiguration::RegisterConfiguration(
126 int num_general_registers, int num_double_registers,
127 int num_allocatable_general_registers, int num_allocatable_double_registers,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 const int* allocatable_general_codes, const int* allocatable_double_codes,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100129 AliasingKind fp_aliasing_kind, const char* const* general_register_names,
130 const char* const* float_register_names,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131 const char* const* double_register_names)
132 : num_general_registers_(num_general_registers),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100133 num_float_registers_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 num_double_registers_(num_double_registers),
135 num_allocatable_general_registers_(num_allocatable_general_registers),
136 num_allocatable_double_registers_(num_allocatable_double_registers),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100137 num_allocatable_float_registers_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 allocatable_general_codes_mask_(0),
139 allocatable_double_codes_mask_(0),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100140 allocatable_float_codes_mask_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 allocatable_general_codes_(allocatable_general_codes),
142 allocatable_double_codes_(allocatable_double_codes),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100143 fp_aliasing_kind_(fp_aliasing_kind),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144 general_register_names_(general_register_names),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100145 float_register_names_(float_register_names),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 double_register_names_(double_register_names) {
Ben Murdochc5610432016-08-08 18:44:38 +0100147 DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters);
148 DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149 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 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100155
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
180int 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
208bool 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;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230}
231
232#undef REGISTER_COUNT
233
234} // namespace internal
235} // namespace v8