blob: 6b1655a81bb51a624fb6de11e71774057cc2686b [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
36static const char* const kDoubleRegisterNames[] = {
37#define REGISTER_NAME(R) #R,
38 DOUBLE_REGISTERS(REGISTER_NAME)
39#undef REGISTER_NAME
40};
41
42STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
43 Register::kNumRegisters);
44STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
45 DoubleRegister::kMaxNumRegisters);
46
47class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
48 public:
49 explicit ArchDefaultRegisterConfiguration(CompilerSelector compiler)
50 : RegisterConfiguration(Register::kNumRegisters,
51 DoubleRegister::kMaxNumRegisters,
52#if V8_TARGET_ARCH_IA32
53 kMaxAllocatableGeneralRegisterCount,
54 kMaxAllocatableDoubleRegisterCount,
55 kMaxAllocatableDoubleRegisterCount,
56#elif V8_TARGET_ARCH_X87
57 kMaxAllocatableGeneralRegisterCount,
58 compiler == TURBOFAN
59 ? 1
60 : kMaxAllocatableDoubleRegisterCount,
61 compiler == TURBOFAN
62 ? 1
63 : kMaxAllocatableDoubleRegisterCount,
64#elif V8_TARGET_ARCH_X64
65 kMaxAllocatableGeneralRegisterCount,
66 kMaxAllocatableDoubleRegisterCount,
67 kMaxAllocatableDoubleRegisterCount,
68#elif V8_TARGET_ARCH_ARM
69 FLAG_enable_embedded_constant_pool
70 ? (kMaxAllocatableGeneralRegisterCount - 1)
71 : kMaxAllocatableGeneralRegisterCount,
72 CpuFeatures::IsSupported(VFP32DREGS)
73 ? kMaxAllocatableDoubleRegisterCount
74 : (ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(
75 REGISTER_COUNT)0),
76 ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(
77 REGISTER_COUNT)0,
78#elif V8_TARGET_ARCH_ARM64
79 kMaxAllocatableGeneralRegisterCount,
80 kMaxAllocatableDoubleRegisterCount,
81 kMaxAllocatableDoubleRegisterCount,
82#elif V8_TARGET_ARCH_MIPS
83 kMaxAllocatableGeneralRegisterCount,
84 kMaxAllocatableDoubleRegisterCount,
85 kMaxAllocatableDoubleRegisterCount,
86#elif V8_TARGET_ARCH_MIPS64
87 kMaxAllocatableGeneralRegisterCount,
88 kMaxAllocatableDoubleRegisterCount,
89 kMaxAllocatableDoubleRegisterCount,
90#elif V8_TARGET_ARCH_PPC
91 kMaxAllocatableGeneralRegisterCount,
92 kMaxAllocatableDoubleRegisterCount,
93 kMaxAllocatableDoubleRegisterCount,
94#else
95#error Unsupported target architecture.
96#endif
97 kAllocatableGeneralCodes, kAllocatableDoubleCodes,
98 kGeneralRegisterNames, kDoubleRegisterNames) {
99 }
100};
101
102
103template <RegisterConfiguration::CompilerSelector compiler>
104struct RegisterConfigurationInitializer {
105 static void Construct(ArchDefaultRegisterConfiguration* config) {
106 new (config) ArchDefaultRegisterConfiguration(compiler);
107 }
108};
109
110static base::LazyInstance<
111 ArchDefaultRegisterConfiguration,
112 RegisterConfigurationInitializer<RegisterConfiguration::CRANKSHAFT>>::type
113 kDefaultRegisterConfigurationForCrankshaft = LAZY_INSTANCE_INITIALIZER;
114
115
116static base::LazyInstance<
117 ArchDefaultRegisterConfiguration,
118 RegisterConfigurationInitializer<RegisterConfiguration::TURBOFAN>>::type
119 kDefaultRegisterConfigurationForTurboFan = LAZY_INSTANCE_INITIALIZER;
120
121} // namespace
122
123
124const RegisterConfiguration* RegisterConfiguration::ArchDefault(
125 CompilerSelector compiler) {
126 return compiler == TURBOFAN
127 ? &kDefaultRegisterConfigurationForTurboFan.Get()
128 : &kDefaultRegisterConfigurationForCrankshaft.Get();
129}
130
131
132RegisterConfiguration::RegisterConfiguration(
133 int num_general_registers, int num_double_registers,
134 int num_allocatable_general_registers, int num_allocatable_double_registers,
135 int num_allocatable_aliased_double_registers,
136 const int* allocatable_general_codes, const int* allocatable_double_codes,
137 const char* const* general_register_names,
138 const char* const* double_register_names)
139 : num_general_registers_(num_general_registers),
140 num_double_registers_(num_double_registers),
141 num_allocatable_general_registers_(num_allocatable_general_registers),
142 num_allocatable_double_registers_(num_allocatable_double_registers),
143 num_allocatable_aliased_double_registers_(
144 num_allocatable_aliased_double_registers),
145 allocatable_general_codes_mask_(0),
146 allocatable_double_codes_mask_(0),
147 allocatable_general_codes_(allocatable_general_codes),
148 allocatable_double_codes_(allocatable_double_codes),
149 general_register_names_(general_register_names),
150 double_register_names_(double_register_names) {
151 for (int i = 0; i < num_allocatable_general_registers_; ++i) {
152 allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[i]);
153 }
154 for (int i = 0; i < num_allocatable_double_registers_; ++i) {
155 allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[i]);
156 }
157}
158
159#undef REGISTER_COUNT
160
161} // namespace internal
162} // namespace v8