| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/register-configuration.h" | 5 #include "src/register-configuration.h" |
| 6 #include "src/globals.h" | 6 #include "src/globals.h" |
| 7 #include "src/macro-assembler.h" | 7 #include "src/macro-assembler.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 FLOAT_REGISTERS(REGISTER_NAME) | 38 FLOAT_REGISTERS(REGISTER_NAME) |
| 39 #undef REGISTER_NAME | 39 #undef REGISTER_NAME |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 static const char* const kDoubleRegisterNames[] = { | 42 static const char* const kDoubleRegisterNames[] = { |
| 43 #define REGISTER_NAME(R) #R, | 43 #define REGISTER_NAME(R) #R, |
| 44 DOUBLE_REGISTERS(REGISTER_NAME) | 44 DOUBLE_REGISTERS(REGISTER_NAME) |
| 45 #undef REGISTER_NAME | 45 #undef REGISTER_NAME |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 static const char* const kSimd128RegisterNames[] = { |
| 49 #define REGISTER_NAME(R) #R, |
| 50 SIMD128_REGISTERS(REGISTER_NAME) |
| 51 #undef REGISTER_NAME |
| 52 }; |
| 53 |
| 48 STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >= | 54 STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >= |
| 49 Register::kNumRegisters); | 55 Register::kNumRegisters); |
| 50 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >= | 56 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >= |
| 57 FloatRegister::kMaxNumRegisters); |
| 58 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >= |
| 51 DoubleRegister::kMaxNumRegisters); | 59 DoubleRegister::kMaxNumRegisters); |
| 60 STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >= |
| 61 Simd128Register::kMaxNumRegisters); |
| 52 | 62 |
| 53 enum CompilerSelector { CRANKSHAFT, TURBOFAN }; | 63 enum CompilerSelector { CRANKSHAFT, TURBOFAN }; |
| 54 | 64 |
| 55 class ArchDefaultRegisterConfiguration : public RegisterConfiguration { | 65 class ArchDefaultRegisterConfiguration : public RegisterConfiguration { |
| 56 public: | 66 public: |
| 57 explicit ArchDefaultRegisterConfiguration(CompilerSelector compiler) | 67 explicit ArchDefaultRegisterConfiguration(CompilerSelector compiler) |
| 58 : RegisterConfiguration( | 68 : RegisterConfiguration( |
| 59 Register::kNumRegisters, DoubleRegister::kMaxNumRegisters, | 69 Register::kNumRegisters, DoubleRegister::kMaxNumRegisters, |
| 60 #if V8_TARGET_ARCH_IA32 | 70 #if V8_TARGET_ARCH_IA32 |
| 61 kMaxAllocatableGeneralRegisterCount, | 71 kMaxAllocatableGeneralRegisterCount, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 86 kMaxAllocatableGeneralRegisterCount, | 96 kMaxAllocatableGeneralRegisterCount, |
| 87 kMaxAllocatableDoubleRegisterCount, | 97 kMaxAllocatableDoubleRegisterCount, |
| 88 #elif V8_TARGET_ARCH_S390 | 98 #elif V8_TARGET_ARCH_S390 |
| 89 kMaxAllocatableGeneralRegisterCount, | 99 kMaxAllocatableGeneralRegisterCount, |
| 90 kMaxAllocatableDoubleRegisterCount, | 100 kMaxAllocatableDoubleRegisterCount, |
| 91 #else | 101 #else |
| 92 #error Unsupported target architecture. | 102 #error Unsupported target architecture. |
| 93 #endif | 103 #endif |
| 94 kAllocatableGeneralCodes, kAllocatableDoubleCodes, | 104 kAllocatableGeneralCodes, kAllocatableDoubleCodes, |
| 95 kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE, | 105 kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE, |
| 96 kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames) { | 106 kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames, |
| 107 kSimd128RegisterNames) { |
| 97 } | 108 } |
| 98 }; | 109 }; |
| 99 | 110 |
| 100 template <CompilerSelector compiler> | 111 template <CompilerSelector compiler> |
| 101 struct RegisterConfigurationInitializer { | 112 struct RegisterConfigurationInitializer { |
| 102 static void Construct(ArchDefaultRegisterConfiguration* config) { | 113 static void Construct(ArchDefaultRegisterConfiguration* config) { |
| 103 new (config) ArchDefaultRegisterConfiguration(compiler); | 114 new (config) ArchDefaultRegisterConfiguration(compiler); |
| 104 } | 115 } |
| 105 }; | 116 }; |
| 106 | 117 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 121 const RegisterConfiguration* RegisterConfiguration::Turbofan() { | 132 const RegisterConfiguration* RegisterConfiguration::Turbofan() { |
| 122 return &kDefaultRegisterConfigurationForTurboFan.Get(); | 133 return &kDefaultRegisterConfigurationForTurboFan.Get(); |
| 123 } | 134 } |
| 124 | 135 |
| 125 RegisterConfiguration::RegisterConfiguration( | 136 RegisterConfiguration::RegisterConfiguration( |
| 126 int num_general_registers, int num_double_registers, | 137 int num_general_registers, int num_double_registers, |
| 127 int num_allocatable_general_registers, int num_allocatable_double_registers, | 138 int num_allocatable_general_registers, int num_allocatable_double_registers, |
| 128 const int* allocatable_general_codes, const int* allocatable_double_codes, | 139 const int* allocatable_general_codes, const int* allocatable_double_codes, |
| 129 AliasingKind fp_aliasing_kind, const char* const* general_register_names, | 140 AliasingKind fp_aliasing_kind, const char* const* general_register_names, |
| 130 const char* const* float_register_names, | 141 const char* const* float_register_names, |
| 131 const char* const* double_register_names) | 142 const char* const* double_register_names, |
| 143 const char* const* simd128_register_names) |
| 132 : num_general_registers_(num_general_registers), | 144 : num_general_registers_(num_general_registers), |
| 133 num_float_registers_(0), | 145 num_float_registers_(0), |
| 134 num_double_registers_(num_double_registers), | 146 num_double_registers_(num_double_registers), |
| 147 num_simd128_registers_(0), |
| 135 num_allocatable_general_registers_(num_allocatable_general_registers), | 148 num_allocatable_general_registers_(num_allocatable_general_registers), |
| 149 num_allocatable_float_registers_(0), |
| 136 num_allocatable_double_registers_(num_allocatable_double_registers), | 150 num_allocatable_double_registers_(num_allocatable_double_registers), |
| 137 num_allocatable_float_registers_(0), | 151 num_allocatable_simd128_registers_(0), |
| 138 allocatable_general_codes_mask_(0), | 152 allocatable_general_codes_mask_(0), |
| 153 allocatable_float_codes_mask_(0), |
| 139 allocatable_double_codes_mask_(0), | 154 allocatable_double_codes_mask_(0), |
| 140 allocatable_float_codes_mask_(0), | 155 allocatable_simd128_codes_mask_(0), |
| 141 allocatable_general_codes_(allocatable_general_codes), | 156 allocatable_general_codes_(allocatable_general_codes), |
| 142 allocatable_double_codes_(allocatable_double_codes), | 157 allocatable_double_codes_(allocatable_double_codes), |
| 143 fp_aliasing_kind_(fp_aliasing_kind), | 158 fp_aliasing_kind_(fp_aliasing_kind), |
| 144 general_register_names_(general_register_names), | 159 general_register_names_(general_register_names), |
| 145 float_register_names_(float_register_names), | 160 float_register_names_(float_register_names), |
| 146 double_register_names_(double_register_names) { | 161 double_register_names_(double_register_names), |
| 162 simd128_register_names_(simd128_register_names) { |
| 147 DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters); | 163 DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters); |
| 148 DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters); | 164 DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters); |
| 149 for (int i = 0; i < num_allocatable_general_registers_; ++i) { | 165 for (int i = 0; i < num_allocatable_general_registers_; ++i) { |
| 150 allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[i]); | 166 allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[i]); |
| 151 } | 167 } |
| 152 for (int i = 0; i < num_allocatable_double_registers_; ++i) { | 168 for (int i = 0; i < num_allocatable_double_registers_; ++i) { |
| 153 allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[i]); | 169 allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[i]); |
| 154 } | 170 } |
| 155 | 171 |
| 156 if (fp_aliasing_kind_ == COMBINE) { | 172 if (fp_aliasing_kind_ == COMBINE) { |
| 157 num_float_registers_ = num_double_registers_ * 2 <= kMaxFPRegisters | 173 num_float_registers_ = num_double_registers_ * 2 <= kMaxFPRegisters |
| 158 ? num_double_registers_ * 2 | 174 ? num_double_registers_ * 2 |
| 159 : kMaxFPRegisters; | 175 : kMaxFPRegisters; |
| 160 num_allocatable_float_registers_ = 0; | 176 num_allocatable_float_registers_ = 0; |
| 161 for (int i = 0; i < num_allocatable_double_registers_; i++) { | 177 for (int i = 0; i < num_allocatable_double_registers_; i++) { |
| 162 int base_code = allocatable_double_codes_[i] * 2; | 178 int base_code = allocatable_double_codes_[i] * 2; |
| 163 if (base_code >= kMaxFPRegisters) continue; | 179 if (base_code >= kMaxFPRegisters) continue; |
| 164 allocatable_float_codes_[num_allocatable_float_registers_++] = base_code; | 180 allocatable_float_codes_[num_allocatable_float_registers_++] = base_code; |
| 165 allocatable_float_codes_[num_allocatable_float_registers_++] = | 181 allocatable_float_codes_[num_allocatable_float_registers_++] = |
| 166 base_code + 1; | 182 base_code + 1; |
| 167 allocatable_float_codes_mask_ |= (0x3 << base_code); | 183 allocatable_float_codes_mask_ |= (0x3 << base_code); |
| 168 } | 184 } |
| 185 num_simd128_registers_ = num_double_registers_ / 2; |
| 186 num_allocatable_simd128_registers_ = 0; |
| 187 int last_simd128_code = allocatable_double_codes_[0] / 2; |
| 188 for (int i = 1; i < num_allocatable_double_registers_; i++) { |
| 189 int next_simd128_code = allocatable_double_codes_[i] / 2; |
| 190 // This scheme assumes allocatable_double_codes_ are strictly increasing. |
| 191 DCHECK_GE(next_simd128_code, last_simd128_code); |
| 192 if (last_simd128_code == next_simd128_code) { |
| 193 allocatable_simd128_codes_[num_allocatable_simd128_registers_++] = |
| 194 next_simd128_code; |
| 195 allocatable_simd128_codes_mask_ |= (0x1 << next_simd128_code); |
| 196 } |
| 197 last_simd128_code = next_simd128_code; |
| 198 } |
| 169 } else { | 199 } else { |
| 170 DCHECK(fp_aliasing_kind_ == OVERLAP); | 200 DCHECK(fp_aliasing_kind_ == OVERLAP); |
| 171 num_float_registers_ = num_double_registers_; | 201 num_float_registers_ = num_simd128_registers_ = num_double_registers_; |
| 172 num_allocatable_float_registers_ = num_allocatable_double_registers_; | 202 num_allocatable_float_registers_ = num_allocatable_simd128_registers_ = |
| 203 num_allocatable_double_registers_; |
| 173 for (int i = 0; i < num_allocatable_float_registers_; ++i) { | 204 for (int i = 0; i < num_allocatable_float_registers_; ++i) { |
| 174 allocatable_float_codes_[i] = allocatable_double_codes_[i]; | 205 allocatable_float_codes_[i] = allocatable_simd128_codes_[i] = |
| 206 allocatable_double_codes_[i]; |
| 175 } | 207 } |
| 176 allocatable_float_codes_mask_ = allocatable_double_codes_mask_; | 208 allocatable_float_codes_mask_ = allocatable_simd128_codes_mask_ = |
| 209 allocatable_double_codes_mask_; |
| 177 } | 210 } |
| 178 } | 211 } |
| 179 | 212 |
| 213 // Assert that kFloat32, kFloat64, and kSimd128 are consecutive values. |
| 214 STATIC_ASSERT(static_cast<int>(MachineRepresentation::kSimd128) == |
| 215 static_cast<int>(MachineRepresentation::kFloat64) + 1); |
| 216 STATIC_ASSERT(static_cast<int>(MachineRepresentation::kFloat64) == |
| 217 static_cast<int>(MachineRepresentation::kFloat32) + 1); |
| 218 |
| 180 int RegisterConfiguration::GetAliases(MachineRepresentation rep, int index, | 219 int RegisterConfiguration::GetAliases(MachineRepresentation rep, int index, |
| 181 MachineRepresentation other_rep, | 220 MachineRepresentation other_rep, |
| 182 int* alias_base_index) const { | 221 int* alias_base_index) const { |
| 183 DCHECK(fp_aliasing_kind_ == COMBINE); | 222 DCHECK(fp_aliasing_kind_ == COMBINE); |
| 184 DCHECK(rep == MachineRepresentation::kFloat32 || | 223 DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep)); |
| 185 rep == MachineRepresentation::kFloat64); | |
| 186 DCHECK(other_rep == MachineRepresentation::kFloat32 || | |
| 187 other_rep == MachineRepresentation::kFloat64); | |
| 188 if (rep == other_rep) { | 224 if (rep == other_rep) { |
| 189 *alias_base_index = index; | 225 *alias_base_index = index; |
| 190 return 1; | 226 return 1; |
| 191 } | 227 } |
| 192 if (rep == MachineRepresentation::kFloat32) { | 228 int rep_int = static_cast<int>(rep); |
| 193 DCHECK(other_rep == MachineRepresentation::kFloat64); | 229 int other_rep_int = static_cast<int>(other_rep); |
| 194 DCHECK(index < num_allocatable_float_registers_); | 230 if (rep_int > other_rep_int) { |
| 195 *alias_base_index = index / 2; | 231 int shift = rep_int - other_rep_int; |
| 196 return 1; | 232 int base_index = index << shift; |
| 233 if (base_index >= kMaxFPRegisters) { |
| 234 // Alias indices would be out of FP register range. |
| 235 return 0; |
| 236 } |
| 237 *alias_base_index = base_index; |
| 238 return 1 << shift; |
| 197 } | 239 } |
| 198 DCHECK(rep == MachineRepresentation::kFloat64); | 240 int shift = other_rep_int - rep_int; |
| 199 DCHECK(other_rep == MachineRepresentation::kFloat32); | 241 *alias_base_index = index >> shift; |
| 200 if (index * 2 >= kMaxFPRegisters) { | 242 return 1; |
| 201 // Alias indices are out of float register range. | |
| 202 return 0; | |
| 203 } | |
| 204 *alias_base_index = index * 2; | |
| 205 return 2; | |
| 206 } | 243 } |
| 207 | 244 |
| 208 bool RegisterConfiguration::AreAliases(MachineRepresentation rep, int index, | 245 bool RegisterConfiguration::AreAliases(MachineRepresentation rep, int index, |
| 209 MachineRepresentation other_rep, | 246 MachineRepresentation other_rep, |
| 210 int other_index) const { | 247 int other_index) const { |
| 211 DCHECK(fp_aliasing_kind_ == COMBINE); | 248 DCHECK(fp_aliasing_kind_ == COMBINE); |
| 212 DCHECK(rep == MachineRepresentation::kFloat32 || | 249 DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep)); |
| 213 rep == MachineRepresentation::kFloat64); | |
| 214 DCHECK(other_rep == MachineRepresentation::kFloat32 || | |
| 215 other_rep == MachineRepresentation::kFloat64); | |
| 216 if (rep == other_rep) { | 250 if (rep == other_rep) { |
| 217 return index == other_index; | 251 return index == other_index; |
| 218 } | 252 } |
| 219 if (rep == MachineRepresentation::kFloat32) { | 253 int rep_int = static_cast<int>(rep); |
| 220 DCHECK(other_rep == MachineRepresentation::kFloat64); | 254 int other_rep_int = static_cast<int>(other_rep); |
| 221 return index / 2 == other_index; | 255 if (rep_int > other_rep_int) { |
| 256 int shift = rep_int - other_rep_int; |
| 257 return index == other_index >> shift; |
| 222 } | 258 } |
| 223 DCHECK(rep == MachineRepresentation::kFloat64); | 259 int shift = other_rep_int - rep_int; |
| 224 DCHECK(other_rep == MachineRepresentation::kFloat32); | 260 return index >> shift == other_index; |
| 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 } | 261 } |
| 231 | 262 |
| 232 #undef REGISTER_COUNT | 263 #undef REGISTER_COUNT |
| 233 | 264 |
| 234 } // namespace internal | 265 } // namespace internal |
| 235 } // namespace v8 | 266 } // namespace v8 |
| OLD | NEW |