| Index: src/compiler/ia32/instruction-selector-ia32-unittest.cc
|
| diff --git a/src/compiler/ia32/instruction-selector-ia32-unittest.cc b/src/compiler/ia32/instruction-selector-ia32-unittest.cc
|
| index 50e1358d17569fc6ae5fb8ddaddd1f48e7d1185c..89d150f26e4e8d73e8166ae8f6bd44106de25f41 100644
|
| --- a/src/compiler/ia32/instruction-selector-ia32-unittest.cc
|
| +++ b/src/compiler/ia32/instruction-selector-ia32-unittest.cc
|
| @@ -189,9 +189,13 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateBase) {
|
| Stream s = m.Build();
|
| ASSERT_EQ(1U, s.size());
|
| EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
|
| + if (base == 0) {
|
| + ASSERT_EQ(1U, s[0]->InputCount());
|
| + } else {
|
| ASSERT_EQ(2U, s[0]->InputCount());
|
| ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
|
| EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
|
| + }
|
| EXPECT_EQ(1U, s[0]->OutputCount());
|
| }
|
| }
|
| @@ -205,9 +209,13 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
|
| Stream s = m.Build();
|
| ASSERT_EQ(1U, s.size());
|
| EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
|
| + if (index == 0) {
|
| + ASSERT_EQ(1U, s[0]->InputCount());
|
| + } else {
|
| ASSERT_EQ(2U, s[0]->InputCount());
|
| ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
|
| EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
|
| + }
|
| EXPECT_EQ(1U, s[0]->OutputCount());
|
| }
|
| }
|
| @@ -235,9 +243,13 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
|
| Stream s = m.Build();
|
| ASSERT_EQ(1U, s.size());
|
| EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
|
| + if (base == 0) {
|
| + ASSERT_EQ(2U, s[0]->InputCount());
|
| + } else {
|
| ASSERT_EQ(3U, s[0]->InputCount());
|
| ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
|
| EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
|
| + }
|
| EXPECT_EQ(0U, s[0]->OutputCount());
|
| }
|
| }
|
| @@ -253,9 +265,13 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
|
| Stream s = m.Build();
|
| ASSERT_EQ(1U, s.size());
|
| EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
|
| - ASSERT_EQ(3U, s[0]->InputCount());
|
| - ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
|
| - EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
|
| + if (index == 0) {
|
| + ASSERT_EQ(2U, s[0]->InputCount());
|
| + } else {
|
| + ASSERT_EQ(3U, s[0]->InputCount());
|
| + ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
|
| + EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
|
| + }
|
| EXPECT_EQ(0U, s[0]->OutputCount());
|
| }
|
| }
|
| @@ -265,6 +281,149 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
|
| InstructionSelectorMemoryAccessTest,
|
| ::testing::ValuesIn(kMemoryAccesses));
|
|
|
| +
|
| +// -----------------------------------------------------------------------------
|
| +// AddressingMode for loads and stores.
|
| +
|
| +class AddressingModeUnitTest : public InstructionSelectorTest {
|
| + public:
|
| + AddressingModeUnitTest() : m(NULL) { Reset(); }
|
| + ~AddressingModeUnitTest() { delete m; }
|
| +
|
| + void Run(Node* base, Node* index, AddressingMode mode) {
|
| + Node* load = m->Load(kMachInt32, base, index);
|
| + m->Store(kMachInt32, base, index, load);
|
| + m->Return(m->Int32Constant(0));
|
| + Stream s = m->Build();
|
| + ASSERT_EQ(2U, s.size());
|
| + EXPECT_EQ(mode, s[0]->addressing_mode());
|
| + EXPECT_EQ(mode, s[1]->addressing_mode());
|
| + }
|
| +
|
| + Node* zero;
|
| + Node* null_ptr;
|
| + Node* non_zero;
|
| + Node* base_reg; // opaque value to generate base as register
|
| + Node* index_reg; // opaque value to generate index as register
|
| + Node* scales[4];
|
| + StreamBuilder* m;
|
| +
|
| + void Reset() {
|
| + delete m;
|
| + m = new StreamBuilder(this, kMachInt32, kMachInt32, kMachInt32);
|
| + zero = m->Int32Constant(0);
|
| + null_ptr = m->Int32Constant(0);
|
| + non_zero = m->Int32Constant(127);
|
| + base_reg = m->Parameter(0);
|
| + index_reg = m->Parameter(0);
|
| +
|
| + scales[0] = m->Int32Constant(1);
|
| + scales[1] = m->Int32Constant(2);
|
| + scales[2] = m->Int32Constant(4);
|
| + scales[3] = m->Int32Constant(8);
|
| + }
|
| +};
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MR) {
|
| + Node* base = base_reg;
|
| + Node* index = zero;
|
| + Run(base, index, kMode_MR);
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MRI) {
|
| + Node* base = base_reg;
|
| + Node* index = non_zero;
|
| + Run(base, index, kMode_MRI);
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MR1) {
|
| + Node* base = base_reg;
|
| + Node* index = index_reg;
|
| + Run(base, index, kMode_MR1);
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MRN) {
|
| + AddressingMode expected[] = {kMode_MR1, kMode_MR2, kMode_MR4, kMode_MR8};
|
| + for (size_t i = 0; i < arraysize(scales); ++i) {
|
| + Reset();
|
| + Node* base = base_reg;
|
| + Node* index = m->Int32Mul(index_reg, scales[i]);
|
| + Run(base, index, expected[i]);
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MR1I) {
|
| + Node* base = base_reg;
|
| + Node* index = m->Int32Add(index_reg, non_zero);
|
| + Run(base, index, kMode_MR1I);
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MRNI) {
|
| + AddressingMode expected[] = {kMode_MR1I, kMode_MR2I, kMode_MR4I, kMode_MR8I};
|
| + for (size_t i = 0; i < arraysize(scales); ++i) {
|
| + Reset();
|
| + Node* base = base_reg;
|
| + Node* index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
|
| + Run(base, index, expected[i]);
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_M1) {
|
| + Node* base = null_ptr;
|
| + Node* index = index_reg;
|
| + Run(base, index, kMode_MR);
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MN) {
|
| + AddressingMode expected[] = {kMode_MR, kMode_M2, kMode_M4, kMode_M8};
|
| + for (size_t i = 0; i < arraysize(scales); ++i) {
|
| + Reset();
|
| + Node* base = null_ptr;
|
| + Node* index = m->Int32Mul(index_reg, scales[i]);
|
| + Run(base, index, expected[i]);
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_M1I) {
|
| + Node* base = null_ptr;
|
| + Node* index = m->Int32Add(index_reg, non_zero);
|
| + Run(base, index, kMode_MRI);
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MNI) {
|
| + AddressingMode expected[] = {kMode_MRI, kMode_M2I, kMode_M4I, kMode_M8I};
|
| + for (size_t i = 0; i < arraysize(scales); ++i) {
|
| + Reset();
|
| + Node* base = null_ptr;
|
| + Node* index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
|
| + Run(base, index, expected[i]);
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST_F(AddressingModeUnitTest, AddressingMode_MI) {
|
| + Node* bases[] = {null_ptr, non_zero};
|
| + Node* indices[] = {zero, non_zero};
|
| + for (size_t i = 0; i < arraysize(bases); ++i) {
|
| + for (size_t j = 0; j < arraysize(indices); ++j) {
|
| + Reset();
|
| + Node* base = bases[i];
|
| + Node* index = indices[j];
|
| + Run(base, index, kMode_MI);
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|