LCOV - code coverage report
Current view: top level - src - register-configuration.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 59 59 100.0 %
Date: 2017-04-26 Functions: 6 6 100.0 %

          Line data    Source code
       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             : #define REGISTER_CODE(R) DoubleRegister::kCode_##R,
      26             : static const int kAllocatableDoubleCodes[] = {
      27             :     ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_CODE)};
      28             : #if V8_TARGET_ARCH_ARM
      29             : static const int kAllocatableNoVFP32DoubleCodes[] = {
      30             :     ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_CODE)};
      31             : #endif  // V8_TARGET_ARCH_ARM
      32             : #undef REGISTER_CODE
      33             : 
      34             : static const char* const kGeneralRegisterNames[] = {
      35             : #define REGISTER_NAME(R) #R,
      36             :     GENERAL_REGISTERS(REGISTER_NAME)
      37             : #undef REGISTER_NAME
      38             : };
      39             : 
      40             : static const char* const kFloatRegisterNames[] = {
      41             : #define REGISTER_NAME(R) #R,
      42             :     FLOAT_REGISTERS(REGISTER_NAME)
      43             : #undef REGISTER_NAME
      44             : };
      45             : 
      46             : static const char* const kDoubleRegisterNames[] = {
      47             : #define REGISTER_NAME(R) #R,
      48             :     DOUBLE_REGISTERS(REGISTER_NAME)
      49             : #undef REGISTER_NAME
      50             : };
      51             : 
      52             : static const char* const kSimd128RegisterNames[] = {
      53             : #define REGISTER_NAME(R) #R,
      54             :     SIMD128_REGISTERS(REGISTER_NAME)
      55             : #undef REGISTER_NAME
      56             : };
      57             : 
      58             : STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
      59             :               Register::kNumRegisters);
      60             : STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
      61             :               FloatRegister::kMaxNumRegisters);
      62             : STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
      63             :               DoubleRegister::kMaxNumRegisters);
      64             : STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
      65             :               Simd128Register::kMaxNumRegisters);
      66             : 
      67             : enum CompilerSelector { CRANKSHAFT, TURBOFAN };
      68             : 
      69             : class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
      70             :  public:
      71       89353 :   explicit ArchDefaultRegisterConfiguration(CompilerSelector compiler)
      72             :       : RegisterConfiguration(
      73             :             Register::kNumRegisters, DoubleRegister::kMaxNumRegisters,
      74             : #if V8_TARGET_ARCH_IA32
      75             :             kMaxAllocatableGeneralRegisterCount,
      76             :             kMaxAllocatableDoubleRegisterCount,
      77             : #elif V8_TARGET_ARCH_X87
      78             :             kMaxAllocatableGeneralRegisterCount,
      79             :             compiler == TURBOFAN ? 1 : kMaxAllocatableDoubleRegisterCount,
      80             : #elif V8_TARGET_ARCH_X64
      81             :             kMaxAllocatableGeneralRegisterCount,
      82             :             kMaxAllocatableDoubleRegisterCount,
      83             : #elif V8_TARGET_ARCH_ARM
      84             :             kMaxAllocatableGeneralRegisterCount,
      85             :             CpuFeatures::IsSupported(VFP32DREGS)
      86             :                 ? kMaxAllocatableDoubleRegisterCount
      87             :                 : (ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_COUNT) 0),
      88             : #elif V8_TARGET_ARCH_ARM64
      89             :             kMaxAllocatableGeneralRegisterCount,
      90             :             kMaxAllocatableDoubleRegisterCount,
      91             : #elif V8_TARGET_ARCH_MIPS
      92             :             kMaxAllocatableGeneralRegisterCount,
      93             :             kMaxAllocatableDoubleRegisterCount,
      94             : #elif V8_TARGET_ARCH_MIPS64
      95             :             kMaxAllocatableGeneralRegisterCount,
      96             :             kMaxAllocatableDoubleRegisterCount,
      97             : #elif V8_TARGET_ARCH_PPC
      98             :             kMaxAllocatableGeneralRegisterCount,
      99             :             kMaxAllocatableDoubleRegisterCount,
     100             : #elif V8_TARGET_ARCH_S390
     101             :             kMaxAllocatableGeneralRegisterCount,
     102             :             kMaxAllocatableDoubleRegisterCount,
     103             : #else
     104             : #error Unsupported target architecture.
     105             : #endif
     106             :             kAllocatableGeneralCodes,
     107             : #if V8_TARGET_ARCH_ARM
     108             :             CpuFeatures::IsSupported(VFP32DREGS)
     109             :                 ? kAllocatableDoubleCodes
     110             :                 : kAllocatableNoVFP32DoubleCodes,
     111             : #else
     112             :             kAllocatableDoubleCodes,
     113             : #endif
     114             :             kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE,
     115             :             kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames,
     116       89353 :             kSimd128RegisterNames) {
     117       89353 :   }
     118             : };
     119             : 
     120             : template <CompilerSelector compiler>
     121             : struct RegisterConfigurationInitializer {
     122             :   static void Construct(ArchDefaultRegisterConfiguration* config) {
     123       89353 :     new (config) ArchDefaultRegisterConfiguration(compiler);
     124             :   }
     125             : };
     126             : 
     127             : static base::LazyInstance<ArchDefaultRegisterConfiguration,
     128             :                           RegisterConfigurationInitializer<CRANKSHAFT>>::type
     129             :     kDefaultRegisterConfigurationForCrankshaft = LAZY_INSTANCE_INITIALIZER;
     130             : 
     131             : static base::LazyInstance<ArchDefaultRegisterConfiguration,
     132             :                           RegisterConfigurationInitializer<TURBOFAN>>::type
     133             :     kDefaultRegisterConfigurationForTurboFan = LAZY_INSTANCE_INITIALIZER;
     134             : 
     135             : }  // namespace
     136             : 
     137    74093911 : const RegisterConfiguration* RegisterConfiguration::Crankshaft() {
     138    74094050 :   return &kDefaultRegisterConfigurationForCrankshaft.Get();
     139             : }
     140             : 
     141     2815475 : const RegisterConfiguration* RegisterConfiguration::Turbofan() {
     142     2815485 :   return &kDefaultRegisterConfigurationForTurboFan.Get();
     143             : }
     144             : 
     145       89407 : RegisterConfiguration::RegisterConfiguration(
     146             :     int num_general_registers, int num_double_registers,
     147             :     int num_allocatable_general_registers, int num_allocatable_double_registers,
     148             :     const int* allocatable_general_codes, const int* allocatable_double_codes,
     149             :     AliasingKind fp_aliasing_kind, const char* const* general_register_names,
     150             :     const char* const* float_register_names,
     151             :     const char* const* double_register_names,
     152             :     const char* const* simd128_register_names)
     153             :     : num_general_registers_(num_general_registers),
     154             :       num_float_registers_(0),
     155             :       num_double_registers_(num_double_registers),
     156             :       num_simd128_registers_(0),
     157             :       num_allocatable_general_registers_(num_allocatable_general_registers),
     158             :       num_allocatable_float_registers_(0),
     159             :       num_allocatable_double_registers_(num_allocatable_double_registers),
     160             :       num_allocatable_simd128_registers_(0),
     161             :       allocatable_general_codes_mask_(0),
     162             :       allocatable_float_codes_mask_(0),
     163             :       allocatable_double_codes_mask_(0),
     164             :       allocatable_simd128_codes_mask_(0),
     165             :       allocatable_general_codes_(allocatable_general_codes),
     166             :       allocatable_double_codes_(allocatable_double_codes),
     167             :       fp_aliasing_kind_(fp_aliasing_kind),
     168             :       general_register_names_(general_register_names),
     169             :       float_register_names_(float_register_names),
     170             :       double_register_names_(double_register_names),
     171       89407 :       simd128_register_names_(simd128_register_names) {
     172             :   DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters);
     173             :   DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters);
     174     1162054 :   for (int i = 0; i < num_allocatable_general_registers_; ++i) {
     175     1072647 :     allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[i]);
     176             :   }
     177     1340707 :   for (int i = 0; i < num_allocatable_double_registers_; ++i) {
     178     1340707 :     allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[i]);
     179             :   }
     180             : 
     181       89407 :   if (fp_aliasing_kind_ == COMBINE) {
     182             :     num_float_registers_ = num_double_registers_ * 2 <= kMaxFPRegisters
     183           1 :                                ? num_double_registers_ * 2
     184           1 :                                : kMaxFPRegisters;
     185             :     num_allocatable_float_registers_ = 0;
     186           4 :     for (int i = 0; i < num_allocatable_double_registers_; i++) {
     187           3 :       int base_code = allocatable_double_codes_[i] * 2;
     188           3 :       if (base_code >= kMaxFPRegisters) continue;
     189           2 :       allocatable_float_codes_[num_allocatable_float_registers_++] = base_code;
     190           2 :       allocatable_float_codes_[num_allocatable_float_registers_++] =
     191           2 :           base_code + 1;
     192           2 :       allocatable_float_codes_mask_ |= (0x3 << base_code);
     193             :     }
     194           1 :     num_simd128_registers_ = num_double_registers_ / 2;
     195             :     num_allocatable_simd128_registers_ = 0;
     196           1 :     int last_simd128_code = allocatable_double_codes_[0] / 2;
     197           3 :     for (int i = 1; i < num_allocatable_double_registers_; i++) {
     198           2 :       int next_simd128_code = allocatable_double_codes_[i] / 2;
     199             :       // This scheme assumes allocatable_double_codes_ are strictly increasing.
     200             :       DCHECK_GE(next_simd128_code, last_simd128_code);
     201           2 :       if (last_simd128_code == next_simd128_code) {
     202           1 :         allocatable_simd128_codes_[num_allocatable_simd128_registers_++] =
     203           1 :             next_simd128_code;
     204           1 :         allocatable_simd128_codes_mask_ |= (0x1 << next_simd128_code);
     205             :       }
     206             :       last_simd128_code = next_simd128_code;
     207             :     }
     208             :   } else {
     209             :     DCHECK(fp_aliasing_kind_ == OVERLAP);
     210       89406 :     num_float_registers_ = num_simd128_registers_ = num_double_registers_;
     211             :     num_allocatable_float_registers_ = num_allocatable_simd128_registers_ =
     212       89406 :         num_allocatable_double_registers_;
     213     1430110 :     for (int i = 0; i < num_allocatable_float_registers_; ++i) {
     214             :       allocatable_float_codes_[i] = allocatable_simd128_codes_[i] =
     215     1340704 :           allocatable_double_codes_[i];
     216             :     }
     217             :     allocatable_float_codes_mask_ = allocatable_simd128_codes_mask_ =
     218       89406 :         allocatable_double_codes_mask_;
     219             :   }
     220       89407 : }
     221             : 
     222             : // Assert that kFloat32, kFloat64, and kSimd128 are consecutive values.
     223             : STATIC_ASSERT(static_cast<int>(MachineRepresentation::kSimd128) ==
     224             :               static_cast<int>(MachineRepresentation::kFloat64) + 1);
     225             : STATIC_ASSERT(static_cast<int>(MachineRepresentation::kFloat64) ==
     226             :               static_cast<int>(MachineRepresentation::kFloat32) + 1);
     227             : 
     228          12 : int RegisterConfiguration::GetAliases(MachineRepresentation rep, int index,
     229             :                                       MachineRepresentation other_rep,
     230             :                                       int* alias_base_index) const {
     231             :   DCHECK(fp_aliasing_kind_ == COMBINE);
     232             :   DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep));
     233          12 :   if (rep == other_rep) {
     234           2 :     *alias_base_index = index;
     235           2 :     return 1;
     236             :   }
     237             :   int rep_int = static_cast<int>(rep);
     238             :   int other_rep_int = static_cast<int>(other_rep);
     239          10 :   if (rep_int > other_rep_int) {
     240           6 :     int shift = rep_int - other_rep_int;
     241           6 :     int base_index = index << shift;
     242           6 :     if (base_index >= kMaxFPRegisters) {
     243             :       // Alias indices would be out of FP register range.
     244             :       return 0;
     245             :     }
     246           3 :     *alias_base_index = base_index;
     247           3 :     return 1 << shift;
     248             :   }
     249           4 :   int shift = other_rep_int - rep_int;
     250           4 :   *alias_base_index = index >> shift;
     251           4 :   return 1;
     252             : }
     253             : 
     254          34 : bool RegisterConfiguration::AreAliases(MachineRepresentation rep, int index,
     255             :                                        MachineRepresentation other_rep,
     256             :                                        int other_index) const {
     257             :   DCHECK(fp_aliasing_kind_ == COMBINE);
     258             :   DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep));
     259          34 :   if (rep == other_rep) {
     260           6 :     return index == other_index;
     261             :   }
     262             :   int rep_int = static_cast<int>(rep);
     263             :   int other_rep_int = static_cast<int>(other_rep);
     264          28 :   if (rep_int > other_rep_int) {
     265          16 :     int shift = rep_int - other_rep_int;
     266          16 :     return index == other_index >> shift;
     267             :   }
     268          12 :   int shift = other_rep_int - rep_int;
     269          12 :   return index >> shift == other_index;
     270             : }
     271             : 
     272             : #undef REGISTER_COUNT
     273             : 
     274             : }  // namespace internal
     275             : }  // namespace v8

Generated by: LCOV version 1.10