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
3 // found in the LICENSE file.
4
5 #include "src/register-configuration.h"
6 #include "testing/gtest-support.h"
7
8 namespace v8 {
9 namespace internal {
10
11 const MachineRepresentation kFloat32 = MachineRepresentation::kFloat32;
12 const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64;
13
14 class RegisterConfigurationUnitTest : public ::testing::Test {
15 public:
RegisterConfigurationUnitTest()16 RegisterConfigurationUnitTest() {}
~RegisterConfigurationUnitTest()17 virtual ~RegisterConfigurationUnitTest() {}
18
19 private:
20 };
21
TEST_F(RegisterConfigurationUnitTest,BasicProperties)22 TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
23 const int kNumGeneralRegs = 3;
24 const int kNumDoubleRegs = 4;
25 const int kNumAllocatableGeneralRegs = 2;
26 const int kNumAllocatableDoubleRegs = 2;
27 int general_codes[kNumAllocatableGeneralRegs] = {1, 2};
28 int double_codes[kNumAllocatableDoubleRegs] = {2, 3};
29
30 RegisterConfiguration test(
31 kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs,
32 kNumAllocatableDoubleRegs, general_codes, double_codes,
33 RegisterConfiguration::OVERLAP, nullptr, nullptr, nullptr);
34
35 EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs);
36 EXPECT_EQ(test.num_double_registers(), kNumDoubleRegs);
37 EXPECT_EQ(test.num_allocatable_general_registers(),
38 kNumAllocatableGeneralRegs);
39 EXPECT_EQ(test.num_allocatable_double_registers(), kNumAllocatableDoubleRegs);
40 EXPECT_EQ(test.num_allocatable_float_registers(), kNumAllocatableDoubleRegs);
41
42 EXPECT_EQ(test.allocatable_general_codes_mask(),
43 (1 << general_codes[0]) | (1 << general_codes[1]));
44 EXPECT_EQ(test.GetAllocatableGeneralCode(0), general_codes[0]);
45 EXPECT_EQ(test.GetAllocatableGeneralCode(1), general_codes[1]);
46 EXPECT_EQ(test.allocatable_double_codes_mask(),
47 (1 << double_codes[0]) | (1 << double_codes[1]));
48 EXPECT_EQ(test.GetAllocatableDoubleCode(0), double_codes[0]);
49 EXPECT_EQ(test.GetAllocatableDoubleCode(1), double_codes[1]);
50 }
51
TEST_F(RegisterConfigurationUnitTest,Aliasing)52 TEST_F(RegisterConfigurationUnitTest, Aliasing) {
53 const int kNumGeneralRegs = 3;
54 const int kNumDoubleRegs = 4;
55 const int kNumAllocatableGeneralRegs = 2;
56 const int kNumAllocatableDoubleRegs = 3;
57 int general_codes[] = {1, 2};
58 int double_codes[] = {2, 3, 16}; // reg 16 should not alias registers 32, 33.
59
60 RegisterConfiguration test(
61 kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs,
62 kNumAllocatableDoubleRegs, general_codes, double_codes,
63 RegisterConfiguration::COMBINE, nullptr, nullptr, nullptr);
64
65 // There are 3 allocatable double regs, but only 2 can alias float regs.
66 EXPECT_EQ(test.num_allocatable_float_registers(), 4);
67
68 // Test that float registers combine in pairs to form double registers.
69 EXPECT_EQ(test.GetAllocatableFloatCode(0), double_codes[0] * 2);
70 EXPECT_EQ(test.GetAllocatableFloatCode(1), double_codes[0] * 2 + 1);
71 EXPECT_EQ(test.GetAllocatableFloatCode(2), double_codes[1] * 2);
72 EXPECT_EQ(test.GetAllocatableFloatCode(3), double_codes[1] * 2 + 1);
73
74 // Registers alias themselves.
75 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat32, 0));
76 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat64, 0));
77 // Registers don't alias other registers of the same size.
78 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat32, 0));
79 EXPECT_FALSE(test.AreAliases(kFloat64, 1, kFloat64, 0));
80 // Float registers combine in pairs and alias double registers.
81 EXPECT_TRUE(test.AreAliases(kFloat32, 0, kFloat64, 0));
82 EXPECT_TRUE(test.AreAliases(kFloat32, 1, kFloat64, 0));
83 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 0));
84 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1));
85
86 EXPECT_FALSE(test.AreAliases(kFloat32, 0, kFloat64, 1));
87 EXPECT_FALSE(test.AreAliases(kFloat32, 1, kFloat64, 1));
88
89 EXPECT_TRUE(test.AreAliases(kFloat64, 0, kFloat32, 1));
90 EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 2));
91 EXPECT_TRUE(test.AreAliases(kFloat64, 1, kFloat32, 3));
92 EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 4));
93 EXPECT_TRUE(test.AreAliases(kFloat64, 2, kFloat32, 5));
94
95 int alias_base_index = -1;
96 EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat32, &alias_base_index), 1);
97 EXPECT_EQ(alias_base_index, 0);
98 EXPECT_EQ(test.GetAliases(kFloat64, 1, kFloat64, &alias_base_index), 1);
99 EXPECT_EQ(alias_base_index, 1);
100 EXPECT_EQ(test.GetAliases(kFloat32, 0, kFloat64, &alias_base_index), 1);
101 EXPECT_EQ(alias_base_index, 0);
102 EXPECT_EQ(test.GetAliases(kFloat32, 1, kFloat64, &alias_base_index), 1);
103 EXPECT_EQ(test.GetAliases(kFloat32, 2, kFloat64, &alias_base_index), 1);
104 EXPECT_EQ(alias_base_index, 1);
105 EXPECT_EQ(test.GetAliases(kFloat32, 3, kFloat64, &alias_base_index), 1);
106 EXPECT_EQ(alias_base_index, 1);
107 EXPECT_EQ(test.GetAliases(kFloat64, 0, kFloat32, &alias_base_index), 2);
108 EXPECT_EQ(alias_base_index, 0);
109 EXPECT_EQ(test.GetAliases(kFloat64, 1, kFloat32, &alias_base_index), 2);
110 EXPECT_EQ(alias_base_index, 2);
111
112 // Non-allocatable codes still alias.
113 EXPECT_EQ(test.GetAliases(kFloat64, 2, kFloat32, &alias_base_index), 2);
114 EXPECT_EQ(alias_base_index, 4);
115 // High numbered double registers don't alias nonexistent single registers.
116 EXPECT_EQ(
117 test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2,
118 kFloat32, &alias_base_index),
119 0);
120 EXPECT_EQ(
121 test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters / 2 + 1,
122 kFloat32, &alias_base_index),
123 0);
124 EXPECT_EQ(test.GetAliases(kFloat64, RegisterConfiguration::kMaxFPRegisters,
125 kFloat32, &alias_base_index),
126 0);
127 }
128
129 } // namespace internal
130 } // namespace v8
131