OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/register-configuration.h" | 5 #include "src/register-configuration.h" |
6 #include "testing/gtest-support.h" | 6 #include "testing/gtest-support.h" |
7 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 | 10 |
11 const MachineRepresentation kFloat32 = MachineRepresentation::kFloat32; | 11 const MachineRepresentation kFloat32 = MachineRepresentation::kFloat32; |
12 const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64; | 12 const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64; |
| 13 const MachineRepresentation kSimd128 = MachineRepresentation::kSimd128; |
13 | 14 |
14 class RegisterConfigurationUnitTest : public ::testing::Test { | 15 class RegisterConfigurationUnitTest : public ::testing::Test { |
15 public: | 16 public: |
16 RegisterConfigurationUnitTest() {} | 17 RegisterConfigurationUnitTest() {} |
17 virtual ~RegisterConfigurationUnitTest() {} | 18 virtual ~RegisterConfigurationUnitTest() {} |
18 | 19 |
19 private: | 20 private: |
20 }; | 21 }; |
21 | 22 |
22 TEST_F(RegisterConfigurationUnitTest, BasicProperties) { | 23 TEST_F(RegisterConfigurationUnitTest, BasicProperties) { |
23 const int kNumGeneralRegs = 3; | 24 const int kNumGeneralRegs = 3; |
24 const int kNumDoubleRegs = 4; | 25 const int kNumDoubleRegs = 4; |
25 const int kNumAllocatableGeneralRegs = 2; | 26 const int kNumAllocatableGeneralRegs = 2; |
26 const int kNumAllocatableDoubleRegs = 2; | 27 const int kNumAllocatableDoubleRegs = 2; |
27 int general_codes[kNumAllocatableGeneralRegs] = {1, 2}; | 28 int general_codes[kNumAllocatableGeneralRegs] = {1, 2}; |
28 int double_codes[kNumAllocatableDoubleRegs] = {2, 3}; | 29 int double_codes[kNumAllocatableDoubleRegs] = {2, 3}; |
29 | 30 |
30 RegisterConfiguration test( | 31 RegisterConfiguration test( |
31 kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs, | 32 kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs, |
32 kNumAllocatableDoubleRegs, general_codes, double_codes, | 33 kNumAllocatableDoubleRegs, general_codes, double_codes, |
33 RegisterConfiguration::OVERLAP, nullptr, nullptr, nullptr); | 34 RegisterConfiguration::OVERLAP, nullptr, nullptr, nullptr, nullptr); |
34 | 35 |
35 EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs); | 36 EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs); |
36 EXPECT_EQ(test.num_double_registers(), kNumDoubleRegs); | 37 EXPECT_EQ(test.num_double_registers(), kNumDoubleRegs); |
37 EXPECT_EQ(test.num_allocatable_general_registers(), | 38 EXPECT_EQ(test.num_allocatable_general_registers(), |
38 kNumAllocatableGeneralRegs); | 39 kNumAllocatableGeneralRegs); |
39 EXPECT_EQ(test.num_allocatable_double_registers(), kNumAllocatableDoubleRegs); | 40 EXPECT_EQ(test.num_allocatable_double_registers(), kNumAllocatableDoubleRegs); |
40 EXPECT_EQ(test.num_allocatable_float_registers(), kNumAllocatableDoubleRegs); | 41 EXPECT_EQ(test.num_allocatable_float_registers(), kNumAllocatableDoubleRegs); |
| 42 EXPECT_EQ(test.num_allocatable_simd128_registers(), |
| 43 kNumAllocatableDoubleRegs); |
41 | 44 |
42 EXPECT_EQ(test.allocatable_general_codes_mask(), | 45 EXPECT_EQ(test.allocatable_general_codes_mask(), |
43 (1 << general_codes[0]) | (1 << general_codes[1])); | 46 (1 << general_codes[0]) | (1 << general_codes[1])); |
44 EXPECT_EQ(test.GetAllocatableGeneralCode(0), general_codes[0]); | 47 EXPECT_EQ(test.GetAllocatableGeneralCode(0), general_codes[0]); |
45 EXPECT_EQ(test.GetAllocatableGeneralCode(1), general_codes[1]); | 48 EXPECT_EQ(test.GetAllocatableGeneralCode(1), general_codes[1]); |
46 EXPECT_EQ(test.allocatable_double_codes_mask(), | 49 EXPECT_EQ(test.allocatable_double_codes_mask(), |
47 (1 << double_codes[0]) | (1 << double_codes[1])); | 50 (1 << double_codes[0]) | (1 << double_codes[1])); |
| 51 EXPECT_EQ(test.GetAllocatableFloatCode(0), double_codes[0]); |
48 EXPECT_EQ(test.GetAllocatableDoubleCode(0), double_codes[0]); | 52 EXPECT_EQ(test.GetAllocatableDoubleCode(0), double_codes[0]); |
| 53 EXPECT_EQ(test.GetAllocatableSimd128Code(0), double_codes[0]); |
| 54 EXPECT_EQ(test.GetAllocatableFloatCode(1), double_codes[1]); |
49 EXPECT_EQ(test.GetAllocatableDoubleCode(1), double_codes[1]); | 55 EXPECT_EQ(test.GetAllocatableDoubleCode(1), double_codes[1]); |
| 56 EXPECT_EQ(test.GetAllocatableSimd128Code(1), double_codes[1]); |
50 } | 57 } |
51 | 58 |
52 TEST_F(RegisterConfigurationUnitTest, Aliasing) { | 59 TEST_F(RegisterConfigurationUnitTest, CombineAliasing) { |
53 const int kNumGeneralRegs = 3; | 60 const int kNumGeneralRegs = 3; |
54 const int kNumDoubleRegs = 4; | 61 const int kNumDoubleRegs = 4; |
55 const int kNumAllocatableGeneralRegs = 2; | 62 const int kNumAllocatableGeneralRegs = 2; |
56 const int kNumAllocatableDoubleRegs = 3; | 63 const int kNumAllocatableDoubleRegs = 3; |
57 int general_codes[] = {1, 2}; | 64 int general_codes[] = {1, 2}; |
58 int double_codes[] = {2, 3, 16}; // reg 16 should not alias registers 32, 33. | 65 int double_codes[] = {2, 3, 16}; // reg 16 should not alias registers 32, 33. |
59 | 66 |
60 RegisterConfiguration test( | 67 RegisterConfiguration test( |
61 kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs, | 68 kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs, |
62 kNumAllocatableDoubleRegs, general_codes, double_codes, | 69 kNumAllocatableDoubleRegs, general_codes, double_codes, |
63 RegisterConfiguration::COMBINE, nullptr, nullptr, nullptr); | 70 RegisterConfiguration::COMBINE, nullptr, nullptr, nullptr, nullptr); |
64 | 71 |
65 // There are 3 allocatable double regs, but only 2 can alias float regs. | 72 // There are 3 allocatable double regs, but only 2 can alias float regs. |
66 EXPECT_EQ(test.num_allocatable_float_registers(), 4); | 73 EXPECT_EQ(test.num_allocatable_float_registers(), 4); |
67 | 74 |
68 // Test that float registers combine in pairs to form double registers. | 75 // Test that float registers combine in pairs to form double registers. |
69 EXPECT_EQ(test.GetAllocatableFloatCode(0), double_codes[0] * 2); | 76 EXPECT_EQ(test.GetAllocatableFloatCode(0), double_codes[0] * 2); |
70 EXPECT_EQ(test.GetAllocatableFloatCode(1), double_codes[0] * 2 + 1); | 77 EXPECT_EQ(test.GetAllocatableFloatCode(1), double_codes[0] * 2 + 1); |
71 EXPECT_EQ(test.GetAllocatableFloatCode(2), double_codes[1] * 2); | 78 EXPECT_EQ(test.GetAllocatableFloatCode(2), double_codes[1] * 2); |
72 EXPECT_EQ(test.GetAllocatableFloatCode(3), double_codes[1] * 2 + 1); | 79 EXPECT_EQ(test.GetAllocatableFloatCode(3), double_codes[1] * 2 + 1); |
73 | 80 |
| 81 // There are 3 allocatable double regs, but only 2 pair to form 1 SIMD reg. |
| 82 EXPECT_EQ(test.num_allocatable_simd128_registers(), 1); |
| 83 |
| 84 // Test that even-odd pairs of double regs combine to form a SIMD reg. |
| 85 EXPECT_EQ(test.GetAllocatableSimd128Code(0), double_codes[0] / 2); |
| 86 |
74 // Registers alias themselves. | 87 // Registers alias themselves. |
75 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat32, 0)); | 88 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat32, 0)); |
76 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat64, 0)); | 89 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat64, 0)); |
| 90 EXPECT_TRUE(test.AreAliases(kSimd128, 0, kSimd128, 0)); |
77 // Registers don't alias other registers of the same size. | 91 // Registers don't alias other registers of the same size. |
78 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat32, 0)); | 92 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat32, 0)); |
79 EXPECT_FALSE(test.AreAliases(kFloat64, 1, kFloat64, 0)); | 93 EXPECT_FALSE(test.AreAliases(kFloat64, 1, kFloat64, 0)); |
80 // Float registers combine in pairs and alias double registers. | 94 EXPECT_FALSE(test.AreAliases(kSimd128, 1, kSimd128, 0)); |
| 95 // Float registers combine in pairs to alias a double with index / 2, and |
| 96 // in 4's to alias a simd128 with index / 4. |
81 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat64, 0)); | 97 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat64, 0)); |
82 EXPECT_TRUE(test.AreAliases(kFloat32, 1, kFloat64, 0)); | 98 EXPECT_TRUE(test.AreAliases(kFloat32, 1, kFloat64, 0)); |
| 99 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kSimd128, 0)); |
| 100 EXPECT_TRUE(test.AreAliases(kFloat32, 1, kSimd128, 0)); |
| 101 EXPECT_TRUE(test.AreAliases(kFloat32, 2, kSimd128, 0)); |
| 102 EXPECT_TRUE(test.AreAliases(kFloat32, 3, kSimd128, 0)); |
83 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 0)); | 103 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 0)); |
84 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1)); | 104 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1)); |
| 105 EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 0)); |
| 106 EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 1)); |
| 107 EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 2)); |
| 108 EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat32, 3)); |
85 | 109 |
86 EXPECT_FALSE(test.AreAliases(kFloat32, 0, kFloat64, 1)); | 110 EXPECT_FALSE(test.AreAliases(kFloat32, 0, kFloat64, 1)); |
87 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat64, 1)); | 111 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat64, 1)); |
| 112 EXPECT_FALSE(test.AreAliases(kFloat32, 0, kSimd128, 1)); |
| 113 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kSimd128, 1)); |
| 114 EXPECT_FALSE(test.AreAliases(kFloat64, 0, kSimd128, 1)); |
| 115 EXPECT_FALSE(test.AreAliases(kFloat64, 1, kSimd128, 1)); |
88 | 116 |
89 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1)); | 117 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1)); |
90 EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 2)); | 118 EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 2)); |
91 EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 3)); | 119 EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 3)); |
92 EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 4)); | 120 EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 4)); |
93 EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 5)); | 121 EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 5)); |
94 | 122 |
| 123 EXPECT_TRUE(test.AreAliases(kSimd128, 0, kFloat64, 1)); |
| 124 EXPECT_TRUE(test.AreAliases(kSimd128, 1, kFloat64, 2)); |
| 125 EXPECT_TRUE(test.AreAliases(kSimd128, 1, kFloat64, 3)); |
| 126 EXPECT_TRUE(test.AreAliases(kSimd128, 2, kFloat64, 4)); |
| 127 EXPECT_TRUE(test.AreAliases(kSimd128, 2, kFloat64, 5)); |
| 128 |
95 int alias_base_index = -1; | 129 int alias_base_index = -1; |
96 EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat32, &alias_base_index), 1); | 130 EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat32, &alias_base_index), 1); |
97 EXPECT_EQ(alias_base_index, 0); | 131 EXPECT_EQ(alias_base_index, 0); |
98 EXPECT_EQ(test.GetAliases(kFloat64, 1, kFloat64, &alias_base_index), 1); | 132 EXPECT_EQ(test.GetAliases(kFloat64, 1, kFloat64, &alias_base_index), 1); |
99 EXPECT_EQ(alias_base_index, 1); | 133 EXPECT_EQ(alias_base_index, 1); |
100 EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat64, &alias_base_index), 1); | 134 EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat64, &alias_base_index), 1); |
101 EXPECT_EQ(alias_base_index, 0); | 135 EXPECT_EQ(alias_base_index, 0); |
102 EXPECT_EQ(test.GetAliases(kFloat32, 1, kFloat64, &alias_base_index), 1); | 136 EXPECT_EQ(test.GetAliases(kFloat32, 1, kFloat64, &alias_base_index), 1); |
103 EXPECT_EQ(test.GetAliases(kFloat32, 2, kFloat64, &alias_base_index), 1); | 137 EXPECT_EQ(test.GetAliases(kFloat32, 2, kFloat64, &alias_base_index), 1); |
104 EXPECT_EQ(alias_base_index, 1); | 138 EXPECT_EQ(alias_base_index, 1); |
105 EXPECT_EQ(test.GetAliases(kFloat32, 3, kFloat64, &alias_base_index), 1); | 139 EXPECT_EQ(test.GetAliases(kFloat32, 3, kFloat64, &alias_base_index), 1); |
106 EXPECT_EQ(alias_base_index, 1); | 140 EXPECT_EQ(alias_base_index, 1); |
107 EXPECT_EQ(test.GetAliases(kFloat64, 0, kFloat32, &alias_base_index), 2); | 141 EXPECT_EQ(test.GetAliases(kFloat64, 0, kFloat32, &alias_base_index), 2); |
108 EXPECT_EQ(alias_base_index, 0); | 142 EXPECT_EQ(alias_base_index, 0); |
109 EXPECT_EQ(test.GetAliases(kFloat64, 1, kFloat32, &alias_base_index), 2); | 143 EXPECT_EQ(test.GetAliases(kFloat64, 1, kFloat32, &alias_base_index), 2); |
110 EXPECT_EQ(alias_base_index, 2); | 144 EXPECT_EQ(alias_base_index, 2); |
111 | 145 |
112 // Non-allocatable codes still alias. | 146 // Non-allocatable codes still alias. |
113 EXPECT_EQ(test.GetAliases(kFloat64, 2, kFloat32, &alias_base_index), 2); | 147 EXPECT_EQ(test.GetAliases(kFloat64, 2, kFloat32, &alias_base_index), 2); |
114 EXPECT_EQ(alias_base_index, 4); | 148 EXPECT_EQ(alias_base_index, 4); |
115 // High numbered double registers don't alias nonexistent single registers. | 149 // High numbered double and simd regs don't alias nonexistent float registers. |
116 EXPECT_EQ( | 150 EXPECT_EQ( |
117 test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2, | 151 test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2, |
118 kFloat32, &alias_base_index), | 152 kFloat32, &alias_base_index), |
119 0); | 153 0); |
120 EXPECT_EQ( | 154 EXPECT_EQ( |
121 test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2 + 1, | 155 test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2 + 1, |
122 kFloat32, &alias_base_index), | 156 kFloat32, &alias_base_index), |
123 0); | 157 0); |
124 EXPECT_EQ(test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters, | 158 EXPECT_EQ(test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters, |
125 kFloat32, &alias_base_index), | 159 kFloat32, &alias_base_index), |
126 0); | 160 0); |
127 } | 161 } |
128 | 162 |
129 } // namespace internal | 163 } // namespace internal |
130 } // namespace v8 | 164 } // namespace v8 |
OLD | NEW |