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 #ifndef V8_CODEGEN_REGISTER_CONFIGURATION_H_ 6 #define V8_CODEGEN_REGISTER_CONFIGURATION_H_ 7 8 #include "src/base/macros.h" 9 #include "src/codegen/machine-type.h" 10 #include "src/codegen/reglist.h" 11 #include "src/common/globals.h" 12 #include "src/utils/utils.h" 13 14 namespace v8 { 15 namespace internal { 16 17 // An architecture independent representation of the sets of registers available 18 // for instruction creation. 19 class V8_EXPORT_PRIVATE RegisterConfiguration { 20 public: 21 enum AliasingKind { 22 // Registers alias a single register of every other size (e.g. Intel). 23 OVERLAP, 24 // Registers alias two registers of the next smaller size (e.g. ARM). 25 COMBINE 26 }; 27 28 // Architecture independent maxes. 29 static constexpr int kMaxGeneralRegisters = 32; 30 static constexpr int kMaxFPRegisters = 32; 31 static constexpr int kMaxRegisters = 32 std::max(kMaxFPRegisters, kMaxGeneralRegisters); 33 34 // Default RegisterConfigurations for the target architecture. 35 static const RegisterConfiguration* Default(); 36 37 // Register configuration with reserved masking register. 38 static const RegisterConfiguration* Poisoning(); 39 40 static const RegisterConfiguration* RestrictGeneralRegisters( 41 RegList registers); 42 43 RegisterConfiguration(int num_general_registers, int num_double_registers, 44 int num_allocatable_general_registers, 45 int num_allocatable_double_registers, 46 const int* allocatable_general_codes, 47 const int* allocatable_double_codes, 48 AliasingKind fp_aliasing_kind); 49 num_general_registers()50 int num_general_registers() const { return num_general_registers_; } num_float_registers()51 int num_float_registers() const { return num_float_registers_; } num_double_registers()52 int num_double_registers() const { return num_double_registers_; } num_simd128_registers()53 int num_simd128_registers() const { return num_simd128_registers_; } num_allocatable_general_registers()54 int num_allocatable_general_registers() const { 55 return num_allocatable_general_registers_; 56 } num_allocatable_float_registers()57 int num_allocatable_float_registers() const { 58 return num_allocatable_float_registers_; 59 } 60 // Caution: this value depends on the current cpu and may change between 61 // build and runtime. At the time of writing, the only architecture with a 62 // variable allocatable double register set is Arm. num_allocatable_double_registers()63 int num_allocatable_double_registers() const { 64 return num_allocatable_double_registers_; 65 } num_allocatable_simd128_registers()66 int num_allocatable_simd128_registers() const { 67 return num_allocatable_simd128_registers_; 68 } fp_aliasing_kind()69 AliasingKind fp_aliasing_kind() const { return fp_aliasing_kind_; } allocatable_general_codes_mask()70 int32_t allocatable_general_codes_mask() const { 71 return allocatable_general_codes_mask_; 72 } allocatable_double_codes_mask()73 int32_t allocatable_double_codes_mask() const { 74 return allocatable_double_codes_mask_; 75 } allocatable_float_codes_mask()76 int32_t allocatable_float_codes_mask() const { 77 return allocatable_float_codes_mask_; 78 } GetAllocatableGeneralCode(int index)79 int GetAllocatableGeneralCode(int index) const { 80 DCHECK(index >= 0 && index < num_allocatable_general_registers()); 81 return allocatable_general_codes_[index]; 82 } IsAllocatableGeneralCode(int index)83 bool IsAllocatableGeneralCode(int index) const { 84 return ((1 << index) & allocatable_general_codes_mask_) != 0; 85 } GetAllocatableFloatCode(int index)86 int GetAllocatableFloatCode(int index) const { 87 DCHECK(index >= 0 && index < num_allocatable_float_registers()); 88 return allocatable_float_codes_[index]; 89 } IsAllocatableFloatCode(int index)90 bool IsAllocatableFloatCode(int index) const { 91 return ((1 << index) & allocatable_float_codes_mask_) != 0; 92 } GetAllocatableDoubleCode(int index)93 int GetAllocatableDoubleCode(int index) const { 94 DCHECK(index >= 0 && index < num_allocatable_double_registers()); 95 return allocatable_double_codes_[index]; 96 } IsAllocatableDoubleCode(int index)97 bool IsAllocatableDoubleCode(int index) const { 98 return ((1 << index) & allocatable_double_codes_mask_) != 0; 99 } GetAllocatableSimd128Code(int index)100 int GetAllocatableSimd128Code(int index) const { 101 DCHECK(index >= 0 && index < num_allocatable_simd128_registers()); 102 return allocatable_simd128_codes_[index]; 103 } IsAllocatableSimd128Code(int index)104 bool IsAllocatableSimd128Code(int index) const { 105 return ((1 << index) & allocatable_simd128_codes_mask_) != 0; 106 } 107 allocatable_general_codes()108 const int* allocatable_general_codes() const { 109 return allocatable_general_codes_; 110 } allocatable_float_codes()111 const int* allocatable_float_codes() const { 112 return allocatable_float_codes_; 113 } allocatable_double_codes()114 const int* allocatable_double_codes() const { 115 return allocatable_double_codes_; 116 } allocatable_simd128_codes()117 const int* allocatable_simd128_codes() const { 118 return allocatable_simd128_codes_; 119 } 120 121 // Aliasing calculations for floating point registers, when fp_aliasing_kind() 122 // is COMBINE. Currently only implemented for kFloat32, kFloat64, or kSimd128 123 // reps. Returns the number of aliases, and if > 0, alias_base_index is set to 124 // the index of the first alias. 125 int GetAliases(MachineRepresentation rep, int index, 126 MachineRepresentation other_rep, int* alias_base_index) const; 127 // Returns a value indicating whether two registers alias each other, when 128 // fp_aliasing_kind() is COMBINE. Currently implemented for kFloat32, 129 // kFloat64, or kSimd128 reps. 130 bool AreAliases(MachineRepresentation rep, int index, 131 MachineRepresentation other_rep, int other_index) const; 132 133 virtual ~RegisterConfiguration() = default; 134 135 private: 136 const int num_general_registers_; 137 int num_float_registers_; 138 const int num_double_registers_; 139 int num_simd128_registers_; 140 int num_allocatable_general_registers_; 141 int num_allocatable_float_registers_; 142 int num_allocatable_double_registers_; 143 int num_allocatable_simd128_registers_; 144 int32_t allocatable_general_codes_mask_; 145 int32_t allocatable_float_codes_mask_; 146 int32_t allocatable_double_codes_mask_; 147 int32_t allocatable_simd128_codes_mask_; 148 const int* allocatable_general_codes_; 149 int allocatable_float_codes_[kMaxFPRegisters]; 150 const int* allocatable_double_codes_; 151 int allocatable_simd128_codes_[kMaxFPRegisters]; 152 AliasingKind fp_aliasing_kind_; 153 }; 154 155 } // namespace internal 156 } // namespace v8 157 158 #endif // V8_CODEGEN_REGISTER_CONFIGURATION_H_ 159