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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace compiler { | 9 namespace compiler { |
10 | 10 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 // ARM64 arithmetic with overflow instructions. | 133 // ARM64 arithmetic with overflow instructions. |
134 static const MachInst2 kOvfAddSubInstructions[] = { | 134 static const MachInst2 kOvfAddSubInstructions[] = { |
135 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", | 135 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", |
136 kArm64Add32, kMachInt32}, | 136 kArm64Add32, kMachInt32}, |
137 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", | 137 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", |
138 kArm64Sub32, kMachInt32}}; | 138 kArm64Sub32, kMachInt32}}; |
139 | 139 |
140 | 140 |
141 // ARM64 shift instructions. | 141 // ARM64 shift instructions. |
142 static const MachInst2 kShiftInstructions[] = { | 142 static const MachInst2 kShiftInstructions[] = { |
143 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32}, | 143 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32}, |
144 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64}, | 144 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64}, |
145 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32}, | 145 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, kMachInt32}, |
146 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64}, | 146 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, kMachInt64}, |
147 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32}, | 147 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, kMachInt32}, |
148 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64}, | 148 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, kMachInt64}, |
149 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, | 149 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, |
150 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; | 150 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; |
151 | 151 |
152 | 152 |
153 // ARM64 Mul/Div instructions. | 153 // ARM64 Mul/Div instructions. |
154 static const MachInst2 kMulDivInstructions[] = { | 154 static const MachInst2 kMulDivInstructions[] = { |
155 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, | 155 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, |
156 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, | 156 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, |
157 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, | 157 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, |
158 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, | 158 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, |
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1480 StreamBuilder m(this, kMachInt64, kMachInt64); | 1480 StreamBuilder m(this, kMachInt64, kMachInt64); |
1481 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0))); | 1481 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0))); |
1482 Stream s = m.Build(); | 1482 Stream s = m.Build(); |
1483 ASSERT_EQ(1U, s.size()); | 1483 ASSERT_EQ(1U, s.size()); |
1484 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); | 1484 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
1485 EXPECT_EQ(1U, s[0]->InputCount()); | 1485 EXPECT_EQ(1U, s[0]->InputCount()); |
1486 EXPECT_EQ(1U, s[0]->OutputCount()); | 1486 EXPECT_EQ(1U, s[0]->OutputCount()); |
1487 } | 1487 } |
1488 } | 1488 } |
1489 | 1489 |
| 1490 |
| 1491 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { |
| 1492 TRACED_FORRANGE(int32_t, lsb, 1, 31) { |
| 1493 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 1494 uint32_t jnk = rng()->NextInt(); |
| 1495 jnk >>= 32 - lsb; |
| 1496 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 1497 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1498 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), |
| 1499 m.Int32Constant(lsb))); |
| 1500 Stream s = m.Build(); |
| 1501 ASSERT_EQ(1U, s.size()); |
| 1502 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 1503 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1504 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 1505 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 1506 } |
| 1507 } |
| 1508 TRACED_FORRANGE(int32_t, lsb, 1, 31) { |
| 1509 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 1510 uint32_t jnk = rng()->NextInt(); |
| 1511 jnk >>= 32 - lsb; |
| 1512 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 1513 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1514 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), |
| 1515 m.Int32Constant(lsb))); |
| 1516 Stream s = m.Build(); |
| 1517 ASSERT_EQ(1U, s.size()); |
| 1518 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 1519 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1520 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 1521 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 1522 } |
| 1523 } |
| 1524 } |
| 1525 |
| 1526 |
| 1527 TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) { |
| 1528 TRACED_FORRANGE(int32_t, lsb, 1, 63) { |
| 1529 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { |
| 1530 uint64_t jnk = rng()->NextInt64(); |
| 1531 jnk >>= 64 - lsb; |
| 1532 uint64_t msk = |
| 1533 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; |
| 1534 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1535 m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)), |
| 1536 m.Int64Constant(lsb))); |
| 1537 Stream s = m.Build(); |
| 1538 ASSERT_EQ(1U, s.size()); |
| 1539 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 1540 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1541 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 1542 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); |
| 1543 } |
| 1544 } |
| 1545 TRACED_FORRANGE(int32_t, lsb, 1, 63) { |
| 1546 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { |
| 1547 uint64_t jnk = rng()->NextInt64(); |
| 1548 jnk >>= 64 - lsb; |
| 1549 uint64_t msk = |
| 1550 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; |
| 1551 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1552 m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)), |
| 1553 m.Int64Constant(lsb))); |
| 1554 Stream s = m.Build(); |
| 1555 ASSERT_EQ(1U, s.size()); |
| 1556 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 1557 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1558 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 1559 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); |
| 1560 } |
| 1561 } |
| 1562 } |
| 1563 |
| 1564 |
| 1565 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { |
| 1566 TRACED_FORRANGE(int32_t, lsb, 1, 31) { |
| 1567 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 1568 uint32_t msk = (1 << width) - 1; |
| 1569 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1570 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)), |
| 1571 m.Int32Constant(msk))); |
| 1572 Stream s = m.Build(); |
| 1573 ASSERT_EQ(1U, s.size()); |
| 1574 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 1575 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1576 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 1577 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 1578 } |
| 1579 } |
| 1580 TRACED_FORRANGE(int32_t, lsb, 1, 31) { |
| 1581 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 1582 uint32_t msk = (1 << width) - 1; |
| 1583 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1584 m.Return(m.Word32And(m.Int32Constant(msk), |
| 1585 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)))); |
| 1586 Stream s = m.Build(); |
| 1587 ASSERT_EQ(1U, s.size()); |
| 1588 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 1589 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1590 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 1591 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 1592 } |
| 1593 } |
| 1594 } |
| 1595 |
| 1596 |
| 1597 TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) { |
| 1598 TRACED_FORRANGE(int32_t, lsb, 1, 31) { |
| 1599 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 1600 uint64_t msk = (V8_UINT64_C(1) << width) - 1; |
| 1601 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1602 m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb)), |
| 1603 m.Int64Constant(msk))); |
| 1604 Stream s = m.Build(); |
| 1605 ASSERT_EQ(1U, s.size()); |
| 1606 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 1607 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1608 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 1609 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); |
| 1610 } |
| 1611 } |
| 1612 TRACED_FORRANGE(int32_t, lsb, 1, 31) { |
| 1613 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 1614 uint64_t msk = (V8_UINT64_C(1) << width) - 1; |
| 1615 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1616 m.Return(m.Word64And(m.Int64Constant(msk), |
| 1617 m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb)))); |
| 1618 Stream s = m.Build(); |
| 1619 ASSERT_EQ(1U, s.size()); |
| 1620 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 1621 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1622 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 1623 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); |
| 1624 } |
| 1625 } |
| 1626 } |
| 1627 |
1490 } // namespace compiler | 1628 } // namespace compiler |
1491 } // namespace internal | 1629 } // namespace internal |
1492 } // namespace v8 | 1630 } // namespace v8 |
OLD | NEW |