Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Unified Diff: test/unittests/compiler/arm/instruction-selector-arm-unittest.cc

Issue 1044793002: [turbofan] Add backend support for float32 operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add MachineOperator unit tests. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
diff --git a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
index 85e52488b478411160bc8dccfc5a055692ce21d5..8534c1c79a72d86a70636ded0f18216c4da24b30 100644
--- a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
+++ b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
@@ -31,7 +31,7 @@ std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
}
-static const DPI kDPIs[] = {
+const DPI kDPIs[] = {
{&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
{&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
{&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
@@ -39,6 +39,32 @@ static const DPI kDPIs[] = {
{&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
+// Floating point arithmetic instructions.
+struct FAI {
+ Constructor constructor;
+ const char* constructor_name;
+ MachineType machine_type;
+ ArchOpcode arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const FAI& fai) {
+ return os << fai.constructor_name;
+}
+
+
+const FAI kFAIs[] = {
+ {&RawMachineAssembler::Float32Add, "Float32Add", kMachFloat32, kArmVaddF32},
+ {&RawMachineAssembler::Float64Add, "Float64Add", kMachFloat64, kArmVaddF64},
+ {&RawMachineAssembler::Float32Sub, "Float32Sub", kMachFloat32, kArmVsubF32},
+ {&RawMachineAssembler::Float64Sub, "Float64Sub", kMachFloat64, kArmVsubF64},
+ {&RawMachineAssembler::Float32Mul, "Float32Mul", kMachFloat32, kArmVmulF32},
+ {&RawMachineAssembler::Float64Mul, "Float64Mul", kMachFloat64, kArmVmulF64},
+ {&RawMachineAssembler::Float32Div, "Float32Div", kMachFloat32, kArmVdivF32},
+ {&RawMachineAssembler::Float64Div, "Float64Div", kMachFloat64,
+ kArmVdivF64}};
+
+
// Data processing instructions with overflow.
struct ODPI {
Constructor constructor;
@@ -53,10 +79,10 @@ std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
}
-static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
- "Int32AddWithOverflow", kArmAdd, kArmAdd},
- {&RawMachineAssembler::Int32SubWithOverflow,
- "Int32SubWithOverflow", kArmSub, kArmRsb}};
+const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
+ "Int32AddWithOverflow", kArmAdd, kArmAdd},
+ {&RawMachineAssembler::Int32SubWithOverflow,
+ "Int32SubWithOverflow", kArmSub, kArmRsb}};
// Shifts.
@@ -75,50 +101,34 @@ std::ostream& operator<<(std::ostream& os, const Shift& shift) {
}
-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}};
+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[] = {
+const int32_t kImmediates[] = {
std::numeric_limits<int32_t>::min(), -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};
+ -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
@@ -1217,7 +1227,7 @@ std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
}
-static const MemoryAccess kMemoryAccesses[] = {
+const MemoryAccess kMemoryAccesses[] = {
{kMachInt8,
kArmLdrsb,
kArmStrb,
@@ -1482,19 +1492,100 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
// Floating point comparisons.
-const Comparison kFPComparisons[] = {
+namespace {
+
+const Comparison kF32Comparisons[] = {
+ {&RawMachineAssembler::Float32Equal, "Float32Equal", kEqual, kNotEqual},
+ {&RawMachineAssembler::Float32LessThan, "Float32LessThan",
+ kUnsignedLessThan, kUnsignedGreaterThanOrEqual},
+ {&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual",
+ kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
+
+} // namespace
+
+typedef InstructionSelectorTestWithParam<Comparison>
+ InstructionSelectorF32ComparisonTest;
+
+
+TEST_P(InstructionSelectorF32ComparisonTest, WithParameters) {
+ const Comparison& cmp = GetParam();
+ StreamBuilder m(this, kMachInt32, kMachFloat32, kMachFloat32);
+ m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
+ Stream const s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorF32ComparisonTest, NegatedWithParameters) {
+ const Comparison& cmp = GetParam();
+ StreamBuilder m(this, kMachInt32, kMachFloat32, kMachFloat32);
+ m.Return(
+ m.WordBinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))));
+ Stream const s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorF32ComparisonTest, WithImmediateZeroOnRight) {
+ const Comparison& cmp = GetParam();
+ StreamBuilder m(this, kMachInt32, kMachFloat32);
+ m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float32Constant(0.0)));
+ Stream const s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+ InstructionSelectorF32ComparisonTest,
+ ::testing::ValuesIn(kF32Comparisons));
+
+
+TEST_F(InstructionSelectorTest, Float32EqualWithImmediateZeroOnLeft) {
+ StreamBuilder m(this, kMachInt32, kMachFloat32);
+ m.Return(m.Float32Equal(m.Float32Constant(0.0f), m.Parameter(0)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(kEqual, s[0]->flags_condition());
+}
+
+
+namespace {
+
+const Comparison kF64Comparisons[] = {
{&RawMachineAssembler::Float64Equal, "Float64Equal", kEqual, kNotEqual},
{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
kUnsignedLessThan, kUnsignedGreaterThanOrEqual},
{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
+} // namespace
typedef InstructionSelectorTestWithParam<Comparison>
- InstructionSelectorFPComparisonTest;
+ InstructionSelectorF64ComparisonTest;
-TEST_P(InstructionSelectorFPComparisonTest, WithParameters) {
+TEST_P(InstructionSelectorF64ComparisonTest, WithParameters) {
const Comparison& cmp = GetParam();
StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64);
m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
@@ -1508,7 +1599,7 @@ TEST_P(InstructionSelectorFPComparisonTest, WithParameters) {
}
-TEST_P(InstructionSelectorFPComparisonTest, NegatedWithParameters) {
+TEST_P(InstructionSelectorF64ComparisonTest, NegatedWithParameters) {
const Comparison& cmp = GetParam();
StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64);
m.Return(
@@ -1523,7 +1614,7 @@ TEST_P(InstructionSelectorFPComparisonTest, NegatedWithParameters) {
}
-TEST_P(InstructionSelectorFPComparisonTest, WithImmediateZeroOnRight) {
+TEST_P(InstructionSelectorF64ComparisonTest, WithImmediateZeroOnRight) {
const Comparison& cmp = GetParam();
StreamBuilder m(this, kMachInt32, kMachFloat64);
m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float64Constant(0.0)));
@@ -1539,8 +1630,8 @@ TEST_P(InstructionSelectorFPComparisonTest, WithImmediateZeroOnRight) {
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
- InstructionSelectorFPComparisonTest,
- ::testing::ValuesIn(kFPComparisons));
+ InstructionSelectorF64ComparisonTest,
+ ::testing::ValuesIn(kF64Comparisons));
TEST_F(InstructionSelectorTest, Float64EqualWithImmediateZeroOnLeft) {
@@ -1558,7 +1649,141 @@ TEST_F(InstructionSelectorTest, Float64EqualWithImmediateZeroOnLeft) {
// -----------------------------------------------------------------------------
-// Miscellaneous.
+// Floating point arithmetic.
+
+
+typedef InstructionSelectorTestWithParam<FAI> InstructionSelectorFAITest;
+
+
+TEST_P(InstructionSelectorFAITest, Parameters) {
+ const FAI& fai = GetParam();
+ StreamBuilder m(this, fai.machine_type, fai.machine_type, fai.machine_type);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const r = (m.*fai.constructor)(p0, p1);
+ m.Return(r);
+ Stream const s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(fai.arch_opcode, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFAITest,
+ ::testing::ValuesIn(kFAIs));
+
+
+TEST_F(InstructionSelectorTest, Float32AddWithFloat32Mul) {
+ {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32,
+ kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const p2 = m.Parameter(2);
+ Node* const n = m.Float32Add(m.Float32Mul(p0, p1), p2);
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVmlaF32, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_TRUE(
+ UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+ }
+ {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32,
+ kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const p2 = m.Parameter(2);
+ Node* const n = m.Float32Add(p0, m.Float32Mul(p1, p2));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVmlaF32, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_TRUE(
+ UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Float64AddWithFloat64Mul) {
+ {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64,
+ kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const p2 = m.Parameter(2);
+ Node* const n = m.Float64Add(m.Float64Mul(p0, p1), p2);
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVmlaF64, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_TRUE(
+ UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+ }
+ {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64,
+ kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const p2 = m.Parameter(2);
+ Node* const n = m.Float64Add(p0, m.Float64Mul(p1, p2));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVmlaF64, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_TRUE(
+ UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Float32SubWithMinusZero) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVnegF32, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
@@ -1576,6 +1801,84 @@ TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
}
+TEST_F(InstructionSelectorTest, Float32SubWithFloat32Mul) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const p2 = m.Parameter(2);
+ Node* const n = m.Float32Sub(p0, m.Float32Mul(p1, p2));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVmlsF32, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+TEST_F(InstructionSelectorTest, Float64SubWithFloat64Mul) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const p2 = m.Parameter(2);
+ Node* const n = m.Float64Sub(p0, m.Float64Mul(p1, p2));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVmlsF64, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+TEST_F(InstructionSelectorTest, Float32Sqrt) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const n = m.Float32Sqrt(p0);
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVsqrtF32, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Sqrt) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const n = m.Float64Sqrt(p0);
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVsqrtF64, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+// -----------------------------------------------------------------------------
+// Miscellaneous.
+
+
TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
{
StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);

Powered by Google App Engine
This is Rietveld 408576698