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