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: 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 { 105 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 124 const RegisterConfiguration* RegisterConfiguration::ArchDefault( 125 CompilerSelector compiler) { 126 return compiler == TURBOFAN 127 ? &kDefaultRegisterConfigurationForTurboFan.Get() 128 : &kDefaultRegisterConfigurationForCrankshaft.Get(); 129 } 130 131 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