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