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
8namespace v8 {
9namespace internal {
10
11const MachineRepresentation kFloat32 = MachineRepresentation::kFloat32;
12const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64;
13
14class RegisterConfigurationUnitTest : public ::testing::Test {
15 public:
16  RegisterConfigurationUnitTest() {}
17  virtual ~RegisterConfigurationUnitTest() {}
18
19 private:
20};
21
22TEST_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
52TEST_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