Revision: 23111
Author:   bmeu...@chromium.org
Date:     Thu Aug 14 06:33:50 2014 UTC
Log:      [turbofan] Refactor the InstructionSelector tests.

Also fix some issues and improve test coverage.

TEST=compiler-unittests
BUG=v8:3489
LOG=y
R=ja...@chromium.org

Review URL: https://codereview.chromium.org/469743002
http://code.google.com/p/v8/source/detail?r=23111

Added:
 /branches/bleeding_edge/test/compiler-unittests/arm64
/branches/bleeding_edge/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/ia32
/branches/bleeding_edge/test/compiler-unittests/ia32/instruction-selector-ia32-unittest.cc
 /branches/bleeding_edge/testing/gtest-support.h
Deleted:
/branches/bleeding_edge/test/cctest/compiler/test-instruction-selector-arm.cc /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector-arm64.cc /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector-ia32.cc
 /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector.cc
 /branches/bleeding_edge/testing/gtest-type-names.h
Modified:
 /branches/bleeding_edge/src/compiler/arm/instruction-selector-arm.cc
 /branches/bleeding_edge/src/compiler/machine-node-factory.h
 /branches/bleeding_edge/test/cctest/cctest.gyp
 /branches/bleeding_edge/test/compiler-unittests/DEPS
/branches/bleeding_edge/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.gyp
 /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h
/branches/bleeding_edge/test/compiler-unittests/instruction-selector-unittest.cc /branches/bleeding_edge/test/compiler-unittests/instruction-selector-unittest.h
 /branches/bleeding_edge/testing/gtest.gyp

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc Thu Aug 14 06:33:50 2014 UTC
@@ -0,0 +1,133 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <list>
+
+#include "test/compiler-unittests/instruction-selector-unittest.h"
+
+#include "test/cctest/compiler/instruction-selector-tester.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
+
+struct DPI {
+  Constructor constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
+  return os << dpi.constructor_name;
+}
+
+
+// ARM64 Logical instructions.
+static const DPI kLogicalInstructions[] = {
+    {&RawMachineAssembler::Word32And, "Word32And", kArm64And32},
+    {&RawMachineAssembler::Word64And, "Word64And", kArm64And},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32},
+    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32},
+    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor}};
+
+
+// ARM64 Arithmetic instructions.
+static const DPI kAddSubInstructions[] = {
+    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32},
+    {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32},
+    {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub}};
+
+
+// ARM64 Add/Sub immediates.
+// TODO(all): Test only a subset of the immediates, similar to what we do for
+// arm. Unit tests should be really fast!
+class AddSubImmediates V8_FINAL : public std::list<int32_t> {
+ public:
+  AddSubImmediates() {
+    for (int32_t imm12 = 0; imm12 < 4096; ++imm12) {
+      CHECK(Assembler::IsImmAddSub(imm12));
+      CHECK(Assembler::IsImmAddSub(imm12 << 12));
+      push_back(imm12);
+      push_back(imm12 << 12);
+    }
+  }
+};
+
+
+// ARM64 Mul/Div instructions.
+static const DPI kMulDivInstructions[] = {
+    {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32},
+    {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul},
+    {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32},
+    {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv},
+    {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32},
+    {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv}};
+
+}  // namespace
+
+
+// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
+TEST_F(InstructionSelectorTest, LogicalWithParameter) {
+  TRACED_FOREACH(DPI, dpi, kLogicalInstructions) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  }
+}
+
+
+// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
+TEST_F(InstructionSelectorTest, AddSubWithParameter) {
+  TRACED_FOREACH(DPI, dpi, kAddSubInstructions) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  }
+}
+
+
+// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
+TEST_F(InstructionSelectorTest, AddSubWithImmediate) {
+  AddSubImmediates immediates;
+  TRACED_FOREACH(DPI, dpi, kAddSubInstructions) {
+    for (AddSubImmediates::const_iterator j = immediates.begin();
+         j != immediates.end(); ++j) {
+      int32_t imm = *j;
+      SCOPED_TRACE(::testing::Message() << "imm = " << imm);
+      StreamBuilder m(this, kMachineWord32, kMachineWord32);
+      m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+    }
+  }
+}
+
+
+// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
+TEST_F(InstructionSelectorTest, MulDivWithParameter) {
+  TRACED_FOREACH(DPI, dpi, kMulDivInstructions) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/compiler-unittests/ia32/instruction-selector-ia32-unittest.cc Thu Aug 14 06:33:50 2014 UTC
@@ -0,0 +1,78 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/compiler-unittests/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+// Immediates (random subset).
+static const int32_t kImmediates[] = {
+    kMinInt, -42, -1, 0,  1,  2,    3,      4,          5,
+    6,       7,   8,  16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt};
+
+}  // namespace
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithParameter) {
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kIA32Add, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithImmediate) {
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    {
+      StreamBuilder m(this, kMachineWord32, kMachineWord32);
+      m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kIA32Add, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    }
+    {
+      StreamBuilder m(this, kMachineWord32, kMachineWord32);
+      m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kIA32Add, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubWithParameter) {
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kIA32Sub, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubWithImmediate) {
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kIA32Sub, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
=======================================
--- /dev/null
+++ /branches/bleeding_edge/testing/gtest-support.h Thu Aug 14 06:33:50 2014 UTC
@@ -0,0 +1,58 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_TESTING_GTEST_SUPPORT_H_
+#define V8_TESTING_GTEST_SUPPORT_H_
+
+#include "include/v8stdint.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace testing {
+namespace internal {
+
+#define GET_TYPE_NAME(type)                \
+  template <>                              \
+  inline std::string GetTypeName<type>() { \
+    return #type;                          \
+  }
+GET_TYPE_NAME(int8_t)
+GET_TYPE_NAME(uint8_t)
+GET_TYPE_NAME(int16_t)
+GET_TYPE_NAME(uint16_t)
+GET_TYPE_NAME(int32_t)
+GET_TYPE_NAME(uint32_t)
+GET_TYPE_NAME(int64_t)
+GET_TYPE_NAME(uint64_t)
+GET_TYPE_NAME(float)
+GET_TYPE_NAME(double)
+#undef GET_TYPE_NAME
+
+
+// TRACED_FOREACH(type, var, array) expands to a loop that assigns |var| every +// item in the |array| and adds a SCOPED_TRACE() message for the |var| while
+// inside the loop body.
+// TODO(bmeurer): Migrate to C++11 once we're ready.
+#define TRACED_FOREACH(_type, _var, _array) \ + for (size_t _i = 0; _i < ARRAY_SIZE(_array); ++_i) \ + for (bool _done = false; !_done;) \ + for (const _type _var = _array[_i]; !_done;) \ + for (SCOPED_TRACE(::testing::Message() << #_var << " = " << _var); \
+             !_done; _done = true)
+
+
+// TRACED_FORRANGE(type, var, low, high) expands to a loop that assigns | var|
+// every value in the range |low| to (including) |high| and adds a
+// SCOPED_TRACE() message for the |var| while inside the loop body.
+// TODO(bmeurer): Migrate to C++11 once we're ready.
+#define TRACED_FORRANGE(_type, _var, _low, _high) \ + for (_type _i = _low; _i <= _high; ++_i) \ + for (bool _done = false; !_done;) \ + for (const _type _var = _i; !_done;) \ + for (SCOPED_TRACE(::testing::Message() << #_var << " = " << _var); \
+             !_done; _done = true)
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // V8_TESTING_GTEST_SUPPORT_H_
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector-arm.cc Tue Aug 5 13:26:55 2014 UTC
+++ /dev/null
@@ -1,1863 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <list>
-
-#include "test/cctest/compiler/instruction-selector-tester.h"
-#include "test/cctest/compiler/value-helper.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-namespace {
-
-typedef RawMachineAssembler::Label MLabel;
-
-struct DPI {
-  Operator* op;
-  ArchOpcode arch_opcode;
-  ArchOpcode reverse_arch_opcode;
-  ArchOpcode test_arch_opcode;
-};
-
-
-// ARM data processing instructions.
-class DPIs V8_FINAL : public std::list<DPI>, private HandleAndZoneScope {
- public:
-  DPIs() {
-    MachineOperatorBuilder machine(main_zone());
-    DPI and_ = {machine.Word32And(), kArmAnd, kArmAnd, kArmTst};
-    push_back(and_);
-    DPI or_ = {machine.Word32Or(), kArmOrr, kArmOrr, kArmOrr};
-    push_back(or_);
-    DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq};
-    push_back(xor_);
-    DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn};
-    push_back(add);
-    DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp};
-    push_back(sub);
-  }
-};
-
-
-struct ODPI {
-  Operator* op;
-  ArchOpcode arch_opcode;
-  ArchOpcode reverse_arch_opcode;
-};
-
-
-// ARM data processing instructions with overflow.
-class ODPIs V8_FINAL : public std::list<ODPI>, private HandleAndZoneScope {
- public:
-  ODPIs() {
-    MachineOperatorBuilder machine(main_zone());
-    ODPI add = {machine.Int32AddWithOverflow(), kArmAdd, kArmAdd};
-    push_back(add);
-    ODPI sub = {machine.Int32SubWithOverflow(), kArmSub, kArmRsb};
-    push_back(sub);
-  }
-};
-
-
-// ARM immediates.
-class Immediates V8_FINAL : public std::list<int32_t> {
- public:
-  Immediates() {
-    for (uint32_t imm8 = 0; imm8 < 256; ++imm8) {
-      for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) {
-        int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4));
-        CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm));
-        push_back(imm);
-      }
-    }
-  }
-};
-
-
-struct Shift {
-  Operator* op;
-  int32_t i_low;          // lowest possible immediate
-  int32_t i_high;         // highest possible immediate
-  AddressingMode i_mode;  // Operand2_R_<shift>_I
-  AddressingMode r_mode;  // Operand2_R_<shift>_R
-};
-
-
-// ARM shifts.
-class Shifts V8_FINAL : public std::list<Shift>, private HandleAndZoneScope {
- public:
-  Shifts() {
-    MachineOperatorBuilder machine(main_zone());
-    Shift sar = {machine.Word32Sar(), 1, 32, kMode_Operand2_R_ASR_I,
-                 kMode_Operand2_R_ASR_R};
-    Shift shl = {machine.Word32Shl(), 0, 31, kMode_Operand2_R_LSL_I,
-                 kMode_Operand2_R_LSL_R};
-    Shift shr = {machine.Word32Shr(), 1, 32, kMode_Operand2_R_LSR_I,
-                 kMode_Operand2_R_LSR_R};
-    push_back(sar);
-    push_back(shl);
-    push_back(shr);
-  }
-};
-
-}  // namespace
-
-
-TEST(InstructionSelectorDPIP) {
-  DPIs dpis;
-  for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
-    DPI dpi = *i;
-    InstructionSelectorTester m;
-    m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-}
-
-
-TEST(InstructionSelectorDPIImm) {
-  DPIs dpis;
-  Immediates immediates;
-  for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
-    DPI dpi = *i;
-    for (Immediates::const_iterator j = immediates.begin();
-         j != immediates.end(); ++j) {
-      int32_t imm = *j;
-      {
-        InstructionSelectorTester m;
-        m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorDPIAndShiftP) {
-  DPIs dpis;
-  Shifts shifts;
-  for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
-    DPI dpi = *i;
- for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
-      Shift shift = *j;
-      {
-        InstructionSelectorTester m;
-        m.Return(
-            m.NewNode(dpi.op, m.Parameter(0),
- m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.NewNode(dpi.op,
- m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
-                           m.Parameter(2)));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorDPIAndRotateRightP) {
-  DPIs dpis;
-  for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
-    DPI dpi = *i;
-    {
-      InstructionSelectorTester m;
-      Node* value = m.Parameter(1);
-      Node* shift = m.Parameter(2);
-      Node* ror = m.Word32Or(
-          m.Word32Shr(value, shift),
-          m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
-      m.Return(m.NewNode(dpi.op, m.Parameter(0), ror));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
-      Node* value = m.Parameter(1);
-      Node* shift = m.Parameter(2);
-      Node* ror =
- m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
-                     m.Word32Shr(value, shift));
-      m.Return(m.NewNode(dpi.op, m.Parameter(0), ror));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
-      Node* value = m.Parameter(1);
-      Node* shift = m.Parameter(2);
-      Node* ror = m.Word32Or(
-          m.Word32Shr(value, shift),
-          m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
-      m.Return(m.NewNode(dpi.op, ror, m.Parameter(0)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
-      Node* value = m.Parameter(1);
-      Node* shift = m.Parameter(2);
-      Node* ror =
- m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
-                     m.Word32Shr(value, shift));
-      m.Return(m.NewNode(dpi.op, ror, m.Parameter(0)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
-    }
-  }
-}
-
-
-TEST(InstructionSelectorDPIAndShiftImm) {
-  DPIs dpis;
-  Shifts shifts;
-  for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
-    DPI dpi = *i;
- for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
-      Shift shift = *j;
-      for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
-        {
-          InstructionSelectorTester m;
-          m.Return(m.NewNode(
-              dpi.op, m.Parameter(0),
-              m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm))));
-          m.SelectInstructions();
-          CHECK_EQ(1, m.code.size());
-          CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-        }
-        {
-          InstructionSelectorTester m;
-          m.Return(m.NewNode(
- dpi.op, m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)),
-              m.Parameter(1)));
-          m.SelectInstructions();
-          CHECK_EQ(1, m.code.size());
-          CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-        }
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorODPIP) {
-  ODPIs odpis;
-  for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
-    ODPI odpi = *i;
-    {
-      InstructionSelectorTester m;
-      m.Return(
- m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-      CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-      CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_LE(1, m.code[0]->OutputCount());
-    }
-    {
-      InstructionSelectorTester m;
-      m.Return(
- m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-      CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_LE(1, m.code[0]->OutputCount());
-    }
-    {
-      InstructionSelectorTester m;
-      Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1));
- m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-      m.SelectInstructions();
-      CHECK_LE(1, m.code.size());
-      CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-      CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-      CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_EQ(2, m.code[0]->OutputCount());
-    }
-  }
-}
-
-
-TEST(InstructionSelectorODPIImm) {
-  ODPIs odpis;
-  Immediates immediates;
-  for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
-    ODPI odpi = *i;
-    for (Immediates::const_iterator j = immediates.begin();
-         j != immediates.end(); ++j) {
-      int32_t imm = *j;
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            1, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(2, m.code[0]->InputCount());
-        CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            1, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(2, m.code[0]->InputCount());
-        CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            0, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-        CHECK_EQ(2, m.code[0]->InputCount());
-        CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            0, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-        CHECK_EQ(2, m.code[0]->InputCount());
-        CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
- Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)); - m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-        m.SelectInstructions();
-        CHECK_LE(1, m.code.size());
-        CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(2, m.code[0]->InputCount());
-        CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_EQ(2, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
- Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)); - m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-        m.SelectInstructions();
-        CHECK_LE(1, m.code.size());
-        CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(2, m.code[0]->InputCount());
-        CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_EQ(2, m.code[0]->OutputCount());
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorODPIAndShiftP) {
-  ODPIs odpis;
-  Shifts shifts;
-  for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
-    ODPI odpi = *i;
- for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
-      Shift shift = *j;
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            1, m.NewNode(odpi.op, m.Parameter(0),
- m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            1, m.NewNode(odpi.op,
- m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
-                         m.Parameter(2))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            0, m.NewNode(odpi.op, m.Parameter(0),
- m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(m.Projection(
-            0, m.NewNode(odpi.op,
- m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
-                         m.Parameter(2))));
-        m.SelectInstructions();
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_LE(1, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        Node* node =
-            m.NewNode(odpi.op, m.Parameter(0),
-                      m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)));
- m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-        m.SelectInstructions();
-        CHECK_LE(1, m.code.size());
-        CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_EQ(2, m.code[0]->OutputCount());
-      }
-      {
-        InstructionSelectorTester m;
-        Node* node = m.NewNode(
-            odpi.op, m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
-            m.Parameter(2));
- m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-        m.SelectInstructions();
-        CHECK_LE(1, m.code.size());
-        CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-        CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-        CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-        CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_EQ(2, m.code[0]->OutputCount());
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorODPIAndShiftImm) {
-  ODPIs odpis;
-  Shifts shifts;
-  for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
-    ODPI odpi = *i;
- for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
-      Shift shift = *j;
-      for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
-        {
-          InstructionSelectorTester m;
-          m.Return(m.Projection(1, m.NewNode(odpi.op, m.Parameter(0),
- m.NewNode(shift.op, m.Parameter(1), - m.Int32Constant(imm)))));
-          m.SelectInstructions();
-          CHECK_EQ(1, m.code.size());
-          CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-          CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-          CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-          CHECK_EQ(3, m.code[0]->InputCount());
-          CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
-          CHECK_LE(1, m.code[0]->OutputCount());
-        }
-        {
-          InstructionSelectorTester m;
-          m.Return(m.Projection(
-              1, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0),
-                                              m.Int32Constant(imm)),
-                           m.Parameter(1))));
-          m.SelectInstructions();
-          CHECK_EQ(1, m.code.size());
-          CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-          CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-          CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-          CHECK_EQ(3, m.code[0]->InputCount());
-          CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
-          CHECK_LE(1, m.code[0]->OutputCount());
-        }
-        {
-          InstructionSelectorTester m;
-          m.Return(m.Projection(0, m.NewNode(odpi.op, m.Parameter(0),
- m.NewNode(shift.op, m.Parameter(1), - m.Int32Constant(imm)))));
-          m.SelectInstructions();
-          CHECK_EQ(1, m.code.size());
-          CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-          CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-          CHECK_EQ(3, m.code[0]->InputCount());
-          CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
-          CHECK_LE(1, m.code[0]->OutputCount());
-        }
-        {
-          InstructionSelectorTester m;
-          m.Return(m.Projection(
-              0, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0),
-                                              m.Int32Constant(imm)),
-                           m.Parameter(1))));
-          m.SelectInstructions();
-          CHECK_EQ(1, m.code.size());
-          CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-          CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
-          CHECK_EQ(3, m.code[0]->InputCount());
-          CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
-          CHECK_LE(1, m.code[0]->OutputCount());
-        }
-        {
-          InstructionSelectorTester m;
-          Node* node = m.NewNode(
-              odpi.op, m.Parameter(0),
-              m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)));
- m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-          m.SelectInstructions();
-          CHECK_LE(1, m.code.size());
-          CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-          CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-          CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-          CHECK_EQ(3, m.code[0]->InputCount());
-          CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
-          CHECK_EQ(2, m.code[0]->OutputCount());
-        }
-        {
-          InstructionSelectorTester m;
- Node* node = m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0),
-                                                    m.Int32Constant(imm)),
-                                 m.Parameter(1));
- m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
-          m.SelectInstructions();
-          CHECK_LE(1, m.code.size());
-          CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
-          CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-          CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
-          CHECK_EQ(kOverflow, m.code[0]->flags_condition());
-          CHECK_EQ(3, m.code[0]->InputCount());
-          CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
-          CHECK_EQ(2, m.code[0]->OutputCount());
-        }
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) {
-  {
-    InstructionSelectorTester m;
-    m.Return(m.Word32And(m.Parameter(0),
- m.Word32Xor(m.Int32Constant(-1), m.Parameter(1))));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-  {
-    InstructionSelectorTester m;
-    m.Return(m.Word32And(m.Parameter(0),
- m.Word32Xor(m.Parameter(1), m.Int32Constant(-1))));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-  {
-    InstructionSelectorTester m;
-    m.Return(m.Word32And(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)),
-                         m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-  {
-    InstructionSelectorTester m;
-    m.Return(m.Word32And(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)),
-                         m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-}
-
-
-TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1AndShiftP) {
-  Shifts shifts;
-  for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
-    Shift shift = *i;
-    {
-      InstructionSelectorTester m;
-      m.Return(m.Word32And(
-          m.Parameter(0),
-          m.Word32Xor(m.Int32Constant(-1),
- m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
-      m.Return(m.Word32And(
-          m.Parameter(0),
-          m.Word32Xor(m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)),
-                      m.Int32Constant(-1))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
-      m.Return(m.Word32And(
-          m.Word32Xor(m.Int32Constant(-1),
-                      m.NewNode(shift.op, m.Parameter(0), m.Parameter(1))),
-          m.Parameter(2)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
-      m.Return(m.Word32And(
-          m.Word32Xor(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
-                      m.Int32Constant(-1)),
-          m.Parameter(2)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    }
-  }
-}
-
-
-TEST(InstructionSelectorWord32XorWithMinus1P) {
-  {
-    InstructionSelectorTester m;
-    m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-  {
-    InstructionSelectorTester m;
-    m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
-  }
-}
-
-
-TEST(InstructionSelectorWord32XorWithMinus1AndShiftP) {
-  Shifts shifts;
-  for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
-    Shift shift = *i;
-    {
-      InstructionSelectorTester m;
-      m.Return(
-          m.Word32Xor(m.Int32Constant(-1),
- m.NewNode(shift.op, m.Parameter(0), m.Parameter(1))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    }
-    {
-      InstructionSelectorTester m;
- m.Return(m.Word32Xor(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
-                           m.Int32Constant(-1)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    }
-  }
-}
-
-
-TEST(InstructionSelectorShiftP) {
-  Shifts shifts;
-  for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
-    Shift shift = *i;
-    InstructionSelectorTester m;
-    m.Return(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
-    CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
-    CHECK_EQ(2, m.code[0]->InputCount());
-  }
-}
-
-
-TEST(InstructionSelectorShiftImm) {
-  Shifts shifts;
-  for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
-    Shift shift = *i;
-    for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
-      InstructionSelectorTester m;
-      m.Return(m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
-      CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-    }
-  }
-}
-
-
-TEST(InstructionSelectorRotateRightP) {
-  {
-    InstructionSelectorTester m;
-    Node* value = m.Parameter(0);
-    Node* shift = m.Parameter(1);
-    m.Return(
-        m.Word32Or(m.Word32Shr(value, shift),
- m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
-    CHECK_EQ(2, m.code[0]->InputCount());
-  }
-  {
-    InstructionSelectorTester m;
-    Node* value = m.Parameter(0);
-    Node* shift = m.Parameter(1);
-    m.Return(
- m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
-                   m.Word32Shr(value, shift)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
-    CHECK_EQ(2, m.code[0]->InputCount());
-  }
-}
-
-
-TEST(InstructionSelectorRotateRightImm) {
-  FOR_INPUTS(uint32_t, ror, i) {
-    uint32_t shift = *i;
-    {
-      InstructionSelectorTester m;
-      Node* value = m.Parameter(0);
-      m.Return(m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
- m.Word32Shl(value, m.Int32Constant(32 - shift))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1)));
-    }
-    {
-      InstructionSelectorTester m;
-      Node* value = m.Parameter(0);
-      m.Return(m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
-                          m.Word32Shr(value, m.Int32Constant(shift))));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
-      CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1)));
-    }
-  }
-}
-
-
-TEST(InstructionSelectorInt32MulP) {
-  InstructionSelectorTester m;
-  m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
-  m.SelectInstructions();
-  CHECK_EQ(1, m.code.size());
-  CHECK_EQ(kArmMul, m.code[0]->arch_opcode());
-}
-
-
-TEST(InstructionSelectorInt32MulImm) {
-  // x * (2^k + 1) -> (x >> k) + x
-  for (int k = 1; k < 31; ++k) {
-    InstructionSelectorTester m;
-    m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmAdd, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
-  }
-  // (2^k + 1) * x -> (x >> k) + x
-  for (int k = 1; k < 31; ++k) {
-    InstructionSelectorTester m;
-    m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmAdd, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
-  }
-  // x * (2^k - 1) -> (x >> k) - x
-  for (int k = 3; k < 31; ++k) {
-    InstructionSelectorTester m;
-    m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmRsb, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
-  }
-  // (2^k - 1) * x -> (x >> k) - x
-  for (int k = 3; k < 31; ++k) {
-    InstructionSelectorTester m;
-    m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmRsb, m.code[0]->arch_opcode());
-    CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
-  }
-}
-
-
-TEST(InstructionSelectorWord32AndImm_ARMv7) {
-  for (uint32_t width = 1; width <= 32; ++width) {
-    InstructionSelectorTester m;
-    m.Return(m.Word32And(m.Parameter(0),
-                         m.Int32Constant(0xffffffffu >> (32 - width))));
-    m.SelectInstructions(ARMv7);
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
-    CHECK_EQ(3, m.code[0]->InputCount());
-    CHECK_EQ(0, m.ToInt32(m.code[0]->InputAt(1)));
-    CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
-  }
-  for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
-    for (uint32_t width = 1; width < 32 - lsb; ++width) {
-      uint32_t msk = ~((0xffffffffu >> (32 - width)) << lsb);
-      InstructionSelectorTester m;
-      m.Return(m.Word32And(m.Parameter(0), m.Int32Constant(msk)));
-      m.SelectInstructions(ARMv7);
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kArmBfc, m.code[0]->arch_opcode());
-      CHECK_EQ(1, m.code[0]->OutputCount());
-      CHECK(UnallocatedOperand::cast(m.code[0]->Output())
-                ->HasSameAsInputPolicy());
-      CHECK_EQ(3, m.code[0]->InputCount());
-      CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
-      CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
-    }
-  }
-}
-
-
-TEST(InstructionSelectorWord32AndAndWord32ShrImm_ARMv7) {
-  for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
-    for (uint32_t width = 1; width <= 32 - lsb; ++width) {
-      {
-        InstructionSelectorTester m;
- m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)), - m.Int32Constant(0xffffffffu >> (32 - width))));
-        m.SelectInstructions(ARMv7);
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
-      }
-      {
-        InstructionSelectorTester m;
-        m.Return(
-            m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
- m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
-        m.SelectInstructions(ARMv7);
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
-      }
-    }
-  }
-}
-
-
-TEST(InstructionSelectorWord32ShrAndWord32AndImm_ARMv7) {
-  for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
-    for (uint32_t width = 1; width <= 32 - lsb; ++width) {
-      uint32_t max = 1 << lsb;
-      if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
-      uint32_t jnk = CcTest::random_number_generator()->NextInt(max);
-      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
-      {
-        InstructionSelectorTester m;
- m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
-                             m.Int32Constant(lsb)));
-        m.SelectInstructions(ARMv7);
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
-      }
-      {
-        InstructionSelectorTester m;
- m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
-                             m.Int32Constant(lsb)));
-        m.SelectInstructions(ARMv7);
-        CHECK_EQ(1, m.code.size());
-        CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
-        CHECK_EQ(3, m.code[0]->InputCount());
-        CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
-        CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
-      }
-    }
-  }
-}
-
***The diff for this file has been truncated for email.***
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector-arm64.cc Wed Aug 13 10:29:22 2014 UTC
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <list>
-
-#include "test/cctest/compiler/instruction-selector-tester.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-namespace {
-
-struct DPI {
-  Operator* op;
-  ArchOpcode arch_opcode;
-};
-
-
-// ARM64 Logical instructions.
-class LogicalInstructions V8_FINAL : public std::list<DPI>,
-                                     private HandleAndZoneScope {
- public:
-  LogicalInstructions() {
-    MachineOperatorBuilder machine(main_zone());
-    DPI and32 = {machine.Word32And(), kArm64And32};
-    push_back(and32);
-    DPI and64 = {machine.Word64And(), kArm64And};
-    push_back(and64);
-    DPI or32 = {machine.Word32Or(), kArm64Or32};
-    push_back(or32);
-    DPI or64 = {machine.Word64Or(), kArm64Or};
-    push_back(or64);
-    DPI xor32 = {machine.Word32Xor(), kArm64Xor32};
-    push_back(xor32);
-    DPI xor64 = {machine.Word64Xor(), kArm64Xor};
-    push_back(xor64);
-  }
-};
-
-
-// ARM64 Arithmetic instructions.
-class AddSubInstructions V8_FINAL : public std::list<DPI>,
-                                    private HandleAndZoneScope {
- public:
-  AddSubInstructions() {
-    MachineOperatorBuilder machine(main_zone());
-    DPI add32 = {machine.Int32Add(), kArm64Add32};
-    push_back(add32);
-    DPI add64 = {machine.Int64Add(), kArm64Add};
-    push_back(add64);
-    DPI sub32 = {machine.Int32Sub(), kArm64Sub32};
-    push_back(sub32);
-    DPI sub64 = {machine.Int64Sub(), kArm64Sub};
-    push_back(sub64);
-  }
-};
-
-
-// ARM64 Add/Sub immediates.
-class AddSubImmediates V8_FINAL : public std::list<int32_t> {
- public:
-  AddSubImmediates() {
-    for (int32_t imm12 = 0; imm12 < 4096; ++imm12) {
-      CHECK(Assembler::IsImmAddSub(imm12));
-      CHECK(Assembler::IsImmAddSub(imm12 << 12));
-      push_back(imm12);
-      push_back(imm12 << 12);
-    }
-  }
-};
-
-
-// ARM64 Arithmetic instructions.
-class MulDivInstructions V8_FINAL : public std::list<DPI>,
-                                    private HandleAndZoneScope {
- public:
-  MulDivInstructions() {
-    MachineOperatorBuilder machine(main_zone());
-    DPI mul32 = {machine.Int32Mul(), kArm64Mul32};
-    push_back(mul32);
-    DPI mul64 = {machine.Int64Mul(), kArm64Mul};
-    push_back(mul64);
-    DPI sdiv32 = {machine.Int32Div(), kArm64Idiv32};
-    push_back(sdiv32);
-    DPI sdiv64 = {machine.Int64Div(), kArm64Idiv};
-    push_back(sdiv64);
-    DPI udiv32 = {machine.Int32UDiv(), kArm64Udiv32};
-    push_back(udiv32);
-    DPI udiv64 = {machine.Int64UDiv(), kArm64Udiv};
-    push_back(udiv64);
-  }
-};
-
-}  // namespace
-
-
-TEST(InstructionSelectorLogicalP) {
-  LogicalInstructions instructions;
-  for (LogicalInstructions::const_iterator i = instructions.begin();
-       i != instructions.end(); ++i) {
-    DPI dpi = *i;
-    InstructionSelectorTester m;
-    m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-  }
-}
-
-
-TEST(InstructionSelectorAddSubP) {
-  AddSubInstructions instructions;
-  for (AddSubInstructions::const_iterator i = instructions.begin();
-       i != instructions.end(); ++i) {
-    DPI dpi = *i;
-    InstructionSelectorTester m;
-    m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-  }
-}
-
-
-TEST(InstructionSelectorAddSubImm) {
-  AddSubInstructions instructions;
-  AddSubImmediates immediates;
-  for (AddSubInstructions::const_iterator i = instructions.begin();
-       i != instructions.end(); ++i) {
-    DPI dpi = *i;
-    for (AddSubImmediates::const_iterator j = immediates.begin();
-         j != immediates.end(); ++j) {
-      int32_t imm = *j;
-      InstructionSelectorTester m;
-      m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-      CHECK(m.code[0]->InputAt(1)->IsImmediate());
-    }
-  }
-}
-
-
-TEST(InstructionSelectorMulDivP) {
-  MulDivInstructions instructions;
-  for (MulDivInstructions::const_iterator i = instructions.begin();
-       i != instructions.end(); ++i) {
-    DPI dpi = *i;
-    InstructionSelectorTester m;
-    m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
-  }
-}
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector-ia32.cc Tue Aug 5 13:26:55 2014 UTC
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test/cctest/compiler/instruction-selector-tester.h"
-#include "test/cctest/compiler/value-helper.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-TEST(InstructionSelectorInt32AddP) {
-  InstructionSelectorTester m;
-  m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
-  m.SelectInstructions();
-  CHECK_EQ(1, m.code.size());
-  CHECK_EQ(kIA32Add, m.code[0]->arch_opcode());
-}
-
-
-TEST(InstructionSelectorInt32AddImm) {
-  FOR_INT32_INPUTS(i) {
-    int32_t imm = *i;
-    {
-      InstructionSelectorTester m;
-      m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kIA32Add, m.code[0]->arch_opcode());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-    }
-    {
-      InstructionSelectorTester m;
-      m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
-      m.SelectInstructions();
-      CHECK_EQ(1, m.code.size());
-      CHECK_EQ(kIA32Add, m.code[0]->arch_opcode());
-      CHECK_EQ(2, m.code[0]->InputCount());
-      CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-    }
-  }
-}
-
-
-TEST(InstructionSelectorInt32SubP) {
-  InstructionSelectorTester m;
-  m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1)));
-  m.SelectInstructions();
-  CHECK_EQ(1, m.code.size());
-  CHECK_EQ(kIA32Sub, m.code[0]->arch_opcode());
-  CHECK_EQ(1, m.code[0]->OutputCount());
-}
-
-
-TEST(InstructionSelectorInt32SubImm) {
-  FOR_INT32_INPUTS(i) {
-    int32_t imm = *i;
-    InstructionSelectorTester m;
-    m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)));
-    m.SelectInstructions();
-    CHECK_EQ(1, m.code.size());
-    CHECK_EQ(kIA32Sub, m.code[0]->arch_opcode());
-    CHECK_EQ(2, m.code[0]->InputCount());
-    CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
-  }
-}
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-instruction-selector.cc Tue Aug 5 14:21:07 2014 UTC
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test/cctest/compiler/instruction-selector-tester.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-#if V8_TURBOFAN_TARGET
-
-TEST(InstructionSelectionReturnZero) {
-  InstructionSelectorTester m;
-  m.Return(m.Int32Constant(0));
-  m.SelectInstructions(InstructionSelectorTester::kInternalMode);
-  CHECK_EQ(2, static_cast<int>(m.code.size()));
-  CHECK_EQ(kArchNop, m.code[0]->opcode());
-  CHECK_EQ(kArchRet, m.code[1]->opcode());
-  CHECK_EQ(1, static_cast<int>(m.code[1]->InputCount()));
-}
-
-#endif  // !V8_TURBOFAN_TARGET
=======================================
--- /branches/bleeding_edge/testing/gtest-type-names.h Tue Aug 12 12:53:14 2014 UTC
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_TESTING_GTEST_TYPE_NAMES_H_
-#define V8_TESTING_GTEST_TYPE_NAMES_H_
-
-#include "include/v8stdint.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace testing {
-namespace internal {
-
-#define GET_TYPE_NAME(type)         \
-  template <>                       \
-  std::string GetTypeName<type>() { \
-    return #type;                   \
-  }
-GET_TYPE_NAME(int8_t)
-GET_TYPE_NAME(uint8_t)
-GET_TYPE_NAME(int16_t)
-GET_TYPE_NAME(uint16_t)
-GET_TYPE_NAME(int32_t)
-GET_TYPE_NAME(uint32_t)
-GET_TYPE_NAME(int64_t)
-GET_TYPE_NAME(uint64_t)
-GET_TYPE_NAME(float)
-GET_TYPE_NAME(double)
-#undef GET_TYPE_NAME
-
-}  // namespace internal
-}  // namespace testing
-
-#endif  // V8_TESTING_GTEST_TYPE_NAMES_H_
=======================================
--- /branches/bleeding_edge/src/compiler/arm/instruction-selector-arm.cc Mon Aug 11 15:55:28 2014 UTC +++ /branches/bleeding_edge/src/compiler/arm/instruction-selector-arm.cc Thu Aug 14 06:33:50 2014 UTC
@@ -141,11 +141,22 @@
   if (value != mshl.left().node()) return false;
   Node* shift = mshr.right().node();
   Int32Matcher mshift(shift);
-  if (mshift.IsInRange(1, 31) && mshl.right().Is(32 - mshift.Value())) {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
-    *value_return = g.UseRegister(value);
-    *shift_return = g.UseImmediate(shift);
-    return true;
+  if (mshift.IsInRange(1, 31)) {
+    if (mshl.right().Is(32 - mshift.Value())) {
+ *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
+      *value_return = g.UseRegister(value);
+      *shift_return = g.UseImmediate(shift);
+      return true;
+    }
+    if (mshl.right().IsInt32Sub()) {
+      Int32BinopMatcher mshlright(mshl.right().node());
+ if (mshlright.left().Is(32) && mshlright.right().Is(mshift.Value())) { + *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
+        *value_return = g.UseRegister(value);
+        *shift_return = g.UseImmediate(shift);
+        return true;
+      }
+    }
   }
   if (mshl.right().IsInt32Sub()) {
     Int32BinopMatcher mshlright(mshl.right().node());
=======================================
--- /branches/bleeding_edge/src/compiler/machine-node-factory.h Mon Aug 11 15:55:28 2014 UTC +++ /branches/bleeding_edge/src/compiler/machine-node-factory.h Thu Aug 14 06:33:50 2014 UTC
@@ -118,6 +118,13 @@
   Node* WordSar(Node* a, Node* b) {
     return NEW_NODE_2(MACHINE()->WordSar(), a, b);
   }
+  Node* WordRor(Node* a, Node* b) {
+    if (MACHINE()->is32()) {
+      return Word32Ror(a, b);
+    } else {
+      return Word64Ror(a, b);
+    }
+  }
   Node* WordEqual(Node* a, Node* b) {
     return NEW_NODE_2(MACHINE()->WordEqual(), a, b);
   }
@@ -157,6 +164,10 @@
   Node* Word32Sar(Node* a, Node* b) {
     return NEW_NODE_2(MACHINE()->Word32Sar(), a, b);
   }
+  Node* Word32Ror(Node* a, Node* b) {
+    return Word32Or(Word32Shl(a, Int32Sub(Int32Constant(32), b)),
+                    Word32Shr(a, b));
+  }
   Node* Word32Equal(Node* a, Node* b) {
     return NEW_NODE_2(MACHINE()->Word32Equal(), a, b);
   }
@@ -184,6 +195,10 @@
   Node* Word64Sar(Node* a, Node* b) {
     return NEW_NODE_2(MACHINE()->Word64Sar(), a, b);
   }
+  Node* Word64Ror(Node* a, Node* b) {
+    return Word64Or(Word64Shl(a, Int64Sub(Int64Constant(64), b)),
+                    Word64Shr(a, b));
+  }
   Node* Word64Equal(Node* a, Node* b) {
     return NEW_NODE_2(MACHINE()->Word64Equal(), a, b);
   }
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.gyp Wed Aug 13 10:29:22 2014 UTC +++ /branches/bleeding_edge/test/cctest/cctest.gyp Thu Aug 14 06:33:50 2014 UTC
@@ -57,7 +57,6 @@
         'compiler/test-codegen-deopt.cc',
         'compiler/test-gap-resolver.cc',
         'compiler/test-graph-reducer.cc',
-        'compiler/test-instruction-selector.cc',
         'compiler/test-instruction.cc',
         'compiler/test-js-context-specialization.cc',
         'compiler/test-js-constant-cache.cc',
@@ -167,7 +166,6 @@
       'conditions': [
         ['v8_target_arch=="ia32"', {
           'sources': [  ### gcmole(arch:ia32) ###
-            'compiler/test-instruction-selector-ia32.cc',
             'test-assembler-ia32.cc',
             'test-code-stubs.cc',
             'test-code-stubs-ia32.cc',
@@ -188,7 +186,6 @@
         }],
         ['v8_target_arch=="arm"', {
           'sources': [  ### gcmole(arch:arm) ###
-            'compiler/test-instruction-selector-arm.cc',
             'test-assembler-arm.cc',
             'test-code-stubs.cc',
             'test-code-stubs-arm.cc',
@@ -198,7 +195,6 @@
         }],
         ['v8_target_arch=="arm64"', {
           'sources': [  ### gcmole(arch:arm64) ###
-            'compiler/test-instruction-selector-arm64.cc',
             'test-utils-arm64.cc',
             'test-assembler-arm64.cc',
             'test-code-stubs.cc',
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/DEPS Tue Aug 12 08:24:20 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/DEPS Thu Aug 14 06:33:50 2014 UTC
@@ -1,6 +1,6 @@
 include_rules = [
   "+src",
   "+testing/gtest",
-  "+testing/gtest-type-names.h",
+  "+testing/gtest-support.h",
   "+testing/gmock",
 ]
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc Tue Aug 12 09:48:52 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc Thu Aug 14 06:33:50 2014 UTC
@@ -8,19 +8,1722 @@
 namespace internal {
 namespace compiler {

-class InstructionSelectorARMTest : public InstructionSelectorTest {};
+namespace {

+typedef RawMachineAssembler::Label MLabel;
+typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);

-TARGET_TEST_F(InstructionSelectorARMTest, Int32AddP) {
+
+// Data processing instructions.
+struct DPI {
+  Constructor constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  ArchOpcode reverse_arch_opcode;
+  ArchOpcode test_arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
+  return os << dpi.constructor_name;
+}
+
+
+static const DPI kDPIs[] = {
+ {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst}, + {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr}, + {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq}, + {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn}, + {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
+
+
+// Data processing instructions with overflow.
+struct ODPI {
+  Constructor constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  ArchOpcode reverse_arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
+  return os << odpi.constructor_name;
+}
+
+
+static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
+                               "Int32AddWithOverflow", kArmAdd, kArmAdd},
+                              {&RawMachineAssembler::Int32SubWithOverflow,
+                               "Int32SubWithOverflow", kArmSub, kArmRsb}};
+
+
+// Shifts.
+struct Shift {
+  Constructor constructor;
+  const char* constructor_name;
+  int32_t i_low;          // lowest possible immediate
+  int32_t i_high;         // highest possible immediate
+  AddressingMode i_mode;  // Operand2_R_<shift>_I
+  AddressingMode r_mode;  // Operand2_R_<shift>_R
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Shift& shift) {
+  return os << shift.constructor_name;
+}
+
+
+static const Shift kShifts[] = {
+    {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
+     kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
+    {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
+     kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
+    {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
+     kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
+    {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
+     kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
+
+
+// Immediates (random subset).
+static const int32_t kImmediates[] = {
+    -2147483617, -2147483606, -2113929216, -2080374784, -1996488704,
+    -1879048192, -1459617792, -1358954496, -1342177265, -1275068414,
+    -1073741818, -1073741777, -855638016,  -805306368,  -402653184,
+    -268435444,  -16777216,   0,           35,          61,
+    105,         116,         171,         245,         255,
+    692,         1216,        1248,        1520,        1600,
+    1888,        3744,        4080,        5888,        8384,
+    9344,        9472,        9792,        13312,       15040,
+    15360,       20736,       22272,       23296,       32000,
+    33536,       37120,       45824,       47872,       56320,
+    59392,       65280,       72704,       101376,      147456,
+    161792,      164864,      167936,      173056,      195584,
+    209920,      212992,      356352,      655360,      704512,
+    716800,      851968,      901120,      1044480,     1523712,
+    2572288,     3211264,     3588096,     3833856,     3866624,
+    4325376,     5177344,     6488064,     7012352,     7471104,
+    14090240,    16711680,    19398656,    22282240,    28573696,
+    30408704,    30670848,    43253760,    54525952,    55312384,
+    56623104,    68157440,    115343360,   131072000,   187695104,
+    188743680,   195035136,   197132288,   203423744,   218103808,
+    267386880,   268435470,   285212672,   402653185,   415236096,
+    595591168,   603979776,   603979778,   629145600,   1073741835,
+    1073741855,  1073741861,  1073741884,  1157627904,  1476395008,
+    1476395010,  1610612741,  2030043136,  2080374785,  2097152000};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Data processing instructions.
+
+
+typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
+
+
+TEST_P(InstructionSelectorDPITest, Parameters) {
+  const DPI dpi = GetParam();
   StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
-  m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
   Stream s = m.Build();
   ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   EXPECT_EQ(2U, s[0]->InputCount());
   EXPECT_EQ(1U, s[0]->OutputCount());
 }
+
+
+TEST_P(InstructionSelectorDPITest, Immediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    m.Return((m.*dpi.constructor)(
+        m.Parameter(0),
+        (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    m.Return((m.*dpi.constructor)(
+        (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+        m.Parameter(2)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      m.Return((m.*dpi.constructor)(
+          m.Parameter(0),
+          (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      m.Return((m.*dpi.constructor)(
+          (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+          m.Parameter(1)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  MLabel a, b;
+  m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+ m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
+             &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+ m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
+             &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    MLabel a, b;
+    m.Branch((m.*dpi.constructor)(
+                 m.Parameter(0),
+                 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    MLabel a, b;
+    m.Branch((m.*dpi.constructor)(
+                 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+                 m.Parameter(2)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      MLabel a, b;
+      m.Branch((m.*dpi.constructor)(m.Parameter(0),
+                                    (m.*shift.constructor)(
+ m.Parameter(1), m.Int32Constant(imm))),
+               &a, &b);
+      m.Bind(&a);
+      m.Return(m.Int32Constant(1));
+      m.Bind(&b);
+      m.Return(m.Int32Constant(0));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(5U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+      EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      MLabel a, b;
+      m.Branch((m.*dpi.constructor)(
+ (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+                   m.Parameter(1)),
+               &a, &b);
+      m.Bind(&a);
+      m.Return(m.Int32Constant(1));
+      m.Bind(&b);
+      m.Return(m.Int32Constant(0));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(5U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+      EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  MLabel a, b;
+ m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
+                         m.Int32Constant(0)),
+           &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  MLabel a, b;
+  m.Branch(
+ m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
+                       m.Int32Constant(0)),
+      &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+    m.Branch(m.Word32Equal(
+ (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+    m.Branch(m.Word32Equal(
+ (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+    m.Branch(m.Word32NotEqual(
+ (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+    m.Branch(m.Word32NotEqual(
+ (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
+                        ::testing::ValuesIn(kDPIs));
+
+
+// -----------------------------------------------------------------------------
+// Data processing instructions with overflow.
+
+
+typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  m.Return(
+ m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(
+               m.Parameter(0),
+               (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(
+               (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+               m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      m.Return(m.Projection(
+          1, (m.*odpi.constructor)(m.Parameter(0),
+                                   (m.*shift.constructor)(
+ m.Parameter(1), m.Int32Constant(imm)))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      m.Return(m.Projection(
+          1, (m.*odpi.constructor)(
+ (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+                 m.Parameter(0))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  m.Return(
+ m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(
+               m.Parameter(0),
+               (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(
+               (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+               m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      m.Return(m.Projection(
+          0, (m.*odpi.constructor)(m.Parameter(0),
+                                   (m.*shift.constructor)(
+ m.Parameter(1), m.Int32Constant(imm)))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      m.Return(m.Projection(
+          0, (m.*odpi.constructor)(
+ (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+                 m.Parameter(0))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+  Stream s = m.Build();
+  ASSERT_LE(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(2U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    Node* n = (m.*odpi.constructor)(
+ m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
+                    kMachineWord32);
+    Node* n = (m.*odpi.constructor)(
+ (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      Node* n = (m.*odpi.constructor)(
+          m.Parameter(0),
+          (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
+      m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+      Stream s = m.Build();
+      ASSERT_LE(1U, s.size());
+      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(2U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+      Node* n = (m.*odpi.constructor)(
+          (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+          m.Parameter(1));
+      m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+      Stream s = m.Build();
+      ASSERT_LE(1U, s.size());
+      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(2U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  MLabel a, b;
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Branch(m.Projection(1, n), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(0));
+  m.Bind(&b);
+  m.Return(m.Projection(0, n));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+    Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
+    m.Branch(m.Projection(1, n), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(0));
+    m.Bind(&b);
+    m.Return(m.Projection(0, n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachineWord32, kMachineWord32);
+    MLabel a, b;
+    Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
+    m.Branch(m.Projection(1, n), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(0));
+    m.Bind(&b);
+    m.Return(m.Projection(0, n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  MLabel a, b;
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Projection(0, n));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+  MLabel a, b;
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+ m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Projection(0, n));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
+                        ::testing::ValuesIn(kODPIs));
+
+
+// -----------------------------------------------------------------------------
+// Shifts.
+
+
+typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
+
+
+TEST_P(InstructionSelectorShiftTest, Parameters) {
+  const Shift shift = GetParam();
***The diff for this file has been truncated for email.***
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc Tue Aug 12 09:52:39 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc Thu Aug 14 06:33:50 2014 UTC
@@ -10,7 +10,6 @@
 #include "src/factory.h"
 #include "test/compiler-unittests/compiler-unittests.h"
 #include "test/compiler-unittests/node-matchers.h"
-#include "testing/gtest-type-names.h"

 using testing::_;

=======================================
--- /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.gyp Tue Aug 12 12:53:14 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.gyp Thu Aug 14 06:33:50 2014 UTC
@@ -32,6 +32,16 @@
             'arm/instruction-selector-arm-unittest.cc',
           ],
         }],
+        ['v8_target_arch=="arm64"', {
+          'sources': [  ### gcmole(arch:arm64) ###
+            'arm64/instruction-selector-arm64-unittest.cc',
+          ],
+        }],
+        ['v8_target_arch=="ia32"', {
+          'sources': [  ### gcmole(arch:ia32) ###
+            'ia32/instruction-selector-ia32-unittest.cc',
+          ],
+        }],
         ['component=="shared_library"', {
# compiler-unittests can't be built against a shared library, so we
           # need to depend on the underlying static target in that case.
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h Tue Aug 12 09:52:39 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h Thu Aug 14 06:33:50 2014 UTC
@@ -7,7 +7,7 @@

 #include "include/v8.h"
 #include "src/zone.h"
-#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest-support.h"

 namespace v8 {
 namespace internal {
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/instruction-selector-unittest.cc Tue Aug 12 09:48:52 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/instruction-selector-unittest.cc Thu Aug 14 06:33:50 2014 UTC
@@ -4,14 +4,23 @@

 #include "test/compiler-unittests/instruction-selector-unittest.h"

+#include "src/flags.h"
+
 namespace v8 {
 namespace internal {
 namespace compiler {

+InstructionSelectorTest::InstructionSelectorTest() : rng_(FLAG_random_seed) {}
+
+
InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
     InstructionSelector::Features features,
     InstructionSelectorTest::StreamBuilderMode mode) {
   Schedule* schedule = Export();
+  if (FLAG_trace_turbo) {
+    OFStream out(stdout);
+ out << "=== Schedule before instruction selection ===" << endl << *schedule;
+  }
   EXPECT_NE(0, graph()->NodeCount());
   CompilationInfo info(test_->isolate(), test_->zone());
   Linkage linkage(&info, call_descriptor());
@@ -21,7 +30,7 @@
   selector.SelectInstructions();
   if (FLAG_trace_turbo) {
     OFStream out(stdout);
-    out << "--- Code sequence after instruction selection ---" << endl
+    out << "=== Code sequence after instruction selection ===" << endl
         << sequence;
   }
   Stream s;
@@ -62,7 +71,7 @@
 }


-TARGET_TEST_F(InstructionSelectorTest, ReturnP) {
+TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) {
   StreamBuilder m(this, kMachineWord32, kMachineWord32);
   m.Return(m.Parameter(0));
   Stream s = m.Build(kAllInstructions);
@@ -74,7 +83,7 @@
 }


-TARGET_TEST_F(InstructionSelectorTest, ReturnImm) {
+TARGET_TEST_F(InstructionSelectorTest, ReturnZero) {
   StreamBuilder m(this, kMachineWord32);
   m.Return(m.Int32Constant(0));
   Stream s = m.Build(kAllInstructions);
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/instruction-selector-unittest.h Mon Aug 11 15:55:28 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/instruction-selector-unittest.h Thu Aug 14 06:33:50 2014 UTC
@@ -6,7 +6,9 @@
 #define V8_COMPILER_UNITTESTS_INSTRUCTION_SELECTOR_UNITTEST_H_

 #include <deque>
+#include <ostream>  // NOLINT(readability/streams)

+#include "src/base/utils/random-number-generator.h"
 #include "src/compiler/instruction-selector.h"
 #include "src/compiler/raw-machine-assembler.h"
 #include "test/compiler-unittests/compiler-unittests.h"
@@ -17,8 +19,10 @@

 class InstructionSelectorTest : public CompilerTest {
  public:
-  InstructionSelectorTest() {}
+  InstructionSelectorTest();
   virtual ~InstructionSelectorTest() {}
+
+  base::RandomNumberGenerator* rng() { return &rng_; }

  protected:
   class Stream;
@@ -44,6 +48,14 @@
CallDescriptorBuilder(test->zone(), return_type, parameter0_type,
                                     parameter1_type)),
           test_(test) {}
+    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
+                  MachineType parameter0_type, MachineType parameter1_type,
+                  MachineType parameter2_type)
+        : RawMachineAssembler(
+              new (test->zone()) Graph(test->zone()),
+ CallDescriptorBuilder(test->zone(), return_type, parameter0_type,
+                                    parameter1_type, parameter2_type)),
+          test_(test) {}

     Stream Build(CpuFeature feature) {
       return Build(InstructionSelector::Features(feature));
@@ -80,6 +92,17 @@
       return new (zone)
           MachineCallDescriptorBuilder(return_type, 2, parameter_types);
     }
+
+    MachineCallDescriptorBuilder* CallDescriptorBuilder(
+        Zone* zone, MachineType return_type, MachineType parameter0_type,
+        MachineType parameter1_type, MachineType parameter2_type) {
+      MachineType* parameter_types = zone->NewArray<MachineType>(3);
+      parameter_types[0] = parameter0_type;
+      parameter_types[1] = parameter1_type;
+      parameter_types[2] = parameter2_type;
+      return new (zone)
+          MachineCallDescriptorBuilder(return_type, 3, parameter_types);
+    }

    private:
     InstructionSelectorTest* test_;
@@ -96,6 +119,11 @@
     int32_t ToInt32(const InstructionOperand* operand) const {
       return ToConstant(operand).ToInt32();
     }
+
+    int ToVreg(const InstructionOperand* operand) const {
+      EXPECT_EQ(InstructionOperand::UNALLOCATED, operand->kind());
+      return UnallocatedOperand::cast(operand)->virtual_register();
+    }

    private:
     Constant ToConstant(const InstructionOperand* operand) const {
@@ -120,8 +148,16 @@
     ConstantMap immediates_;
     std::deque<Instruction*> instructions_;
   };
+
+  base::RandomNumberGenerator rng_;
 };

+
+template <typename T>
+class InstructionSelectorTestWithParam
+    : public InstructionSelectorTest,
+      public ::testing::WithParamInterface<T> {};
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /branches/bleeding_edge/testing/gtest.gyp   Tue Aug 12 08:24:20 2014 UTC
+++ /branches/bleeding_edge/testing/gtest.gyp   Thu Aug 14 06:33:50 2014 UTC
@@ -37,7 +37,7 @@
         'gtest/src/gtest-test-part.cc',
         'gtest/src/gtest-typed-test.cc',
         'gtest/src/gtest.cc',
-        'gtest-type-names.h',
+        'gtest-support.h',
       ],
       'sources!': [
         'gtest/src/gtest-all.cc',  # Not needed by our build.

--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to