OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits> | 5 #include <limits> |
6 | 6 |
7 #include "test/unittests/compiler/instruction-selector-unittest.h" | 7 #include "test/unittests/compiler/instruction-selector-unittest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 13 matching lines...) Expand all Loading... |
24 ArchOpcode reverse_arch_opcode; | 24 ArchOpcode reverse_arch_opcode; |
25 ArchOpcode test_arch_opcode; | 25 ArchOpcode test_arch_opcode; |
26 }; | 26 }; |
27 | 27 |
28 | 28 |
29 std::ostream& operator<<(std::ostream& os, const DPI& dpi) { | 29 std::ostream& operator<<(std::ostream& os, const DPI& dpi) { |
30 return os << dpi.constructor_name; | 30 return os << dpi.constructor_name; |
31 } | 31 } |
32 | 32 |
33 | 33 |
34 static const DPI kDPIs[] = { | 34 const DPI kDPIs[] = { |
35 {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst}, | 35 {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst}, |
36 {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr}, | 36 {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr}, |
37 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq}, | 37 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq}, |
38 {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn}, | 38 {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn}, |
39 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}}; | 39 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}}; |
40 | 40 |
41 | 41 |
| 42 // Floating point arithmetic instructions. |
| 43 struct FAI { |
| 44 Constructor constructor; |
| 45 const char* constructor_name; |
| 46 MachineType machine_type; |
| 47 ArchOpcode arch_opcode; |
| 48 }; |
| 49 |
| 50 |
| 51 std::ostream& operator<<(std::ostream& os, const FAI& fai) { |
| 52 return os << fai.constructor_name; |
| 53 } |
| 54 |
| 55 |
| 56 const FAI kFAIs[] = { |
| 57 {&RawMachineAssembler::Float32Add, "Float32Add", kMachFloat32, kArmVaddF32}, |
| 58 {&RawMachineAssembler::Float64Add, "Float64Add", kMachFloat64, kArmVaddF64}, |
| 59 {&RawMachineAssembler::Float32Sub, "Float32Sub", kMachFloat32, kArmVsubF32}, |
| 60 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMachFloat64, kArmVsubF64}, |
| 61 {&RawMachineAssembler::Float32Mul, "Float32Mul", kMachFloat32, kArmVmulF32}, |
| 62 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMachFloat64, kArmVmulF64}, |
| 63 {&RawMachineAssembler::Float32Div, "Float32Div", kMachFloat32, kArmVdivF32}, |
| 64 {&RawMachineAssembler::Float64Div, "Float64Div", kMachFloat64, |
| 65 kArmVdivF64}}; |
| 66 |
| 67 |
42 // Data processing instructions with overflow. | 68 // Data processing instructions with overflow. |
43 struct ODPI { | 69 struct ODPI { |
44 Constructor constructor; | 70 Constructor constructor; |
45 const char* constructor_name; | 71 const char* constructor_name; |
46 ArchOpcode arch_opcode; | 72 ArchOpcode arch_opcode; |
47 ArchOpcode reverse_arch_opcode; | 73 ArchOpcode reverse_arch_opcode; |
48 }; | 74 }; |
49 | 75 |
50 | 76 |
51 std::ostream& operator<<(std::ostream& os, const ODPI& odpi) { | 77 std::ostream& operator<<(std::ostream& os, const ODPI& odpi) { |
52 return os << odpi.constructor_name; | 78 return os << odpi.constructor_name; |
53 } | 79 } |
54 | 80 |
55 | 81 |
56 static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow, | 82 const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow, |
57 "Int32AddWithOverflow", kArmAdd, kArmAdd}, | 83 "Int32AddWithOverflow", kArmAdd, kArmAdd}, |
58 {&RawMachineAssembler::Int32SubWithOverflow, | 84 {&RawMachineAssembler::Int32SubWithOverflow, |
59 "Int32SubWithOverflow", kArmSub, kArmRsb}}; | 85 "Int32SubWithOverflow", kArmSub, kArmRsb}}; |
60 | 86 |
61 | 87 |
62 // Shifts. | 88 // Shifts. |
63 struct Shift { | 89 struct Shift { |
64 Constructor constructor; | 90 Constructor constructor; |
65 const char* constructor_name; | 91 const char* constructor_name; |
66 int32_t i_low; // lowest possible immediate | 92 int32_t i_low; // lowest possible immediate |
67 int32_t i_high; // highest possible immediate | 93 int32_t i_high; // highest possible immediate |
68 AddressingMode i_mode; // Operand2_R_<shift>_I | 94 AddressingMode i_mode; // Operand2_R_<shift>_I |
69 AddressingMode r_mode; // Operand2_R_<shift>_R | 95 AddressingMode r_mode; // Operand2_R_<shift>_R |
70 }; | 96 }; |
71 | 97 |
72 | 98 |
73 std::ostream& operator<<(std::ostream& os, const Shift& shift) { | 99 std::ostream& operator<<(std::ostream& os, const Shift& shift) { |
74 return os << shift.constructor_name; | 100 return os << shift.constructor_name; |
75 } | 101 } |
76 | 102 |
77 | 103 |
78 static const Shift kShifts[] = { | 104 const Shift kShifts[] = {{&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32, |
79 {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32, | 105 kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R}, |
80 kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R}, | 106 {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31, |
81 {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31, | 107 kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R}, |
82 kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R}, | 108 {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32, |
83 {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32, | 109 kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R}, |
84 kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R}, | 110 {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31, |
85 {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31, | 111 kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}}; |
86 kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}}; | |
87 | 112 |
88 | 113 |
89 // Immediates (random subset). | 114 // Immediates (random subset). |
90 static const int32_t kImmediates[] = { | 115 const int32_t kImmediates[] = { |
91 std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216, | 116 std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216, |
92 -2080374784, -1996488704, -1879048192, -1459617792, | 117 -2080374784, -1996488704, -1879048192, -1459617792, -1358954496, |
93 -1358954496, -1342177265, -1275068414, -1073741818, | 118 -1342177265, -1275068414, -1073741818, -1073741777, -855638016, -805306368, |
94 -1073741777, -855638016, -805306368, -402653184, | 119 -402653184, -268435444, -16777216, 0, 35, 61, 105, 116, 171, 245, 255, 692, |
95 -268435444, -16777216, 0, 35, | 120 1216, 1248, 1520, 1600, 1888, 3744, 4080, 5888, 8384, 9344, 9472, 9792, |
96 61, 105, 116, 171, | 121 13312, 15040, 15360, 20736, 22272, 23296, 32000, 33536, 37120, 45824, 47872, |
97 245, 255, 692, 1216, | 122 56320, 59392, 65280, 72704, 101376, 147456, 161792, 164864, 167936, 173056, |
98 1248, 1520, 1600, 1888, | 123 195584, 209920, 212992, 356352, 655360, 704512, 716800, 851968, 901120, |
99 3744, 4080, 5888, 8384, | 124 1044480, 1523712, 2572288, 3211264, 3588096, 3833856, 3866624, 4325376, |
100 9344, 9472, 9792, 13312, | 125 5177344, 6488064, 7012352, 7471104, 14090240, 16711680, 19398656, 22282240, |
101 15040, 15360, 20736, 22272, | 126 28573696, 30408704, 30670848, 43253760, 54525952, 55312384, 56623104, |
102 23296, 32000, 33536, 37120, | 127 68157440, 115343360, 131072000, 187695104, 188743680, 195035136, 197132288, |
103 45824, 47872, 56320, 59392, | 128 203423744, 218103808, 267386880, 268435470, 285212672, 402653185, 415236096, |
104 65280, 72704, 101376, 147456, | 129 595591168, 603979776, 603979778, 629145600, 1073741835, 1073741855, |
105 161792, 164864, 167936, 173056, | 130 1073741861, 1073741884, 1157627904, 1476395008, 1476395010, 1610612741, |
106 195584, 209920, 212992, 356352, | 131 2030043136, 2080374785, 2097152000}; |
107 655360, 704512, 716800, 851968, | |
108 901120, 1044480, 1523712, 2572288, | |
109 3211264, 3588096, 3833856, 3866624, | |
110 4325376, 5177344, 6488064, 7012352, | |
111 7471104, 14090240, 16711680, 19398656, | |
112 22282240, 28573696, 30408704, 30670848, | |
113 43253760, 54525952, 55312384, 56623104, | |
114 68157440, 115343360, 131072000, 187695104, | |
115 188743680, 195035136, 197132288, 203423744, | |
116 218103808, 267386880, 268435470, 285212672, | |
117 402653185, 415236096, 595591168, 603979776, | |
118 603979778, 629145600, 1073741835, 1073741855, | |
119 1073741861, 1073741884, 1157627904, 1476395008, | |
120 1476395010, 1610612741, 2030043136, 2080374785, | |
121 2097152000}; | |
122 | 132 |
123 } // namespace | 133 } // namespace |
124 | 134 |
125 | 135 |
126 // ----------------------------------------------------------------------------- | 136 // ----------------------------------------------------------------------------- |
127 // Data processing instructions. | 137 // Data processing instructions. |
128 | 138 |
129 | 139 |
130 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest; | 140 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest; |
131 | 141 |
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 const InstructionOperand*) const; | 1220 const InstructionOperand*) const; |
1211 const int32_t immediates[40]; | 1221 const int32_t immediates[40]; |
1212 }; | 1222 }; |
1213 | 1223 |
1214 | 1224 |
1215 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { | 1225 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { |
1216 return os << memacc.type; | 1226 return os << memacc.type; |
1217 } | 1227 } |
1218 | 1228 |
1219 | 1229 |
1220 static const MemoryAccess kMemoryAccesses[] = { | 1230 const MemoryAccess kMemoryAccesses[] = { |
1221 {kMachInt8, | 1231 {kMachInt8, |
1222 kArmLdrsb, | 1232 kArmLdrsb, |
1223 kArmStrb, | 1233 kArmStrb, |
1224 &InstructionSelectorTest::Stream::IsInteger, | 1234 &InstructionSelectorTest::Stream::IsInteger, |
1225 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 1235 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
1226 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 1236 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
1227 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 1237 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
1228 {kMachUint8, | 1238 {kMachUint8, |
1229 kArmLdrb, | 1239 kArmLdrb, |
1230 kArmStrb, | 1240 kArmStrb, |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 | 1485 |
1476 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1486 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
1477 InstructionSelectorComparisonTest, | 1487 InstructionSelectorComparisonTest, |
1478 ::testing::ValuesIn(kComparisons)); | 1488 ::testing::ValuesIn(kComparisons)); |
1479 | 1489 |
1480 | 1490 |
1481 // ----------------------------------------------------------------------------- | 1491 // ----------------------------------------------------------------------------- |
1482 // Floating point comparisons. | 1492 // Floating point comparisons. |
1483 | 1493 |
1484 | 1494 |
1485 const Comparison kFPComparisons[] = { | 1495 namespace { |
| 1496 |
| 1497 const Comparison kF32Comparisons[] = { |
| 1498 {&RawMachineAssembler::Float32Equal, "Float32Equal", kEqual, kNotEqual}, |
| 1499 {&RawMachineAssembler::Float32LessThan, "Float32LessThan", |
| 1500 kUnsignedLessThan, kUnsignedGreaterThanOrEqual}, |
| 1501 {&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual", |
| 1502 kUnsignedLessThanOrEqual, kUnsignedGreaterThan}}; |
| 1503 |
| 1504 } // namespace |
| 1505 |
| 1506 typedef InstructionSelectorTestWithParam<Comparison> |
| 1507 InstructionSelectorF32ComparisonTest; |
| 1508 |
| 1509 |
| 1510 TEST_P(InstructionSelectorF32ComparisonTest, WithParameters) { |
| 1511 const Comparison& cmp = GetParam(); |
| 1512 StreamBuilder m(this, kMachInt32, kMachFloat32, kMachFloat32); |
| 1513 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))); |
| 1514 Stream const s = m.Build(); |
| 1515 ASSERT_EQ(1U, s.size()); |
| 1516 EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode()); |
| 1517 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1518 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1519 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1520 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); |
| 1521 } |
| 1522 |
| 1523 |
| 1524 TEST_P(InstructionSelectorF32ComparisonTest, NegatedWithParameters) { |
| 1525 const Comparison& cmp = GetParam(); |
| 1526 StreamBuilder m(this, kMachInt32, kMachFloat32, kMachFloat32); |
| 1527 m.Return( |
| 1528 m.WordBinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)))); |
| 1529 Stream const s = m.Build(); |
| 1530 ASSERT_EQ(1U, s.size()); |
| 1531 EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode()); |
| 1532 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1533 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1534 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1535 EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition()); |
| 1536 } |
| 1537 |
| 1538 |
| 1539 TEST_P(InstructionSelectorF32ComparisonTest, WithImmediateZeroOnRight) { |
| 1540 const Comparison& cmp = GetParam(); |
| 1541 StreamBuilder m(this, kMachInt32, kMachFloat32); |
| 1542 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float32Constant(0.0))); |
| 1543 Stream const s = m.Build(); |
| 1544 ASSERT_EQ(1U, s.size()); |
| 1545 EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode()); |
| 1546 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1547 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 1548 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1549 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1550 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); |
| 1551 } |
| 1552 |
| 1553 |
| 1554 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 1555 InstructionSelectorF32ComparisonTest, |
| 1556 ::testing::ValuesIn(kF32Comparisons)); |
| 1557 |
| 1558 |
| 1559 TEST_F(InstructionSelectorTest, Float32EqualWithImmediateZeroOnLeft) { |
| 1560 StreamBuilder m(this, kMachInt32, kMachFloat32); |
| 1561 m.Return(m.Float32Equal(m.Float32Constant(0.0f), m.Parameter(0))); |
| 1562 Stream s = m.Build(); |
| 1563 ASSERT_EQ(1U, s.size()); |
| 1564 EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode()); |
| 1565 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1566 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 1567 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1568 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1569 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 1570 } |
| 1571 |
| 1572 |
| 1573 namespace { |
| 1574 |
| 1575 const Comparison kF64Comparisons[] = { |
1486 {&RawMachineAssembler::Float64Equal, "Float64Equal", kEqual, kNotEqual}, | 1576 {&RawMachineAssembler::Float64Equal, "Float64Equal", kEqual, kNotEqual}, |
1487 {&RawMachineAssembler::Float64LessThan, "Float64LessThan", | 1577 {&RawMachineAssembler::Float64LessThan, "Float64LessThan", |
1488 kUnsignedLessThan, kUnsignedGreaterThanOrEqual}, | 1578 kUnsignedLessThan, kUnsignedGreaterThanOrEqual}, |
1489 {&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", | 1579 {&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", |
1490 kUnsignedLessThanOrEqual, kUnsignedGreaterThan}}; | 1580 kUnsignedLessThanOrEqual, kUnsignedGreaterThan}}; |
1491 | 1581 |
| 1582 } // namespace |
1492 | 1583 |
1493 typedef InstructionSelectorTestWithParam<Comparison> | 1584 typedef InstructionSelectorTestWithParam<Comparison> |
1494 InstructionSelectorFPComparisonTest; | 1585 InstructionSelectorF64ComparisonTest; |
1495 | 1586 |
1496 | 1587 |
1497 TEST_P(InstructionSelectorFPComparisonTest, WithParameters) { | 1588 TEST_P(InstructionSelectorF64ComparisonTest, WithParameters) { |
1498 const Comparison& cmp = GetParam(); | 1589 const Comparison& cmp = GetParam(); |
1499 StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64); | 1590 StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64); |
1500 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))); | 1591 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))); |
1501 Stream const s = m.Build(); | 1592 Stream const s = m.Build(); |
1502 ASSERT_EQ(1U, s.size()); | 1593 ASSERT_EQ(1U, s.size()); |
1503 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); | 1594 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); |
1504 ASSERT_EQ(2U, s[0]->InputCount()); | 1595 ASSERT_EQ(2U, s[0]->InputCount()); |
1505 ASSERT_EQ(1U, s[0]->OutputCount()); | 1596 ASSERT_EQ(1U, s[0]->OutputCount()); |
1506 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1597 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1507 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); | 1598 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); |
1508 } | 1599 } |
1509 | 1600 |
1510 | 1601 |
1511 TEST_P(InstructionSelectorFPComparisonTest, NegatedWithParameters) { | 1602 TEST_P(InstructionSelectorF64ComparisonTest, NegatedWithParameters) { |
1512 const Comparison& cmp = GetParam(); | 1603 const Comparison& cmp = GetParam(); |
1513 StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64); | 1604 StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64); |
1514 m.Return( | 1605 m.Return( |
1515 m.WordBinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)))); | 1606 m.WordBinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)))); |
1516 Stream const s = m.Build(); | 1607 Stream const s = m.Build(); |
1517 ASSERT_EQ(1U, s.size()); | 1608 ASSERT_EQ(1U, s.size()); |
1518 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); | 1609 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); |
1519 ASSERT_EQ(2U, s[0]->InputCount()); | 1610 ASSERT_EQ(2U, s[0]->InputCount()); |
1520 ASSERT_EQ(1U, s[0]->OutputCount()); | 1611 ASSERT_EQ(1U, s[0]->OutputCount()); |
1521 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1612 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1522 EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition()); | 1613 EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition()); |
1523 } | 1614 } |
1524 | 1615 |
1525 | 1616 |
1526 TEST_P(InstructionSelectorFPComparisonTest, WithImmediateZeroOnRight) { | 1617 TEST_P(InstructionSelectorF64ComparisonTest, WithImmediateZeroOnRight) { |
1527 const Comparison& cmp = GetParam(); | 1618 const Comparison& cmp = GetParam(); |
1528 StreamBuilder m(this, kMachInt32, kMachFloat64); | 1619 StreamBuilder m(this, kMachInt32, kMachFloat64); |
1529 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float64Constant(0.0))); | 1620 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float64Constant(0.0))); |
1530 Stream const s = m.Build(); | 1621 Stream const s = m.Build(); |
1531 ASSERT_EQ(1U, s.size()); | 1622 ASSERT_EQ(1U, s.size()); |
1532 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); | 1623 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); |
1533 ASSERT_EQ(2U, s[0]->InputCount()); | 1624 ASSERT_EQ(2U, s[0]->InputCount()); |
1534 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 1625 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
1535 ASSERT_EQ(1U, s[0]->OutputCount()); | 1626 ASSERT_EQ(1U, s[0]->OutputCount()); |
1536 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1627 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1537 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); | 1628 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); |
1538 } | 1629 } |
1539 | 1630 |
1540 | 1631 |
1541 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1632 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
1542 InstructionSelectorFPComparisonTest, | 1633 InstructionSelectorF64ComparisonTest, |
1543 ::testing::ValuesIn(kFPComparisons)); | 1634 ::testing::ValuesIn(kF64Comparisons)); |
1544 | 1635 |
1545 | 1636 |
1546 TEST_F(InstructionSelectorTest, Float64EqualWithImmediateZeroOnLeft) { | 1637 TEST_F(InstructionSelectorTest, Float64EqualWithImmediateZeroOnLeft) { |
1547 StreamBuilder m(this, kMachInt32, kMachFloat64); | 1638 StreamBuilder m(this, kMachInt32, kMachFloat64); |
1548 m.Return(m.Float64Equal(m.Float64Constant(0.0), m.Parameter(0))); | 1639 m.Return(m.Float64Equal(m.Float64Constant(0.0), m.Parameter(0))); |
1549 Stream s = m.Build(); | 1640 Stream s = m.Build(); |
1550 ASSERT_EQ(1U, s.size()); | 1641 ASSERT_EQ(1U, s.size()); |
1551 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); | 1642 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode()); |
1552 EXPECT_EQ(2U, s[0]->InputCount()); | 1643 EXPECT_EQ(2U, s[0]->InputCount()); |
1553 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 1644 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
1554 EXPECT_EQ(1U, s[0]->OutputCount()); | 1645 EXPECT_EQ(1U, s[0]->OutputCount()); |
1555 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1646 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1556 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1647 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1557 } | 1648 } |
1558 | 1649 |
1559 | 1650 |
1560 // ----------------------------------------------------------------------------- | 1651 // ----------------------------------------------------------------------------- |
1561 // Miscellaneous. | 1652 // Floating point arithmetic. |
| 1653 |
| 1654 |
| 1655 typedef InstructionSelectorTestWithParam<FAI> InstructionSelectorFAITest; |
| 1656 |
| 1657 |
| 1658 TEST_P(InstructionSelectorFAITest, Parameters) { |
| 1659 const FAI& fai = GetParam(); |
| 1660 StreamBuilder m(this, fai.machine_type, fai.machine_type, fai.machine_type); |
| 1661 Node* const p0 = m.Parameter(0); |
| 1662 Node* const p1 = m.Parameter(1); |
| 1663 Node* const r = (m.*fai.constructor)(p0, p1); |
| 1664 m.Return(r); |
| 1665 Stream const s = m.Build(); |
| 1666 ASSERT_EQ(1U, s.size()); |
| 1667 EXPECT_EQ(fai.arch_opcode, s[0]->arch_opcode()); |
| 1668 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 1669 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1670 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1671 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 1672 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1673 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0))); |
| 1674 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1675 } |
| 1676 |
| 1677 |
| 1678 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFAITest, |
| 1679 ::testing::ValuesIn(kFAIs)); |
| 1680 |
| 1681 |
| 1682 TEST_F(InstructionSelectorTest, Float32AddWithFloat32Mul) { |
| 1683 { |
| 1684 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32, |
| 1685 kMachFloat32); |
| 1686 Node* const p0 = m.Parameter(0); |
| 1687 Node* const p1 = m.Parameter(1); |
| 1688 Node* const p2 = m.Parameter(2); |
| 1689 Node* const n = m.Float32Add(m.Float32Mul(p0, p1), p2); |
| 1690 m.Return(n); |
| 1691 Stream s = m.Build(); |
| 1692 ASSERT_EQ(1U, s.size()); |
| 1693 EXPECT_EQ(kArmVmlaF32, s[0]->arch_opcode()); |
| 1694 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1695 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0))); |
| 1696 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1))); |
| 1697 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(2))); |
| 1698 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1699 EXPECT_TRUE( |
| 1700 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
| 1701 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1702 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1703 } |
| 1704 { |
| 1705 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32, |
| 1706 kMachFloat32); |
| 1707 Node* const p0 = m.Parameter(0); |
| 1708 Node* const p1 = m.Parameter(1); |
| 1709 Node* const p2 = m.Parameter(2); |
| 1710 Node* const n = m.Float32Add(p0, m.Float32Mul(p1, p2)); |
| 1711 m.Return(n); |
| 1712 Stream s = m.Build(); |
| 1713 ASSERT_EQ(1U, s.size()); |
| 1714 EXPECT_EQ(kArmVmlaF32, s[0]->arch_opcode()); |
| 1715 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1716 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1717 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 1718 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2))); |
| 1719 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1720 EXPECT_TRUE( |
| 1721 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
| 1722 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1723 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1724 } |
| 1725 } |
| 1726 |
| 1727 |
| 1728 TEST_F(InstructionSelectorTest, Float64AddWithFloat64Mul) { |
| 1729 { |
| 1730 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64, |
| 1731 kMachFloat64); |
| 1732 Node* const p0 = m.Parameter(0); |
| 1733 Node* const p1 = m.Parameter(1); |
| 1734 Node* const p2 = m.Parameter(2); |
| 1735 Node* const n = m.Float64Add(m.Float64Mul(p0, p1), p2); |
| 1736 m.Return(n); |
| 1737 Stream s = m.Build(); |
| 1738 ASSERT_EQ(1U, s.size()); |
| 1739 EXPECT_EQ(kArmVmlaF64, s[0]->arch_opcode()); |
| 1740 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1741 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0))); |
| 1742 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1))); |
| 1743 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(2))); |
| 1744 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1745 EXPECT_TRUE( |
| 1746 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
| 1747 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1748 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1749 } |
| 1750 { |
| 1751 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64, |
| 1752 kMachFloat64); |
| 1753 Node* const p0 = m.Parameter(0); |
| 1754 Node* const p1 = m.Parameter(1); |
| 1755 Node* const p2 = m.Parameter(2); |
| 1756 Node* const n = m.Float64Add(p0, m.Float64Mul(p1, p2)); |
| 1757 m.Return(n); |
| 1758 Stream s = m.Build(); |
| 1759 ASSERT_EQ(1U, s.size()); |
| 1760 EXPECT_EQ(kArmVmlaF64, s[0]->arch_opcode()); |
| 1761 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1762 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1763 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 1764 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2))); |
| 1765 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1766 EXPECT_TRUE( |
| 1767 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
| 1768 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1769 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1770 } |
| 1771 } |
| 1772 |
| 1773 |
| 1774 TEST_F(InstructionSelectorTest, Float32SubWithMinusZero) { |
| 1775 StreamBuilder m(this, kMachFloat32, kMachFloat32); |
| 1776 Node* const p0 = m.Parameter(0); |
| 1777 Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0); |
| 1778 m.Return(n); |
| 1779 Stream s = m.Build(); |
| 1780 ASSERT_EQ(1U, s.size()); |
| 1781 EXPECT_EQ(kArmVnegF32, s[0]->arch_opcode()); |
| 1782 ASSERT_EQ(1U, s[0]->InputCount()); |
| 1783 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1784 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1785 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1786 } |
1562 | 1787 |
1563 | 1788 |
1564 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) { | 1789 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) { |
1565 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 1790 StreamBuilder m(this, kMachFloat64, kMachFloat64); |
1566 Node* const p0 = m.Parameter(0); | 1791 Node* const p0 = m.Parameter(0); |
1567 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); | 1792 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); |
1568 m.Return(n); | 1793 m.Return(n); |
1569 Stream s = m.Build(); | 1794 Stream s = m.Build(); |
1570 ASSERT_EQ(1U, s.size()); | 1795 ASSERT_EQ(1U, s.size()); |
1571 EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode()); | 1796 EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode()); |
1572 ASSERT_EQ(1U, s[0]->InputCount()); | 1797 ASSERT_EQ(1U, s[0]->InputCount()); |
1573 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1798 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
1574 ASSERT_EQ(1U, s[0]->OutputCount()); | 1799 ASSERT_EQ(1U, s[0]->OutputCount()); |
1575 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1800 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
1576 } | 1801 } |
1577 | 1802 |
1578 | 1803 |
| 1804 TEST_F(InstructionSelectorTest, Float32SubWithFloat32Mul) { |
| 1805 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32, kMachFloat32); |
| 1806 Node* const p0 = m.Parameter(0); |
| 1807 Node* const p1 = m.Parameter(1); |
| 1808 Node* const p2 = m.Parameter(2); |
| 1809 Node* const n = m.Float32Sub(p0, m.Float32Mul(p1, p2)); |
| 1810 m.Return(n); |
| 1811 Stream s = m.Build(); |
| 1812 ASSERT_EQ(1U, s.size()); |
| 1813 EXPECT_EQ(kArmVmlsF32, s[0]->arch_opcode()); |
| 1814 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1815 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1816 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 1817 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2))); |
| 1818 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1819 EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
| 1820 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1821 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1822 } |
| 1823 |
| 1824 |
| 1825 TEST_F(InstructionSelectorTest, Float64SubWithFloat64Mul) { |
| 1826 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64, kMachFloat64); |
| 1827 Node* const p0 = m.Parameter(0); |
| 1828 Node* const p1 = m.Parameter(1); |
| 1829 Node* const p2 = m.Parameter(2); |
| 1830 Node* const n = m.Float64Sub(p0, m.Float64Mul(p1, p2)); |
| 1831 m.Return(n); |
| 1832 Stream s = m.Build(); |
| 1833 ASSERT_EQ(1U, s.size()); |
| 1834 EXPECT_EQ(kArmVmlsF64, s[0]->arch_opcode()); |
| 1835 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1836 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1837 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 1838 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2))); |
| 1839 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1840 EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
| 1841 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1842 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1843 } |
| 1844 |
| 1845 |
| 1846 TEST_F(InstructionSelectorTest, Float32Sqrt) { |
| 1847 StreamBuilder m(this, kMachFloat32, kMachFloat32); |
| 1848 Node* const p0 = m.Parameter(0); |
| 1849 Node* const n = m.Float32Sqrt(p0); |
| 1850 m.Return(n); |
| 1851 Stream s = m.Build(); |
| 1852 ASSERT_EQ(1U, s.size()); |
| 1853 EXPECT_EQ(kArmVsqrtF32, s[0]->arch_opcode()); |
| 1854 ASSERT_EQ(1U, s[0]->InputCount()); |
| 1855 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1856 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1857 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1858 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1859 } |
| 1860 |
| 1861 |
| 1862 TEST_F(InstructionSelectorTest, Float64Sqrt) { |
| 1863 StreamBuilder m(this, kMachFloat64, kMachFloat64); |
| 1864 Node* const p0 = m.Parameter(0); |
| 1865 Node* const n = m.Float64Sqrt(p0); |
| 1866 m.Return(n); |
| 1867 Stream s = m.Build(); |
| 1868 ASSERT_EQ(1U, s.size()); |
| 1869 EXPECT_EQ(kArmVsqrtF64, s[0]->arch_opcode()); |
| 1870 ASSERT_EQ(1U, s[0]->InputCount()); |
| 1871 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1872 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1873 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1874 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1875 } |
| 1876 |
| 1877 |
| 1878 // ----------------------------------------------------------------------------- |
| 1879 // Miscellaneous. |
| 1880 |
| 1881 |
1579 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) { | 1882 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) { |
1580 { | 1883 { |
1581 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32); | 1884 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32); |
1582 Node* const p0 = m.Parameter(0); | 1885 Node* const p0 = m.Parameter(0); |
1583 Node* const p1 = m.Parameter(1); | 1886 Node* const p1 = m.Parameter(1); |
1584 Node* const p2 = m.Parameter(2); | 1887 Node* const p2 = m.Parameter(2); |
1585 Node* const n = m.Int32Add(p0, m.Int32Mul(p1, p2)); | 1888 Node* const n = m.Int32Add(p0, m.Int32Mul(p1, p2)); |
1586 m.Return(n); | 1889 m.Return(n); |
1587 Stream s = m.Build(); | 1890 Stream s = m.Build(); |
1588 ASSERT_EQ(1U, s.size()); | 1891 ASSERT_EQ(1U, s.size()); |
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 EXPECT_EQ(kArmClz, s[0]->arch_opcode()); | 2740 EXPECT_EQ(kArmClz, s[0]->arch_opcode()); |
2438 ASSERT_EQ(1U, s[0]->InputCount()); | 2741 ASSERT_EQ(1U, s[0]->InputCount()); |
2439 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2742 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
2440 ASSERT_EQ(1U, s[0]->OutputCount()); | 2743 ASSERT_EQ(1U, s[0]->OutputCount()); |
2441 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 2744 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
2442 } | 2745 } |
2443 | 2746 |
2444 } // namespace compiler | 2747 } // namespace compiler |
2445 } // namespace internal | 2748 } // namespace internal |
2446 } // namespace v8 | 2749 } // namespace v8 |
OLD | NEW |