Home | History | Annotate | Download | only in src
      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