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 kDoubleRegisterNames[] = {
37 #define REGISTER_NAME(R) #R,
38 DOUBLE_REGISTERS(REGISTER_NAME)
39 #undef REGISTER_NAME
40 };
41
42 STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
43 Register::kNumRegisters);
44 STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
45 DoubleRegister::kMaxNumRegisters);
46
47 class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
48 public:
ArchDefaultRegisterConfiguration(CompilerSelector compiler)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
103 template <RegisterConfiguration::CompilerSelector compiler>
104 struct RegisterConfigurationInitializer {
Constructv8::internal::__anon9047172f0111::RegisterConfigurationInitializer105 static void Construct(ArchDefaultRegisterConfiguration* config) {
106 new (config) ArchDefaultRegisterConfiguration(compiler);
107 }
108 };
109
110 static base::LazyInstance<
111 ArchDefaultRegisterConfiguration,
112 RegisterConfigurationInitializer<RegisterConfiguration::CRANKSHAFT>>::type
113 kDefaultRegisterConfigurationForCrankshaft = LAZY_INSTANCE_INITIALIZER;
114
115
116 static base::LazyInstance<
117 ArchDefaultRegisterConfiguration,
118 RegisterConfigurationInitializer<RegisterConfiguration::TURBOFAN>>::type
119 kDefaultRegisterConfigurationForTurboFan = LAZY_INSTANCE_INITIALIZER;
120
121 } // namespace
122
123
ArchDefault(CompilerSelector compiler)124 const RegisterConfiguration* RegisterConfiguration::ArchDefault(
125 CompilerSelector compiler) {
126 return compiler == TURBOFAN
127 ? &kDefaultRegisterConfigurationForTurboFan.Get()
128 : &kDefaultRegisterConfigurationForCrankshaft.Get();
129 }
130
131
RegisterConfiguration(int num_general_registers,int num_double_registers,int num_allocatable_general_registers,int num_allocatable_double_registers,int num_allocatable_aliased_double_registers,const int * allocatable_general_codes,const int * allocatable_double_codes,const char * const * general_register_names,const char * const * double_register_names)132 RegisterConfiguration::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
163