5 #include "src/register-configuration.h" 6 #include "src/globals.h" 7 #include "src/macro-assembler.h" 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;
20 static const int kAllocatableGeneralCodes[] = {
21 #define REGISTER_CODE(R) kRegCode_##R, 22 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_CODE)};
25 #define REGISTER_CODE(R) kDoubleCode_##R, 26 static const int kAllocatableDoubleCodes[] = {
27 ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_CODE)};
28 #if V8_TARGET_ARCH_ARM 29 static const int kAllocatableNoVFP32DoubleCodes[] = {
30 ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_CODE)};
31 #endif // V8_TARGET_ARCH_ARM 34 STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
35 Register::kNumRegisters);
36 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
37 FloatRegister::kNumRegisters);
38 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
39 DoubleRegister::kNumRegisters);
40 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
41 Simd128Register::kNumRegisters);
43 static int get_num_allocatable_double_registers() {
45 #if V8_TARGET_ARCH_IA32 46 kMaxAllocatableDoubleRegisterCount;
47 #elif V8_TARGET_ARCH_X64 48 kMaxAllocatableDoubleRegisterCount;
49 #elif V8_TARGET_ARCH_ARM 50 CpuFeatures::IsSupported(VFP32DREGS)
51 ? kMaxAllocatableDoubleRegisterCount
52 : (ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_COUNT) 0);
53 #elif V8_TARGET_ARCH_ARM64 54 kMaxAllocatableDoubleRegisterCount;
55 #elif V8_TARGET_ARCH_MIPS 56 kMaxAllocatableDoubleRegisterCount;
57 #elif V8_TARGET_ARCH_MIPS64 58 kMaxAllocatableDoubleRegisterCount;
59 #elif V8_TARGET_ARCH_PPC 60 kMaxAllocatableDoubleRegisterCount;
61 #elif V8_TARGET_ARCH_S390 62 kMaxAllocatableDoubleRegisterCount;
64 #error Unsupported target architecture. 70 static const int* get_allocatable_double_codes() {
72 #if V8_TARGET_ARCH_ARM 73 CpuFeatures::IsSupported(VFP32DREGS) ? kAllocatableDoubleCodes
74 : kAllocatableNoVFP32DoubleCodes;
76 kAllocatableDoubleCodes;
80 class ArchDefaultRegisterConfiguration :
public RegisterConfiguration {
82 ArchDefaultRegisterConfiguration()
83 : RegisterConfiguration(
84 Register::kNumRegisters, DoubleRegister::kNumRegisters,
85 kMaxAllocatableGeneralRegisterCount,
86 get_num_allocatable_double_registers(), kAllocatableGeneralCodes,
87 get_allocatable_double_codes(),
88 kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE) {
92 struct RegisterConfigurationInitializer {
93 static void Construct(
void* config) {
94 new (config) ArchDefaultRegisterConfiguration();
98 static base::LazyInstance<ArchDefaultRegisterConfiguration,
99 RegisterConfigurationInitializer>::type
100 kDefaultRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
103 class ArchDefaultPoisoningRegisterConfiguration :
public RegisterConfiguration {
105 ArchDefaultPoisoningRegisterConfiguration()
106 : RegisterConfiguration(
107 Register::kNumRegisters, DoubleRegister::kNumRegisters,
108 kMaxAllocatableGeneralRegisterCount - 1,
109 get_num_allocatable_double_registers(),
110 InitializeGeneralRegisterCodes(), get_allocatable_double_codes(),
111 kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE) {
115 static const int* InitializeGeneralRegisterCodes() {
116 int filtered_index = 0;
117 for (
int i = 0;
i < kMaxAllocatableGeneralRegisterCount; ++
i) {
118 if (kAllocatableGeneralCodes[
i] != kSpeculationPoisonRegister.code()) {
119 allocatable_general_codes_[filtered_index] =
120 kAllocatableGeneralCodes[
i];
124 DCHECK_EQ(filtered_index, kMaxAllocatableGeneralRegisterCount - 1);
125 return allocatable_general_codes_;
129 allocatable_general_codes_[kMaxAllocatableGeneralRegisterCount - 1];
132 int ArchDefaultPoisoningRegisterConfiguration::allocatable_general_codes_
133 [kMaxAllocatableGeneralRegisterCount - 1];
135 struct PoisoningRegisterConfigurationInitializer {
136 static void Construct(
void* config) {
137 new (config) ArchDefaultPoisoningRegisterConfiguration();
141 static base::LazyInstance<ArchDefaultPoisoningRegisterConfiguration,
142 PoisoningRegisterConfigurationInitializer>::type
143 kDefaultPoisoningRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
148 class RestrictedRegisterConfiguration :
public RegisterConfiguration {
150 RestrictedRegisterConfiguration(
151 int num_allocatable_general_registers,
152 std::unique_ptr<
int[]> allocatable_general_register_codes,
153 std::unique_ptr<
char const* []> allocatable_general_register_names)
154 : RegisterConfiguration(
155 Register::kNumRegisters, DoubleRegister::kNumRegisters,
156 num_allocatable_general_registers,
157 get_num_allocatable_double_registers(),
158 allocatable_general_register_codes.get(),
159 get_allocatable_double_codes(),
160 kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE),
161 allocatable_general_register_codes_(
162 std::move(allocatable_general_register_codes)),
163 allocatable_general_register_names_(
164 std::move(allocatable_general_register_names)) {
165 for (
int i = 0;
i < num_allocatable_general_registers; ++
i) {
167 IsAllocatableGeneralRegister(allocatable_general_register_codes_[
i]));
171 bool IsAllocatableGeneralRegister(
int code) {
172 for (
int i = 0;
i < kMaxAllocatableGeneralRegisterCount; ++
i) {
173 if (code == kAllocatableGeneralCodes[
i]) {
181 std::unique_ptr<int[]> allocatable_general_register_codes_;
182 std::unique_ptr<char const* []> allocatable_general_register_names_;
187 const RegisterConfiguration* RegisterConfiguration::Default() {
188 return &kDefaultRegisterConfiguration.Get();
191 const RegisterConfiguration* RegisterConfiguration::Poisoning() {
192 return &kDefaultPoisoningRegisterConfiguration.Get();
195 const RegisterConfiguration* RegisterConfiguration::RestrictGeneralRegisters(
197 int num = NumRegs(registers);
198 std::unique_ptr<int[]> codes{
new int[num]};
199 std::unique_ptr<char const* []> names {
new char const*[num] };
201 for (
int i = 0;
i < Default()->num_allocatable_general_registers(); ++
i) {
202 auto reg = Register::from_code(Default()->GetAllocatableGeneralCode(
i));
203 if (reg.bit() & registers) {
204 DCHECK(counter < num);
205 codes[counter] = reg.code();
206 names[counter] = RegisterName(Register::from_code(
i));
211 return new RestrictedRegisterConfiguration(num, std::move(codes),
215 RegisterConfiguration::RegisterConfiguration(
216 int num_general_registers,
int num_double_registers,
217 int num_allocatable_general_registers,
int num_allocatable_double_registers,
218 const int* allocatable_general_codes,
const int* allocatable_double_codes,
219 AliasingKind fp_aliasing_kind)
220 : num_general_registers_(num_general_registers),
221 num_float_registers_(0),
222 num_double_registers_(num_double_registers),
223 num_simd128_registers_(0),
224 num_allocatable_general_registers_(num_allocatable_general_registers),
225 num_allocatable_float_registers_(0),
226 num_allocatable_double_registers_(num_allocatable_double_registers),
227 num_allocatable_simd128_registers_(0),
228 allocatable_general_codes_mask_(0),
229 allocatable_float_codes_mask_(0),
230 allocatable_double_codes_mask_(0),
231 allocatable_simd128_codes_mask_(0),
232 allocatable_general_codes_(allocatable_general_codes),
233 allocatable_double_codes_(allocatable_double_codes),
234 fp_aliasing_kind_(fp_aliasing_kind) {
235 DCHECK_LE(num_general_registers_,
236 RegisterConfiguration::kMaxGeneralRegisters);
237 DCHECK_LE(num_double_registers_, RegisterConfiguration::kMaxFPRegisters);
238 for (
int i = 0;
i < num_allocatable_general_registers_; ++
i) {
239 allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[
i]);
241 for (
int i = 0;
i < num_allocatable_double_registers_; ++
i) {
242 allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[
i]);
245 if (fp_aliasing_kind_ == COMBINE) {
246 num_float_registers_ = num_double_registers_ * 2 <= kMaxFPRegisters
247 ? num_double_registers_ * 2
249 num_allocatable_float_registers_ = 0;
250 for (
int i = 0;
i < num_allocatable_double_registers_;
i++) {
251 int base_code = allocatable_double_codes_[
i] * 2;
252 if (base_code >= kMaxFPRegisters)
continue;
253 allocatable_float_codes_[num_allocatable_float_registers_++] = base_code;
254 allocatable_float_codes_[num_allocatable_float_registers_++] =
256 allocatable_float_codes_mask_ |= (0x3 << base_code);
258 num_simd128_registers_ = num_double_registers_ / 2;
259 num_allocatable_simd128_registers_ = 0;
260 int last_simd128_code = allocatable_double_codes_[0] / 2;
261 for (
int i = 1;
i < num_allocatable_double_registers_;
i++) {
262 int next_simd128_code = allocatable_double_codes_[
i] / 2;
264 DCHECK_GE(next_simd128_code, last_simd128_code);
265 if (last_simd128_code == next_simd128_code) {
266 allocatable_simd128_codes_[num_allocatable_simd128_registers_++] =
268 allocatable_simd128_codes_mask_ |= (0x1 << next_simd128_code);
270 last_simd128_code = next_simd128_code;
273 DCHECK(fp_aliasing_kind_ == OVERLAP);
274 num_float_registers_ = num_simd128_registers_ = num_double_registers_;
275 num_allocatable_float_registers_ = num_allocatable_simd128_registers_ =
276 num_allocatable_double_registers_;
277 for (
int i = 0;
i < num_allocatable_float_registers_; ++
i) {
278 allocatable_float_codes_[
i] = allocatable_simd128_codes_[
i] =
279 allocatable_double_codes_[
i];
281 allocatable_float_codes_mask_ = allocatable_simd128_codes_mask_ =
282 allocatable_double_codes_mask_;
287 STATIC_ASSERT(static_cast<int>(MachineRepresentation::kSimd128) ==
288 static_cast<int>(MachineRepresentation::kFloat64) + 1);
289 STATIC_ASSERT(static_cast<int>(MachineRepresentation::kFloat64) ==
290 static_cast<int>(MachineRepresentation::kFloat32) + 1);
292 int RegisterConfiguration::GetAliases(MachineRepresentation rep,
int index,
293 MachineRepresentation other_rep,
294 int* alias_base_index)
const {
295 DCHECK(fp_aliasing_kind_ == COMBINE);
296 DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep));
297 if (rep == other_rep) {
298 *alias_base_index = index;
301 int rep_int =
static_cast<int>(rep);
302 int other_rep_int =
static_cast<int>(other_rep);
303 if (rep_int > other_rep_int) {
304 int shift = rep_int - other_rep_int;
305 int base_index = index << shift;
306 if (base_index >= kMaxFPRegisters) {
310 *alias_base_index = base_index;
313 int shift = other_rep_int - rep_int;
314 *alias_base_index = index >> shift;
318 bool RegisterConfiguration::AreAliases(MachineRepresentation rep,
int index,
319 MachineRepresentation other_rep,
320 int other_index)
const {
321 DCHECK(fp_aliasing_kind_ == COMBINE);
322 DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep));
323 if (rep == other_rep) {
324 return index == other_index;
326 int rep_int =
static_cast<int>(rep);
327 int other_rep_int =
static_cast<int>(other_rep);
328 if (rep_int > other_rep_int) {
329 int shift = rep_int - other_rep_int;
330 return index == other_index >> shift;
332 int shift = other_rep_int - rep_int;
333 return index >> shift == other_index;