Commit aca3716a authored by bbudge's avatar bbudge Committed by Commit bot

[Turbofan] Add Simd128 registers to RegisterConfiguration.

-Defines SIMD128_REGISTERS for all platforms.
-Adds Simd128 register information to RegisterConfiguration, and implements
aliasing calculations.

LOG=N
BUG=v8:4124

Review-Url: https://codereview.chromium.org/2092103004
Cr-Commit-Position: refs/heads/master@{#37437}
parent e8d2238d
...@@ -69,6 +69,10 @@ namespace internal { ...@@ -69,6 +69,10 @@ namespace internal {
V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
#define SIMD128_REGISTERS(V) \
V(q0) V(q1) V(q2) V(q3) V(q4) V(q5) V(q6) V(q7) \
V(q8) V(q9) V(q10) V(q11) V(q12) V(q13) V(q14) V(q15)
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) \ V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) \
......
...@@ -40,7 +40,7 @@ namespace internal { ...@@ -40,7 +40,7 @@ namespace internal {
R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \
R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x27) R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x27)
#define FLOAT_REGISTERS(V) \ #define FLOAT_REGISTERS(V) \
V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \ V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \
V(s8) V(s9) V(s10) V(s11) V(s12) V(s13) V(s14) V(s15) \ V(s8) V(s9) V(s10) V(s11) V(s12) V(s13) V(s14) V(s15) \
V(s16) V(s17) V(s18) V(s19) V(s20) V(s21) V(s22) V(s23) \ V(s16) V(s17) V(s18) V(s19) V(s20) V(s21) V(s22) V(s23) \
...@@ -52,6 +52,10 @@ namespace internal { ...@@ -52,6 +52,10 @@ namespace internal {
R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \ R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \
R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31) R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31)
#define SIMD128_REGISTERS(V) \
V(q0) V(q1) V(q2) V(q3) V(q4) V(q5) V(q6) V(q7) \
V(q8) V(q9) V(q10) V(q11) V(q12) V(q13) V(q14) V(q15)
#define ALLOCATABLE_DOUBLE_REGISTERS(R) \ #define ALLOCATABLE_DOUBLE_REGISTERS(R) \
R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \
R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \ R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \
......
...@@ -32,26 +32,41 @@ bool Blocks(const OperandSet& set, const InstructionOperand& operand) { ...@@ -32,26 +32,41 @@ bool Blocks(const OperandSet& set, const InstructionOperand& operand) {
// Only FP registers on archs with non-simple aliasing need extra checks. // Only FP registers on archs with non-simple aliasing need extra checks.
if (!operand.IsFPRegister() || kSimpleFPAliasing) return false; if (!operand.IsFPRegister() || kSimpleFPAliasing) return false;
// Check operand against operands of other FP types for interference.
const LocationOperand& loc = LocationOperand::cast(operand); const LocationOperand& loc = LocationOperand::cast(operand);
MachineRepresentation rep = loc.representation(); MachineRepresentation rep = loc.representation();
MachineRepresentation other_fp_rep = rep == MachineRepresentation::kFloat64 MachineRepresentation other_rep1, other_rep2;
? MachineRepresentation::kFloat32 switch (rep) {
: MachineRepresentation::kFloat64; case MachineRepresentation::kFloat32:
other_rep1 = MachineRepresentation::kFloat64;
other_rep2 = MachineRepresentation::kSimd128;
break;
case MachineRepresentation::kFloat64:
other_rep1 = MachineRepresentation::kFloat32;
other_rep2 = MachineRepresentation::kSimd128;
break;
case MachineRepresentation::kSimd128:
other_rep1 = MachineRepresentation::kFloat32;
other_rep2 = MachineRepresentation::kFloat64;
break;
default:
UNREACHABLE();
break;
}
const RegisterConfiguration* config = RegisterConfiguration::Turbofan(); const RegisterConfiguration* config = RegisterConfiguration::Turbofan();
if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) { int base = -1;
// Overlap aliasing case. int aliases = config->GetAliases(rep, loc.register_code(), other_rep1, &base);
return set.find(LocationOperand(loc.kind(), loc.location_kind(), DCHECK(aliases > 0 || (aliases == 0 && base == -1));
other_fp_rep, loc.register_code())) != while (aliases--) {
set.end(); if (set.find(LocationOperand(loc.kind(), loc.location_kind(), other_rep1,
} base + aliases)) != set.end())
// Combine aliasing case. return true;
int alias_base_index = -1; }
int aliases = config->GetAliases(rep, loc.register_code(), other_fp_rep, aliases = config->GetAliases(rep, loc.register_code(), other_rep2, &base);
&alias_base_index); DCHECK(aliases > 0 || (aliases == 0 && base == -1));
while (aliases--) { while (aliases--) {
int aliased_reg = alias_base_index + aliases; if (set.find(LocationOperand(loc.kind(), loc.location_kind(), other_rep2,
if (set.find(LocationOperand(loc.kind(), loc.location_kind(), other_fp_rep, base + aliases)) != set.end())
aliased_reg)) != set.end())
return true; return true;
} }
return false; return false;
......
This diff is collapsed.
...@@ -779,6 +779,12 @@ class RegisterAllocationData final : public ZoneObject { ...@@ -779,6 +779,12 @@ class RegisterAllocationData final : public ZoneObject {
const ZoneVector<TopLevelLiveRange*>& fixed_double_live_ranges() const { const ZoneVector<TopLevelLiveRange*>& fixed_double_live_ranges() const {
return fixed_double_live_ranges_; return fixed_double_live_ranges_;
} }
ZoneVector<TopLevelLiveRange*>& fixed_simd128_live_ranges() {
return fixed_simd128_live_ranges_;
}
const ZoneVector<TopLevelLiveRange*>& fixed_simd128_live_ranges() const {
return fixed_simd128_live_ranges_;
}
ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; } ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; }
ZoneVector<BitVector*>& live_out_sets() { return live_out_sets_; } ZoneVector<BitVector*>& live_out_sets() { return live_out_sets_; }
ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; } ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
...@@ -842,6 +848,7 @@ class RegisterAllocationData final : public ZoneObject { ...@@ -842,6 +848,7 @@ class RegisterAllocationData final : public ZoneObject {
ZoneVector<TopLevelLiveRange*> fixed_live_ranges_; ZoneVector<TopLevelLiveRange*> fixed_live_ranges_;
ZoneVector<TopLevelLiveRange*> fixed_float_live_ranges_; ZoneVector<TopLevelLiveRange*> fixed_float_live_ranges_;
ZoneVector<TopLevelLiveRange*> fixed_double_live_ranges_; ZoneVector<TopLevelLiveRange*> fixed_double_live_ranges_;
ZoneVector<TopLevelLiveRange*> fixed_simd128_live_ranges_;
ZoneVector<SpillRange*> spill_ranges_; ZoneVector<SpillRange*> spill_ranges_;
DelayedReferences delayed_references_; DelayedReferences delayed_references_;
BitVector* assigned_registers_; BitVector* assigned_registers_;
......
...@@ -75,7 +75,7 @@ namespace internal { ...@@ -75,7 +75,7 @@ namespace internal {
V(xmm7) V(xmm7)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD_REGISTERS DOUBLE_REGISTERS #define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(xmm1) \ V(xmm1) \
......
...@@ -23,8 +23,8 @@ enum class MachineRepresentation : uint8_t { ...@@ -23,8 +23,8 @@ enum class MachineRepresentation : uint8_t {
kWord32, kWord32,
kWord64, kWord64,
kFloat32, kFloat32,
kFloat64, kFloat64, // must follow kFloat32
kSimd128, kSimd128, // must follow kFloat64
kTagged kTagged
}; };
......
...@@ -64,6 +64,7 @@ namespace internal { ...@@ -64,6 +64,7 @@ namespace internal {
V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31) V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f14) \ V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f14) \
......
...@@ -64,6 +64,7 @@ namespace internal { ...@@ -64,6 +64,7 @@ namespace internal {
V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31) V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f14) \ V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f14) \
......
...@@ -110,6 +110,7 @@ namespace internal { ...@@ -110,6 +110,7 @@ namespace internal {
V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
......
...@@ -45,10 +45,20 @@ static const char* const kDoubleRegisterNames[] = { ...@@ -45,10 +45,20 @@ static const char* const kDoubleRegisterNames[] = {
#undef REGISTER_NAME #undef REGISTER_NAME
}; };
static const char* const kSimd128RegisterNames[] = {
#define REGISTER_NAME(R) #R,
SIMD128_REGISTERS(REGISTER_NAME)
#undef REGISTER_NAME
};
STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >= STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
Register::kNumRegisters); Register::kNumRegisters);
STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
FloatRegister::kMaxNumRegisters);
STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >= STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
DoubleRegister::kMaxNumRegisters); DoubleRegister::kMaxNumRegisters);
STATIC_ASSERT(RegisterConfiguration::kMaxFPRegisters >=
Simd128Register::kMaxNumRegisters);
enum CompilerSelector { CRANKSHAFT, TURBOFAN }; enum CompilerSelector { CRANKSHAFT, TURBOFAN };
...@@ -93,7 +103,8 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration { ...@@ -93,7 +103,8 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
#endif #endif
kAllocatableGeneralCodes, kAllocatableDoubleCodes, kAllocatableGeneralCodes, kAllocatableDoubleCodes,
kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE, kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE,
kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames) { kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames,
kSimd128RegisterNames) {
} }
}; };
...@@ -128,22 +139,27 @@ RegisterConfiguration::RegisterConfiguration( ...@@ -128,22 +139,27 @@ RegisterConfiguration::RegisterConfiguration(
const int* allocatable_general_codes, const int* allocatable_double_codes, const int* allocatable_general_codes, const int* allocatable_double_codes,
AliasingKind fp_aliasing_kind, const char* const* general_register_names, AliasingKind fp_aliasing_kind, const char* const* general_register_names,
const char* const* float_register_names, const char* const* float_register_names,
const char* const* double_register_names) const char* const* double_register_names,
const char* const* simd128_register_names)
: num_general_registers_(num_general_registers), : num_general_registers_(num_general_registers),
num_float_registers_(0), num_float_registers_(0),
num_double_registers_(num_double_registers), num_double_registers_(num_double_registers),
num_simd128_registers_(0),
num_allocatable_general_registers_(num_allocatable_general_registers), num_allocatable_general_registers_(num_allocatable_general_registers),
num_allocatable_double_registers_(num_allocatable_double_registers),
num_allocatable_float_registers_(0), num_allocatable_float_registers_(0),
num_allocatable_double_registers_(num_allocatable_double_registers),
num_allocatable_simd128_registers_(0),
allocatable_general_codes_mask_(0), allocatable_general_codes_mask_(0),
allocatable_double_codes_mask_(0),
allocatable_float_codes_mask_(0), allocatable_float_codes_mask_(0),
allocatable_double_codes_mask_(0),
allocatable_simd128_codes_mask_(0),
allocatable_general_codes_(allocatable_general_codes), allocatable_general_codes_(allocatable_general_codes),
allocatable_double_codes_(allocatable_double_codes), allocatable_double_codes_(allocatable_double_codes),
fp_aliasing_kind_(fp_aliasing_kind), fp_aliasing_kind_(fp_aliasing_kind),
general_register_names_(general_register_names), general_register_names_(general_register_names),
float_register_names_(float_register_names), float_register_names_(float_register_names),
double_register_names_(double_register_names) { double_register_names_(double_register_names),
simd128_register_names_(simd128_register_names) {
DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters); DCHECK(num_general_registers_ <= RegisterConfiguration::kMaxGeneralRegisters);
DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters); DCHECK(num_double_registers_ <= RegisterConfiguration::kMaxFPRegisters);
for (int i = 0; i < num_allocatable_general_registers_; ++i) { for (int i = 0; i < num_allocatable_general_registers_; ++i) {
...@@ -166,67 +182,82 @@ RegisterConfiguration::RegisterConfiguration( ...@@ -166,67 +182,82 @@ RegisterConfiguration::RegisterConfiguration(
base_code + 1; base_code + 1;
allocatable_float_codes_mask_ |= (0x3 << base_code); allocatable_float_codes_mask_ |= (0x3 << base_code);
} }
num_simd128_registers_ = num_double_registers_ / 2;
num_allocatable_simd128_registers_ = 0;
int last_simd128_code = allocatable_double_codes_[0] / 2;
for (int i = 1; i < num_allocatable_double_registers_; i++) {
int next_simd128_code = allocatable_double_codes_[i] / 2;
// This scheme assumes allocatable_double_codes_ are strictly increasing.
DCHECK_GE(next_simd128_code, last_simd128_code);
if (last_simd128_code == next_simd128_code) {
allocatable_simd128_codes_[num_allocatable_simd128_registers_++] =
next_simd128_code;
allocatable_simd128_codes_mask_ |= (0x1 << next_simd128_code);
}
last_simd128_code = next_simd128_code;
}
} else { } else {
DCHECK(fp_aliasing_kind_ == OVERLAP); DCHECK(fp_aliasing_kind_ == OVERLAP);
num_float_registers_ = num_double_registers_; num_float_registers_ = num_simd128_registers_ = num_double_registers_;
num_allocatable_float_registers_ = num_allocatable_double_registers_; num_allocatable_float_registers_ = num_allocatable_simd128_registers_ =
num_allocatable_double_registers_;
for (int i = 0; i < num_allocatable_float_registers_; ++i) { for (int i = 0; i < num_allocatable_float_registers_; ++i) {
allocatable_float_codes_[i] = allocatable_double_codes_[i]; allocatable_float_codes_[i] = allocatable_simd128_codes_[i] =
allocatable_double_codes_[i];
} }
allocatable_float_codes_mask_ = allocatable_double_codes_mask_; allocatable_float_codes_mask_ = allocatable_simd128_codes_mask_ =
allocatable_double_codes_mask_;
} }
} }
// Assert that kFloat32, kFloat64, and kSimd128 are consecutive values.
STATIC_ASSERT(static_cast<int>(MachineRepresentation::kSimd128) ==
static_cast<int>(MachineRepresentation::kFloat64) + 1);
STATIC_ASSERT(static_cast<int>(MachineRepresentation::kFloat64) ==
static_cast<int>(MachineRepresentation::kFloat32) + 1);
int RegisterConfiguration::GetAliases(MachineRepresentation rep, int index, int RegisterConfiguration::GetAliases(MachineRepresentation rep, int index,
MachineRepresentation other_rep, MachineRepresentation other_rep,
int* alias_base_index) const { int* alias_base_index) const {
DCHECK(fp_aliasing_kind_ == COMBINE); DCHECK(fp_aliasing_kind_ == COMBINE);
DCHECK(rep == MachineRepresentation::kFloat32 || DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep));
rep == MachineRepresentation::kFloat64);
DCHECK(other_rep == MachineRepresentation::kFloat32 ||
other_rep == MachineRepresentation::kFloat64);
if (rep == other_rep) { if (rep == other_rep) {
*alias_base_index = index; *alias_base_index = index;
return 1; return 1;
} }
if (rep == MachineRepresentation::kFloat32) { int rep_int = static_cast<int>(rep);
DCHECK(other_rep == MachineRepresentation::kFloat64); int other_rep_int = static_cast<int>(other_rep);
DCHECK(index < num_allocatable_float_registers_); if (rep_int > other_rep_int) {
*alias_base_index = index / 2; int shift = rep_int - other_rep_int;
return 1; int base_index = index << shift;
} if (base_index >= kMaxFPRegisters) {
DCHECK(rep == MachineRepresentation::kFloat64); // Alias indices would be out of FP register range.
DCHECK(other_rep == MachineRepresentation::kFloat32); return 0;
if (index * 2 >= kMaxFPRegisters) { }
// Alias indices are out of float register range. *alias_base_index = base_index;
return 0; return 1 << shift;
} }
*alias_base_index = index * 2; int shift = other_rep_int - rep_int;
return 2; *alias_base_index = index >> shift;
return 1;
} }
bool RegisterConfiguration::AreAliases(MachineRepresentation rep, int index, bool RegisterConfiguration::AreAliases(MachineRepresentation rep, int index,
MachineRepresentation other_rep, MachineRepresentation other_rep,
int other_index) const { int other_index) const {
DCHECK(fp_aliasing_kind_ == COMBINE); DCHECK(fp_aliasing_kind_ == COMBINE);
DCHECK(rep == MachineRepresentation::kFloat32 || DCHECK(IsFloatingPoint(rep) && IsFloatingPoint(other_rep));
rep == MachineRepresentation::kFloat64);
DCHECK(other_rep == MachineRepresentation::kFloat32 ||
other_rep == MachineRepresentation::kFloat64);
if (rep == other_rep) { if (rep == other_rep) {
return index == other_index; return index == other_index;
} }
if (rep == MachineRepresentation::kFloat32) { int rep_int = static_cast<int>(rep);
DCHECK(other_rep == MachineRepresentation::kFloat64); int other_rep_int = static_cast<int>(other_rep);
return index / 2 == other_index; if (rep_int > other_rep_int) {
} int shift = rep_int - other_rep_int;
DCHECK(rep == MachineRepresentation::kFloat64); return index == other_index >> shift;
DCHECK(other_rep == MachineRepresentation::kFloat32);
if (index * 2 >= kMaxFPRegisters) {
// Alias indices are out of float register range.
return false;
} }
return index == other_index / 2; int shift = other_rep_int - rep_int;
return index >> shift == other_index;
} }
#undef REGISTER_COUNT #undef REGISTER_COUNT
......
...@@ -40,19 +40,24 @@ class RegisterConfiguration { ...@@ -40,19 +40,24 @@ class RegisterConfiguration {
AliasingKind fp_aliasing_kind, AliasingKind fp_aliasing_kind,
char const* const* general_names, char const* const* general_names,
char const* const* float_names, char const* const* float_names,
char const* const* double_names); char const* const* double_names,
char const* const* simd128_names);
int num_general_registers() const { return num_general_registers_; } int num_general_registers() const { return num_general_registers_; }
int num_float_registers() const { return num_float_registers_; } int num_float_registers() const { return num_float_registers_; }
int num_double_registers() const { return num_double_registers_; } int num_double_registers() const { return num_double_registers_; }
int num_simd128_registers() const { return num_simd128_registers_; }
int num_allocatable_general_registers() const { int num_allocatable_general_registers() const {
return num_allocatable_general_registers_; return num_allocatable_general_registers_;
} }
int num_allocatable_float_registers() const {
return num_allocatable_float_registers_;
}
int num_allocatable_double_registers() const { int num_allocatable_double_registers() const {
return num_allocatable_double_registers_; return num_allocatable_double_registers_;
} }
int num_allocatable_float_registers() const { int num_allocatable_simd128_registers() const {
return num_allocatable_float_registers_; return num_allocatable_simd128_registers_;
} }
AliasingKind fp_aliasing_kind() const { return fp_aliasing_kind_; } AliasingKind fp_aliasing_kind() const { return fp_aliasing_kind_; }
int32_t allocatable_general_codes_mask() const { int32_t allocatable_general_codes_mask() const {
...@@ -67,17 +72,23 @@ class RegisterConfiguration { ...@@ -67,17 +72,23 @@ class RegisterConfiguration {
bool IsAllocatableGeneralCode(int index) const { bool IsAllocatableGeneralCode(int index) const {
return ((1 << index) & allocatable_general_codes_mask_) != 0; return ((1 << index) & allocatable_general_codes_mask_) != 0;
} }
int GetAllocatableFloatCode(int index) const {
return allocatable_float_codes_[index];
}
bool IsAllocatableFloatCode(int index) const {
return ((1 << index) & allocatable_float_codes_mask_) != 0;
}
int GetAllocatableDoubleCode(int index) const { int GetAllocatableDoubleCode(int index) const {
return allocatable_double_codes_[index]; return allocatable_double_codes_[index];
} }
bool IsAllocatableDoubleCode(int index) const { bool IsAllocatableDoubleCode(int index) const {
return ((1 << index) & allocatable_double_codes_mask_) != 0; return ((1 << index) & allocatable_double_codes_mask_) != 0;
} }
int GetAllocatableFloatCode(int index) const { int GetAllocatableSimd128Code(int index) const {
return allocatable_float_codes_[index]; return allocatable_simd128_codes_[index];
} }
bool IsAllocatableFloatCode(int index) const { bool IsAllocatableSimd128Code(int index) const {
return ((1 << index) & allocatable_float_codes_mask_) != 0; return ((1 << index) & allocatable_simd128_codes_mask_) != 0;
} }
const char* GetGeneralRegisterName(int code) const { const char* GetGeneralRegisterName(int code) const {
return general_register_names_[code]; return general_register_names_[code];
...@@ -88,25 +99,31 @@ class RegisterConfiguration { ...@@ -88,25 +99,31 @@ class RegisterConfiguration {
const char* GetDoubleRegisterName(int code) const { const char* GetDoubleRegisterName(int code) const {
return double_register_names_[code]; return double_register_names_[code];
} }
const char* GetSimd128RegisterName(int code) const {
return simd128_register_names_[code];
}
const int* allocatable_general_codes() const { const int* allocatable_general_codes() const {
return allocatable_general_codes_; return allocatable_general_codes_;
} }
const int* allocatable_float_codes() const {
return allocatable_float_codes_;
}
const int* allocatable_double_codes() const { const int* allocatable_double_codes() const {
return allocatable_double_codes_; return allocatable_double_codes_;
} }
const int* allocatable_float_codes() const { const int* allocatable_simd128_codes() const {
return allocatable_float_codes_; return allocatable_simd128_codes_;
} }
// Aliasing calculations for floating point registers, when fp_aliasing_kind() // Aliasing calculations for floating point registers, when fp_aliasing_kind()
// is COMBINE. Currently only implemented for kFloat32, or kFloat64 reps. // is COMBINE. Currently only implemented for kFloat32, kFloat64, or kSimd128
// Returns the number of aliases, and if > 0, alias_base_index is set to the // reps. Returns the number of aliases, and if > 0, alias_base_index is set to
// index of the first alias. // the index of the first alias.
int GetAliases(MachineRepresentation rep, int index, int GetAliases(MachineRepresentation rep, int index,
MachineRepresentation other_rep, int* alias_base_index) const; MachineRepresentation other_rep, int* alias_base_index) const;
// Returns a value indicating whether two registers alias each other, when // Returns a value indicating whether two registers alias each other, when
// fp_aliasing_kind() is COMBINE. Currently only implemented for kFloat32, or // fp_aliasing_kind() is COMBINE. Currently implemented for kFloat32,
// kFloat64 reps. // kFloat64, or kSimd128 reps.
bool AreAliases(MachineRepresentation rep, int index, bool AreAliases(MachineRepresentation rep, int index,
MachineRepresentation other_rep, int other_index) const; MachineRepresentation other_rep, int other_index) const;
...@@ -114,19 +131,24 @@ class RegisterConfiguration { ...@@ -114,19 +131,24 @@ class RegisterConfiguration {
const int num_general_registers_; const int num_general_registers_;
int num_float_registers_; int num_float_registers_;
const int num_double_registers_; const int num_double_registers_;
int num_simd128_registers_;
int num_allocatable_general_registers_; int num_allocatable_general_registers_;
int num_allocatable_double_registers_;
int num_allocatable_float_registers_; int num_allocatable_float_registers_;
int num_allocatable_double_registers_;
int num_allocatable_simd128_registers_;
int32_t allocatable_general_codes_mask_; int32_t allocatable_general_codes_mask_;
int32_t allocatable_double_codes_mask_;
int32_t allocatable_float_codes_mask_; int32_t allocatable_float_codes_mask_;
int32_t allocatable_double_codes_mask_;
int32_t allocatable_simd128_codes_mask_;
const int* allocatable_general_codes_; const int* allocatable_general_codes_;
const int* allocatable_double_codes_;
int allocatable_float_codes_[kMaxFPRegisters]; int allocatable_float_codes_[kMaxFPRegisters];
const int* allocatable_double_codes_;
int allocatable_simd128_codes_[kMaxFPRegisters];
AliasingKind fp_aliasing_kind_; AliasingKind fp_aliasing_kind_;
char const* const* general_register_names_; char const* const* general_register_names_;
char const* const* float_register_names_; char const* const* float_register_names_;
char const* const* double_register_names_; char const* const* double_register_names_;
char const* const* simd128_register_names_;
}; };
} // namespace internal } // namespace internal
......
...@@ -91,6 +91,7 @@ namespace internal { ...@@ -91,6 +91,7 @@ namespace internal {
V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
......
...@@ -182,6 +182,7 @@ const Register arg_reg_4 = {Register::kCode_rcx}; ...@@ -182,6 +182,7 @@ const Register arg_reg_4 = {Register::kCode_rcx};
V(xmm15) V(xmm15)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(xmm0) \ V(xmm0) \
......
...@@ -75,6 +75,7 @@ namespace internal { ...@@ -75,6 +75,7 @@ namespace internal {
V(stX_7) V(stX_7)
#define FLOAT_REGISTERS DOUBLE_REGISTERS #define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(stX_0) \ V(stX_0) \
......
...@@ -22,8 +22,8 @@ group("gn_all") { ...@@ -22,8 +22,8 @@ group("gn_all") {
if (v8_test_isolation_mode != "noop") { if (v8_test_isolation_mode != "noop") {
deps += [ deps += [
":bot_default_run",
":benchmarks_run", ":benchmarks_run",
":bot_default_run",
":default_run", ":default_run",
":mozilla_run", ":mozilla_run",
":simdjs_run", ":simdjs_run",
...@@ -54,7 +54,7 @@ group("default_tests") { ...@@ -54,7 +54,7 @@ group("default_tests") {
v8_isolate_run("bot_default") { v8_isolate_run("bot_default") {
deps = [ deps = [
":default_tests", ":default_tests",
":webkit_run", ":webkit_run",
] ]
...@@ -131,8 +131,8 @@ v8_isolate_run("fuzzer") { ...@@ -131,8 +131,8 @@ v8_isolate_run("fuzzer") {
"..:v8_simple_json_fuzzer", "..:v8_simple_json_fuzzer",
"..:v8_simple_parser_fuzzer", "..:v8_simple_parser_fuzzer",
"..:v8_simple_regexp_fuzzer", "..:v8_simple_regexp_fuzzer",
"..:v8_simple_wasm_fuzzer",
"..:v8_simple_wasm_asmjs_fuzzer", "..:v8_simple_wasm_asmjs_fuzzer",
"..:v8_simple_wasm_fuzzer",
] ]
isolate = "fuzzer/fuzzer.isolate" isolate = "fuzzer/fuzzer.isolate"
......
...@@ -72,7 +72,8 @@ RegisterConfiguration* InstructionSequenceTest::config() { ...@@ -72,7 +72,8 @@ RegisterConfiguration* InstructionSequenceTest::config() {
: RegisterConfiguration::COMBINE, : RegisterConfiguration::COMBINE,
general_register_names_, general_register_names_,
double_register_names_, // float register names double_register_names_, // float register names
double_register_names_)); double_register_names_,
double_register_names_)); // SIMD 128 register names
} }
return config_.get(); return config_.get();
} }
......
...@@ -10,6 +10,7 @@ namespace internal { ...@@ -10,6 +10,7 @@ namespace internal {
const MachineRepresentation kFloat32 = MachineRepresentation::kFloat32; const MachineRepresentation kFloat32 = MachineRepresentation::kFloat32;
const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64; const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64;
const MachineRepresentation kSimd128 = MachineRepresentation::kSimd128;
class RegisterConfigurationUnitTest : public ::testing::Test { class RegisterConfigurationUnitTest : public ::testing::Test {
public: public:
...@@ -30,7 +31,7 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) { ...@@ -30,7 +31,7 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
RegisterConfiguration test( RegisterConfiguration test(
kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs, kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs,
kNumAllocatableDoubleRegs, general_codes, double_codes, kNumAllocatableDoubleRegs, general_codes, double_codes,
RegisterConfiguration::OVERLAP, nullptr, nullptr, nullptr); RegisterConfiguration::OVERLAP, nullptr, nullptr, nullptr, nullptr);
EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs); EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs);
EXPECT_EQ(test.num_double_registers(), kNumDoubleRegs); EXPECT_EQ(test.num_double_registers(), kNumDoubleRegs);
...@@ -38,6 +39,8 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) { ...@@ -38,6 +39,8 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
kNumAllocatableGeneralRegs); kNumAllocatableGeneralRegs);
EXPECT_EQ(test.num_allocatable_double_registers(), kNumAllocatableDoubleRegs); EXPECT_EQ(test.num_allocatable_double_registers(), kNumAllocatableDoubleRegs);
EXPECT_EQ(test.num_allocatable_float_registers(), kNumAllocatableDoubleRegs); EXPECT_EQ(test.num_allocatable_float_registers(), kNumAllocatableDoubleRegs);
EXPECT_EQ(test.num_allocatable_simd128_registers(),
kNumAllocatableDoubleRegs);
EXPECT_EQ(test.allocatable_general_codes_mask(), EXPECT_EQ(test.allocatable_general_codes_mask(),
(1 << general_codes[0]) | (1 << general_codes[1])); (1 << general_codes[0]) | (1 << general_codes[1]));
...@@ -45,11 +48,15 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) { ...@@ -45,11 +48,15 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
EXPECT_EQ(test.GetAllocatableGeneralCode(1), general_codes[1]); EXPECT_EQ(test.GetAllocatableGeneralCode(1), general_codes[1]);
EXPECT_EQ(test.allocatable_double_codes_mask(), EXPECT_EQ(test.allocatable_double_codes_mask(),
(1 << double_codes[0]) | (1 << double_codes[1])); (1 << double_codes[0]) | (1 << double_codes[1]));
EXPECT_EQ(test.GetAllocatableFloatCode(0), double_codes[0]);
EXPECT_EQ(test.GetAllocatableDoubleCode(0), double_codes[0]); EXPECT_EQ(test.GetAllocatableDoubleCode(0), double_codes[0]);
EXPECT_EQ(test.GetAllocatableSimd128Code(0), double_codes[0]);
EXPECT_EQ(test.GetAllocatableFloatCode(1), double_codes[1]);
EXPECT_EQ(test.GetAllocatableDoubleCode(1), double_codes[1]); EXPECT_EQ(test.GetAllocatableDoubleCode(1), double_codes[1]);
EXPECT_EQ(test.GetAllocatableSimd128Code(1), double_codes[1]);
} }
TEST_F(RegisterConfigurationUnitTest, Aliasing) { TEST_F(RegisterConfigurationUnitTest, CombineAliasing) {
const int kNumGeneralRegs = 3; const int kNumGeneralRegs = 3;
const int kNumDoubleRegs = 4; const int kNumDoubleRegs = 4;
const int kNumAllocatableGeneralRegs = 2; const int kNumAllocatableGeneralRegs = 2;
...@@ -60,7 +67,7 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) { ...@@ -60,7 +67,7 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) {
RegisterConfiguration test( RegisterConfiguration test(
kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs, kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs,
kNumAllocatableDoubleRegs, general_codes, double_codes, kNumAllocatableDoubleRegs, general_codes, double_codes,
RegisterConfiguration::COMBINE, nullptr, nullptr, nullptr); RegisterConfiguration::COMBINE, nullptr, nullptr, nullptr, nullptr);
// There are 3 allocatable double regs, but only 2 can alias float regs. // There are 3 allocatable double regs, but only 2 can alias float regs.
EXPECT_EQ(test.num_allocatable_float_registers(), 4); EXPECT_EQ(test.num_allocatable_float_registers(), 4);
...@@ -71,20 +78,41 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) { ...@@ -71,20 +78,41 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) {
EXPECT_EQ(test.GetAllocatableFloatCode(2), double_codes[1] * 2); EXPECT_EQ(test.GetAllocatableFloatCode(2), double_codes[1] * 2);
EXPECT_EQ(test.GetAllocatableFloatCode(3), double_codes[1] * 2 + 1); EXPECT_EQ(test.GetAllocatableFloatCode(3), double_codes[1] * 2 + 1);
// There are 3 allocatable double regs, but only 2 pair to form 1 SIMD reg.
EXPECT_EQ(test.num_allocatable_simd128_registers(), 1);
// Test that even-odd pairs of double regs combine to form a SIMD reg.
EXPECT_EQ(test.GetAllocatableSimd128Code(0), double_codes[0] / 2);
// Registers alias themselves. // Registers alias themselves.
EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat32, 0)); EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat32, 0));
EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat64, 0)); EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat64, 0));
EXPECT_TRUE(test.AreAliases(kSimd128, 0, kSimd128, 0));
// Registers don't alias other registers of the same size. // Registers don't alias other registers of the same size.
EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat32, 0)); EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat32, 0));
EXPECT_FALSE(test.AreAliases(kFloat64, 1, kFloat64, 0)); EXPECT_FALSE(test.AreAliases(kFloat64, 1, kFloat64, 0));
// Float registers combine in pairs and alias double registers. EXPECT_FALSE(test.AreAliases(kSimd128, 1, kSimd128, 0));
// Float registers combine in pairs to alias a double with index / 2, and
// in 4's to alias a simd128 with index / 4.
EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat64, 0)); EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat64, 0));
EXPECT_TRUE(test.AreAliases(kFloat32, 1, kFloat64, 0)); EXPECT_TRUE(test.AreAliases(kFloat32, 1, kFloat64, 0));
EXPECT_TRUE(test.AreAliases(kFloat32, 0, kSimd128, 0));
EXPECT_TRUE(test.AreAliases(kFloat32, 1, kSimd128, 0));
EXPECT_TRUE(test.AreAliases(kFloat32, 2, kSimd128, 0));
EXPECT_TRUE(test.AreAliases(kFloat32, 3, kSimd128, 0));
EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 0)); EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 0));
EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1)); EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1));
EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 0));
EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 1));
EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 2));
EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 3));
EXPECT_FALSE(test.AreAliases(kFloat32, 0, kFloat64, 1)); EXPECT_FALSE(test.AreAliases(kFloat32, 0, kFloat64, 1));
EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat64, 1)); EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat64, 1));
EXPECT_FALSE(test.AreAliases(kFloat32, 0, kSimd128, 1));
EXPECT_FALSE(test.AreAliases(kFloat32, 1, kSimd128, 1));
EXPECT_FALSE(test.AreAliases(kFloat64, 0, kSimd128, 1));
EXPECT_FALSE(test.AreAliases(kFloat64, 1, kSimd128, 1));
EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1)); EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1));
EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 2)); EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 2));
...@@ -92,6 +120,12 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) { ...@@ -92,6 +120,12 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) {
EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 4)); EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 4));
EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 5)); EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 5));
EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat64, 1));
EXPECT_TRUE(test.AreAliases(kSimd128, 1, kFloat64, 2));
EXPECT_TRUE(test.AreAliases(kSimd128, 1, kFloat64, 3));
EXPECT_TRUE(test.AreAliases(kSimd128, 2, kFloat64, 4));
EXPECT_TRUE(test.AreAliases(kSimd128, 2, kFloat64, 5));
int alias_base_index = -1; int alias_base_index = -1;
EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat32, &alias_base_index), 1); EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat32, &alias_base_index), 1);
EXPECT_EQ(alias_base_index, 0); EXPECT_EQ(alias_base_index, 0);
...@@ -112,7 +146,7 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) { ...@@ -112,7 +146,7 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) {
// Non-allocatable codes still alias. // Non-allocatable codes still alias.
EXPECT_EQ(test.GetAliases(kFloat64, 2, kFloat32, &alias_base_index), 2); EXPECT_EQ(test.GetAliases(kFloat64, 2, kFloat32, &alias_base_index), 2);
EXPECT_EQ(alias_base_index, 4); EXPECT_EQ(alias_base_index, 4);
// High numbered double registers don't alias nonexistent single registers. // High numbered double and simd regs don't alias nonexistent float registers.
EXPECT_EQ( EXPECT_EQ(
test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2, test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2,
kFloat32, &alias_base_index), kFloat32, &alias_base_index),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment