OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 "src/assembler-inl.h" | 5 #include "src/assembler-inl.h" |
6 #include "src/wasm/wasm-macro-gen.h" | 6 #include "src/wasm/wasm-macro-gen.h" |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
9 #include "test/cctest/wasm/wasm-run-utils.h" | 9 #include "test/cctest/wasm/wasm-run-utils.h" |
10 | 10 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 , WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 1), \ | 361 , WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 1), \ |
362 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 2), \ | 362 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 2), \ |
363 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 3) | 363 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 3) |
364 | 364 |
365 #define TO_BYTE(val) static_cast<byte>(val) | 365 #define TO_BYTE(val) static_cast<byte>(val) |
366 #define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op) | 366 #define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op) |
367 #define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat) | 367 #define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat) |
368 #define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op) | 368 #define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op) |
369 #define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op) | 369 #define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op) |
370 #define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift) | 370 #define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift) |
| 371 #define WASM_SIMD_CONCAT_OP(op, bytes, x, y) \ |
| 372 x, y, WASM_SIMD_OP(op), TO_BYTE(bytes) |
371 #define WASM_SIMD_SELECT(format, x, y, z) \ | 373 #define WASM_SIMD_SELECT(format, x, y, z) \ |
372 x, y, z, WASM_SIMD_OP(kExprS##format##Select) | 374 x, y, z, WASM_SIMD_OP(kExprS##format##Select) |
373 // Since boolean vectors can't be checked directly, materialize them into | 375 // Since boolean vectors can't be checked directly, materialize them into |
374 // integer vectors using a Select operation. | 376 // integer vectors using a Select operation. |
375 #define WASM_SIMD_MATERIALIZE_BOOLS(format, x) \ | 377 #define WASM_SIMD_MATERIALIZE_BOOLS(format, x) \ |
376 x, WASM_SIMD_I##format##_SPLAT(WASM_ONE), \ | 378 x, WASM_SIMD_I##format##_SPLAT(WASM_ONE), \ |
377 WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \ | 379 WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \ |
378 WASM_SIMD_OP(kExprS##format##Select) | 380 WASM_SIMD_OP(kExprS##format##Select) |
379 | 381 |
380 #define WASM_SIMD_F32x4_SPLAT(x) x, WASM_SIMD_OP(kExprF32x4Splat) | 382 #define WASM_SIMD_F32x4_SPLAT(x) x, WASM_SIMD_OP(kExprF32x4Splat) |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_MIPS || | 1590 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_MIPS || |
1589 // V8_TARGET_ARCH_MIPS64 | 1591 // V8_TARGET_ARCH_MIPS64 |
1590 | 1592 |
1591 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 | 1593 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 |
1592 WASM_SIMD_SELECT_TEST(16x8) | 1594 WASM_SIMD_SELECT_TEST(16x8) |
1593 | 1595 |
1594 WASM_SIMD_SELECT_TEST(8x16) | 1596 WASM_SIMD_SELECT_TEST(8x16) |
1595 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 | 1597 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 |
1596 | 1598 |
1597 #if V8_TARGET_ARCH_ARM | 1599 #if V8_TARGET_ARCH_ARM |
| 1600 template <typename T> |
| 1601 void RunUnaryPermuteOpTest( |
| 1602 WasmOpcode simd_op, |
| 1603 const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
| 1604 FLAG_wasm_simd_prototype = true; |
| 1605 WasmRunner<int32_t> r(kExecuteCompiled); |
| 1606 // Set up a test pattern as a global, e.g. [0, 1, 2, 3]. |
| 1607 T* global = r.module().AddGlobal<T>(kWasmS128); |
| 1608 static const size_t kElems = kSimd128Size / sizeof(T); |
| 1609 for (size_t i = 0; i < kElems; i++) { |
| 1610 global[i] = i; |
| 1611 } |
| 1612 BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_UNOP(simd_op, WASM_GET_GLOBAL(0))), |
| 1613 WASM_ONE); |
| 1614 |
| 1615 CHECK_EQ(1, r.Call()); |
| 1616 for (size_t i = 0; i < kElems; i++) { |
| 1617 CHECK_EQ(global[i], expected[i]); |
| 1618 } |
| 1619 } |
| 1620 |
| 1621 WASM_EXEC_COMPILED_TEST(S32x2Reverse) { |
| 1622 RunUnaryPermuteOpTest<int32_t>(kExprS32x2Reverse, {{1, 0, 3, 2}}); |
| 1623 } |
| 1624 |
| 1625 WASM_EXEC_COMPILED_TEST(S16x4Reverse) { |
| 1626 RunUnaryPermuteOpTest<int16_t>(kExprS16x4Reverse, {{3, 2, 1, 0, 7, 6, 5, 4}}); |
| 1627 } |
| 1628 |
| 1629 WASM_EXEC_COMPILED_TEST(S16x2Reverse) { |
| 1630 RunUnaryPermuteOpTest<int16_t>(kExprS16x2Reverse, {{1, 0, 3, 2, 5, 4, 7, 6}}); |
| 1631 } |
| 1632 |
| 1633 WASM_EXEC_COMPILED_TEST(S8x8Reverse) { |
| 1634 RunUnaryPermuteOpTest<int8_t>(kExprS8x8Reverse, {{7, 6, 5, 4, 3, 2, 1, 0, 15, |
| 1635 14, 13, 12, 11, 10, 9, 8}}); |
| 1636 } |
| 1637 |
| 1638 WASM_EXEC_COMPILED_TEST(S8x4Reverse) { |
| 1639 RunUnaryPermuteOpTest<int8_t>(kExprS8x4Reverse, {{3, 2, 1, 0, 7, 6, 5, 4, 11, |
| 1640 10, 9, 8, 15, 14, 13, 12}}); |
| 1641 } |
| 1642 |
| 1643 WASM_EXEC_COMPILED_TEST(S8x2Reverse) { |
| 1644 RunUnaryPermuteOpTest<int8_t>( |
| 1645 kExprS8x2Reverse, |
| 1646 {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}}); |
| 1647 } |
| 1648 |
| 1649 template <typename T> |
| 1650 void RunBinaryPermuteOpTest( |
| 1651 WasmOpcode simd_op, |
| 1652 const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
| 1653 FLAG_wasm_simd_prototype = true; |
| 1654 WasmRunner<int32_t> r(kExecuteCompiled); |
| 1655 // Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7]. |
| 1656 T* global1 = r.module().AddGlobal<T>(kWasmS128); |
| 1657 T* global2 = r.module().AddGlobal<T>(kWasmS128); |
| 1658 static const size_t kElems = kSimd128Size / sizeof(T); |
| 1659 for (size_t i = 0; i < kElems; i++) { |
| 1660 global1[i] = i; |
| 1661 global2[i] = kElems + i; |
| 1662 } |
| 1663 BUILD(r, |
| 1664 WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(simd_op, WASM_GET_GLOBAL(0), |
| 1665 WASM_GET_GLOBAL(1))), |
| 1666 WASM_ONE); |
| 1667 |
| 1668 CHECK_EQ(1, r.Call()); |
| 1669 for (size_t i = 0; i < expected.size(); i++) { |
| 1670 CHECK_EQ(global1[i], expected[i]); |
| 1671 } |
| 1672 } |
| 1673 |
| 1674 WASM_EXEC_COMPILED_TEST(S32x4ZipLeft) { |
| 1675 RunBinaryPermuteOpTest<int32_t>(kExprS32x4ZipLeft, {{0, 4, 1, 5}}); |
| 1676 } |
| 1677 |
| 1678 WASM_EXEC_COMPILED_TEST(S32x4ZipRight) { |
| 1679 RunBinaryPermuteOpTest<int32_t>(kExprS32x4ZipRight, {{2, 6, 3, 7}}); |
| 1680 } |
| 1681 |
| 1682 WASM_EXEC_COMPILED_TEST(S32x4UnzipLeft) { |
| 1683 RunBinaryPermuteOpTest<int32_t>(kExprS32x4UnzipLeft, {{0, 2, 4, 6}}); |
| 1684 } |
| 1685 |
| 1686 WASM_EXEC_COMPILED_TEST(S32x4UnzipRight) { |
| 1687 RunBinaryPermuteOpTest<int32_t>(kExprS32x4UnzipRight, {{1, 3, 5, 7}}); |
| 1688 } |
| 1689 |
| 1690 WASM_EXEC_COMPILED_TEST(S32x4TransposeLeft) { |
| 1691 RunBinaryPermuteOpTest<int32_t>(kExprS32x4TransposeLeft, {{0, 4, 2, 6}}); |
| 1692 } |
| 1693 |
| 1694 WASM_EXEC_COMPILED_TEST(S32x4TransposeRight) { |
| 1695 RunBinaryPermuteOpTest<int32_t>(kExprS32x4TransposeRight, {{1, 5, 3, 7}}); |
| 1696 } |
| 1697 |
| 1698 WASM_EXEC_COMPILED_TEST(S16x8ZipLeft) { |
| 1699 RunBinaryPermuteOpTest<int16_t>(kExprS16x8ZipLeft, |
| 1700 {{0, 8, 1, 9, 2, 10, 3, 11}}); |
| 1701 } |
| 1702 |
| 1703 WASM_EXEC_COMPILED_TEST(S16x8ZipRight) { |
| 1704 RunBinaryPermuteOpTest<int16_t>(kExprS16x8ZipRight, |
| 1705 {{4, 12, 5, 13, 6, 14, 7, 15}}); |
| 1706 } |
| 1707 |
| 1708 WASM_EXEC_COMPILED_TEST(S16x8UnzipLeft) { |
| 1709 RunBinaryPermuteOpTest<int16_t>(kExprS16x8UnzipLeft, |
| 1710 {{0, 2, 4, 6, 8, 10, 12, 14}}); |
| 1711 } |
| 1712 |
| 1713 WASM_EXEC_COMPILED_TEST(S16x8UnzipRight) { |
| 1714 RunBinaryPermuteOpTest<int16_t>(kExprS16x8UnzipRight, |
| 1715 {{1, 3, 5, 7, 9, 11, 13, 15}}); |
| 1716 } |
| 1717 |
| 1718 WASM_EXEC_COMPILED_TEST(S16x8TransposeLeft) { |
| 1719 RunBinaryPermuteOpTest<int16_t>(kExprS16x8TransposeLeft, |
| 1720 {{0, 8, 2, 10, 4, 12, 6, 14}}); |
| 1721 } |
| 1722 |
| 1723 WASM_EXEC_COMPILED_TEST(S16x8TransposeRight) { |
| 1724 RunBinaryPermuteOpTest<int16_t>(kExprS16x8TransposeRight, |
| 1725 {{1, 9, 3, 11, 5, 13, 7, 15}}); |
| 1726 } |
| 1727 |
| 1728 WASM_EXEC_COMPILED_TEST(S8x16ZipLeft) { |
| 1729 RunBinaryPermuteOpTest<int8_t>( |
| 1730 kExprS8x16ZipLeft, |
| 1731 {{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}}); |
| 1732 } |
| 1733 |
| 1734 WASM_EXEC_COMPILED_TEST(S8x16ZipRight) { |
| 1735 RunBinaryPermuteOpTest<int8_t>( |
| 1736 kExprS8x16ZipRight, |
| 1737 {{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31}}); |
| 1738 } |
| 1739 |
| 1740 WASM_EXEC_COMPILED_TEST(S8x16UnzipLeft) { |
| 1741 RunBinaryPermuteOpTest<int8_t>( |
| 1742 kExprS8x16UnzipLeft, |
| 1743 {{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}); |
| 1744 } |
| 1745 |
| 1746 WASM_EXEC_COMPILED_TEST(S8x16UnzipRight) { |
| 1747 RunBinaryPermuteOpTest<int8_t>( |
| 1748 kExprS8x16UnzipRight, |
| 1749 {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}}); |
| 1750 } |
| 1751 |
| 1752 WASM_EXEC_COMPILED_TEST(S8x16TransposeLeft) { |
| 1753 RunBinaryPermuteOpTest<int8_t>( |
| 1754 kExprS8x16TransposeLeft, |
| 1755 {{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30}}); |
| 1756 } |
| 1757 |
| 1758 WASM_EXEC_COMPILED_TEST(S8x16TransposeRight) { |
| 1759 RunBinaryPermuteOpTest<int8_t>( |
| 1760 kExprS8x16TransposeRight, |
| 1761 {{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31}}); |
| 1762 } |
| 1763 |
| 1764 template <typename T> |
| 1765 void RunConcatOpTest(WasmOpcode simd_op, int bytes, |
| 1766 const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
| 1767 FLAG_wasm_simd_prototype = true; |
| 1768 WasmRunner<int32_t> r(kExecuteCompiled); |
| 1769 // Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7]. |
| 1770 T* global1 = r.module().AddGlobal<T>(kWasmS128); |
| 1771 T* global2 = r.module().AddGlobal<T>(kWasmS128); |
| 1772 static const size_t kElems = kSimd128Size / sizeof(T); |
| 1773 for (size_t i = 0; i < kElems; i++) { |
| 1774 global1[i] = i; |
| 1775 global2[i] = kElems + i; |
| 1776 } |
| 1777 BUILD( |
| 1778 r, |
| 1779 WASM_SET_GLOBAL(0, WASM_SIMD_CONCAT_OP(simd_op, bytes, WASM_GET_GLOBAL(0), |
| 1780 WASM_GET_GLOBAL(1))), |
| 1781 WASM_ONE); |
| 1782 |
| 1783 CHECK_EQ(1, r.Call()); |
| 1784 for (size_t i = 0; i < expected.size(); i++) { |
| 1785 CHECK_EQ(global1[i], expected[i]); |
| 1786 } |
| 1787 } |
| 1788 |
| 1789 WASM_EXEC_COMPILED_TEST(S8x16Concat) { |
| 1790 std::array<int8_t, kSimd128Size> expected; |
| 1791 for (int k = 1; k < 16; k++) { |
| 1792 int j = 0; |
| 1793 // last 16 - k bytes of first vector. |
| 1794 for (int i = k; i < kSimd128Size; i++) { |
| 1795 expected[j++] = i; |
| 1796 } |
| 1797 // first k bytes of second vector |
| 1798 for (int i = 0; i < k; i++) { |
| 1799 expected[j++] = i + kSimd128Size; |
| 1800 } |
| 1801 RunConcatOpTest<int8_t>(kExprS8x16Concat, k, expected); |
| 1802 } |
| 1803 } |
| 1804 |
1598 // Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer | 1805 // Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer |
1599 // result. Use relational ops on numeric vectors to create the boolean vector | 1806 // result. Use relational ops on numeric vectors to create the boolean vector |
1600 // test inputs. Test inputs with all true, all false, one true, and one false. | 1807 // test inputs. Test inputs with all true, all false, one true, and one false. |
1601 #define WASM_SIMD_BOOL_REDUCTION_TEST(format, lanes) \ | 1808 #define WASM_SIMD_BOOL_REDUCTION_TEST(format, lanes) \ |
1602 WASM_EXEC_TEST(ReductionTest##lanes) { \ | 1809 WASM_EXEC_TEST(ReductionTest##lanes) { \ |
1603 FLAG_wasm_simd_prototype = true; \ | 1810 FLAG_wasm_simd_prototype = true; \ |
1604 WasmRunner<int32_t> r(kExecuteCompiled); \ | 1811 WasmRunner<int32_t> r(kExecuteCompiled); \ |
1605 byte zero = r.AllocateLocal(kWasmS128); \ | 1812 byte zero = r.AllocateLocal(kWasmS128); \ |
1606 byte one_one = r.AllocateLocal(kWasmS128); \ | 1813 byte one_one = r.AllocateLocal(kWasmS128); \ |
1607 byte reduced = r.AllocateLocal(kWasmI32); \ | 1814 byte reduced = r.AllocateLocal(kWasmI32); \ |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 | 1969 |
1763 WASM_EXEC_COMPILED_TEST(S1x8Or) { RunS1x8BinOpTest(kExprS1x8Or, Or); } | 1970 WASM_EXEC_COMPILED_TEST(S1x8Or) { RunS1x8BinOpTest(kExprS1x8Or, Or); } |
1764 | 1971 |
1765 WASM_EXEC_COMPILED_TEST(S1x8Xor) { RunS1x8BinOpTest(kExprS1x8Xor, Xor); } | 1972 WASM_EXEC_COMPILED_TEST(S1x8Xor) { RunS1x8BinOpTest(kExprS1x8Xor, Xor); } |
1766 | 1973 |
1767 WASM_EXEC_COMPILED_TEST(S1x16And) { RunS1x16BinOpTest(kExprS1x16And, And); } | 1974 WASM_EXEC_COMPILED_TEST(S1x16And) { RunS1x16BinOpTest(kExprS1x16And, And); } |
1768 | 1975 |
1769 WASM_EXEC_COMPILED_TEST(S1x16Or) { RunS1x16BinOpTest(kExprS1x16Or, Or); } | 1976 WASM_EXEC_COMPILED_TEST(S1x16Or) { RunS1x16BinOpTest(kExprS1x16Or, Or); } |
1770 | 1977 |
1771 WASM_EXEC_COMPILED_TEST(S1x16Xor) { RunS1x16BinOpTest(kExprS1x16Xor, Xor); } | 1978 WASM_EXEC_COMPILED_TEST(S1x16Xor) { RunS1x16BinOpTest(kExprS1x16Xor, Xor); } |
| 1979 #endif // !V8_TARGET_ARCH_ARM |
1772 | 1980 |
| 1981 #if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
1773 WASM_EXEC_COMPILED_TEST(SimdI32x4ExtractWithF32x4) { | 1982 WASM_EXEC_COMPILED_TEST(SimdI32x4ExtractWithF32x4) { |
1774 FLAG_wasm_simd_prototype = true; | 1983 FLAG_wasm_simd_prototype = true; |
1775 WasmRunner<int32_t> r(kExecuteCompiled); | 1984 WasmRunner<int32_t> r(kExecuteCompiled); |
1776 BUILD(r, WASM_IF_ELSE_I( | 1985 BUILD(r, WASM_IF_ELSE_I( |
1777 WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE( | 1986 WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE( |
1778 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))), | 1987 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))), |
1779 WASM_I32_REINTERPRET_F32(WASM_F32(30.5))), | 1988 WASM_I32_REINTERPRET_F32(WASM_F32(30.5))), |
1780 WASM_I32V(1), WASM_I32V(0))); | 1989 WASM_I32V(1), WASM_I32V(0))); |
1781 CHECK_EQ(1, r.Call()); | 1990 CHECK_EQ(1, r.Call()); |
1782 } | 1991 } |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 WASM_SIMD_I32x4_EXTRACT_LANE( | 2222 WASM_SIMD_I32x4_EXTRACT_LANE( |
2014 0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO))); | 2223 0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO))); |
2015 | 2224 |
2016 FOR_INT32_INPUTS(i) { | 2225 FOR_INT32_INPUTS(i) { |
2017 int32_t expected = *i; | 2226 int32_t expected = *i; |
2018 r.module().WriteMemory(&memory[0], expected); | 2227 r.module().WriteMemory(&memory[0], expected); |
2019 CHECK_EQ(expected, r.Call()); | 2228 CHECK_EQ(expected, r.Call()); |
2020 } | 2229 } |
2021 } | 2230 } |
2022 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET | 2231 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
OLD | NEW |