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