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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 , WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 1), \ | 347 , WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 1), \ |
348 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 2), \ | 348 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 2), \ |
349 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 3) | 349 WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 3) |
350 | 350 |
351 #define TO_BYTE(val) static_cast<byte>(val) | 351 #define TO_BYTE(val) static_cast<byte>(val) |
352 #define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op) | 352 #define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op) |
353 #define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat) | 353 #define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat) |
354 #define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op) | 354 #define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op) |
355 #define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op) | 355 #define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op) |
356 #define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift) | 356 #define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift) |
| 357 #define WASM_SIMD_CONCAT_OP(op, bytes, x, y) \ |
| 358 x, y, WASM_SIMD_OP(op), TO_BYTE(bytes) |
357 #define WASM_SIMD_SELECT(format, x, y, z) \ | 359 #define WASM_SIMD_SELECT(format, x, y, z) \ |
358 x, y, z, WASM_SIMD_OP(kExprS##format##Select) | 360 x, y, z, WASM_SIMD_OP(kExprS##format##Select) |
359 // Since boolean vectors can't be checked directly, materialize them into | 361 // Since boolean vectors can't be checked directly, materialize them into |
360 // integer vectors using a Select operation. | 362 // integer vectors using a Select operation. |
361 #define WASM_SIMD_MATERIALIZE_BOOLS(format, x) \ | 363 #define WASM_SIMD_MATERIALIZE_BOOLS(format, x) \ |
362 x, WASM_SIMD_I##format##_SPLAT(WASM_ONE), \ | 364 x, WASM_SIMD_I##format##_SPLAT(WASM_ONE), \ |
363 WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \ | 365 WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \ |
364 WASM_SIMD_OP(kExprS##format##Select) | 366 WASM_SIMD_OP(kExprS##format##Select) |
365 | 367 |
366 #define WASM_SIMD_F32x4_SPLAT(x) x, WASM_SIMD_OP(kExprF32x4Splat) | 368 #define WASM_SIMD_F32x4_SPLAT(x) x, WASM_SIMD_OP(kExprF32x4Splat) |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 CHECK_EQ(1, r.Call(0x12, 0x34)); \ | 1437 CHECK_EQ(1, r.Call(0x12, 0x34)); \ |
1436 } | 1438 } |
1437 | 1439 |
1438 WASM_SIMD_SELECT_TEST(32x4) | 1440 WASM_SIMD_SELECT_TEST(32x4) |
1439 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 | 1441 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 |
1440 | 1442 |
1441 #if V8_TARGET_ARCH_ARM | 1443 #if V8_TARGET_ARCH_ARM |
1442 WASM_SIMD_SELECT_TEST(16x8) | 1444 WASM_SIMD_SELECT_TEST(16x8) |
1443 WASM_SIMD_SELECT_TEST(8x16) | 1445 WASM_SIMD_SELECT_TEST(8x16) |
1444 | 1446 |
| 1447 template <typename T> |
| 1448 void RunUnaryPermuteOpTest( |
| 1449 WasmOpcode simd_op, |
| 1450 const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
| 1451 FLAG_wasm_simd_prototype = true; |
| 1452 WasmRunner<int32_t> r(kExecuteCompiled); |
| 1453 // Set up a test pattern as a global, e.g. [0, 1, 2, 3]. |
| 1454 T* global = r.module().AddGlobal<T>(kWasmS128); |
| 1455 static const size_t kElems = kSimd128Size / sizeof(T); |
| 1456 for (size_t i = 0; i < kElems; i++) { |
| 1457 global[i] = i; |
| 1458 } |
| 1459 BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_UNOP(simd_op, WASM_GET_GLOBAL(0))), |
| 1460 WASM_ONE); |
| 1461 |
| 1462 CHECK_EQ(1, r.Call()); |
| 1463 for (size_t i = 0; i < kElems; i++) { |
| 1464 CHECK_EQ(global[i], expected[i]); |
| 1465 } |
| 1466 } |
| 1467 |
| 1468 WASM_EXEC_COMPILED_TEST(S64x2Reverse) { |
| 1469 RunUnaryPermuteOpTest<int32_t>(kExprS64x2Reverse, {{2, 3, 0, 1}}); |
| 1470 } |
| 1471 |
| 1472 WASM_EXEC_COMPILED_TEST(S32x2Reverse) { |
| 1473 RunUnaryPermuteOpTest<int32_t>(kExprS32x2Reverse, {{1, 0, 3, 2}}); |
| 1474 } |
| 1475 |
| 1476 WASM_EXEC_COMPILED_TEST(S16x4Reverse) { |
| 1477 RunUnaryPermuteOpTest<int16_t>(kExprS16x4Reverse, {{3, 2, 1, 0, 7, 6, 5, 4}}); |
| 1478 } |
| 1479 |
| 1480 WASM_EXEC_COMPILED_TEST(S16x2Reverse) { |
| 1481 RunUnaryPermuteOpTest<int16_t>(kExprS16x2Reverse, {{1, 0, 3, 2, 5, 4, 7, 6}}); |
| 1482 } |
| 1483 |
| 1484 WASM_EXEC_COMPILED_TEST(S8x8Reverse) { |
| 1485 RunUnaryPermuteOpTest<int8_t>(kExprS8x8Reverse, {{7, 6, 5, 4, 3, 2, 1, 0, 15, |
| 1486 14, 13, 12, 11, 10, 9, 8}}); |
| 1487 } |
| 1488 |
| 1489 WASM_EXEC_COMPILED_TEST(S8x4Reverse) { |
| 1490 RunUnaryPermuteOpTest<int8_t>(kExprS8x4Reverse, {{3, 2, 1, 0, 7, 6, 5, 4, 11, |
| 1491 10, 9, 8, 15, 14, 13, 12}}); |
| 1492 } |
| 1493 |
| 1494 WASM_EXEC_COMPILED_TEST(S8x2Reverse) { |
| 1495 RunUnaryPermuteOpTest<int8_t>( |
| 1496 kExprS8x2Reverse, |
| 1497 {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}}); |
| 1498 } |
| 1499 |
| 1500 template <typename T> |
| 1501 void RunBinaryPermuteOpTest( |
| 1502 WasmOpcode simd_op, |
| 1503 const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
| 1504 FLAG_wasm_simd_prototype = true; |
| 1505 WasmRunner<int32_t> r(kExecuteCompiled); |
| 1506 // Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7]. |
| 1507 T* global1 = r.module().AddGlobal<T>(kWasmS128); |
| 1508 T* global2 = r.module().AddGlobal<T>(kWasmS128); |
| 1509 static const size_t kElems = kSimd128Size / sizeof(T); |
| 1510 for (size_t i = 0; i < kElems; i++) { |
| 1511 global1[i] = i; |
| 1512 global2[i] = kElems + i; |
| 1513 } |
| 1514 BUILD(r, |
| 1515 WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(simd_op, WASM_GET_GLOBAL(0), |
| 1516 WASM_GET_GLOBAL(1))), |
| 1517 WASM_ONE); |
| 1518 |
| 1519 CHECK_EQ(1, r.Call()); |
| 1520 for (size_t i = 0; i < expected.size(); i++) { |
| 1521 CHECK_EQ(global1[i], expected[i]); |
| 1522 } |
| 1523 } |
| 1524 |
| 1525 WASM_EXEC_COMPILED_TEST(S32x4ZipLeft) { |
| 1526 RunBinaryPermuteOpTest<int32_t>(kExprS32x4ZipLeft, {{0, 4, 1, 5}}); |
| 1527 } |
| 1528 |
| 1529 WASM_EXEC_COMPILED_TEST(S32x4ZipRight) { |
| 1530 RunBinaryPermuteOpTest<int32_t>(kExprS32x4ZipRight, {{2, 6, 3, 7}}); |
| 1531 } |
| 1532 |
| 1533 WASM_EXEC_COMPILED_TEST(S32x4UnzipLeft) { |
| 1534 RunBinaryPermuteOpTest<int32_t>(kExprS32x4UnzipLeft, {{0, 2, 4, 6}}); |
| 1535 } |
| 1536 |
| 1537 WASM_EXEC_COMPILED_TEST(S32x4UnzipRight) { |
| 1538 RunBinaryPermuteOpTest<int32_t>(kExprS32x4UnzipRight, {{1, 3, 5, 7}}); |
| 1539 } |
| 1540 |
| 1541 WASM_EXEC_COMPILED_TEST(S32x4TransposeLeft) { |
| 1542 RunBinaryPermuteOpTest<int32_t>(kExprS32x4TransposeLeft, {{0, 4, 2, 6}}); |
| 1543 } |
| 1544 |
| 1545 WASM_EXEC_COMPILED_TEST(S32x4TransposeRight) { |
| 1546 RunBinaryPermuteOpTest<int32_t>(kExprS32x4TransposeRight, {{1, 5, 3, 7}}); |
| 1547 } |
| 1548 |
| 1549 WASM_EXEC_COMPILED_TEST(S16x8ZipLeft) { |
| 1550 RunBinaryPermuteOpTest<int16_t>(kExprS16x8ZipLeft, |
| 1551 {{0, 8, 1, 9, 2, 10, 3, 11}}); |
| 1552 } |
| 1553 |
| 1554 WASM_EXEC_COMPILED_TEST(S16x8ZipRight) { |
| 1555 RunBinaryPermuteOpTest<int16_t>(kExprS16x8ZipRight, |
| 1556 {{4, 12, 5, 13, 6, 14, 7, 15}}); |
| 1557 } |
| 1558 |
| 1559 WASM_EXEC_COMPILED_TEST(S16x8UnzipLeft) { |
| 1560 RunBinaryPermuteOpTest<int16_t>(kExprS16x8UnzipLeft, |
| 1561 {{0, 2, 4, 6, 8, 10, 12, 14}}); |
| 1562 } |
| 1563 |
| 1564 WASM_EXEC_COMPILED_TEST(S16x8UnzipRight) { |
| 1565 RunBinaryPermuteOpTest<int16_t>(kExprS16x8UnzipRight, |
| 1566 {{1, 3, 5, 7, 9, 11, 13, 15}}); |
| 1567 } |
| 1568 |
| 1569 WASM_EXEC_COMPILED_TEST(S16x8TransposeLeft) { |
| 1570 RunBinaryPermuteOpTest<int16_t>(kExprS16x8TransposeLeft, |
| 1571 {{0, 8, 2, 10, 4, 12, 6, 14}}); |
| 1572 } |
| 1573 |
| 1574 WASM_EXEC_COMPILED_TEST(S16x8TransposeRight) { |
| 1575 RunBinaryPermuteOpTest<int16_t>(kExprS16x8TransposeRight, |
| 1576 {{1, 9, 3, 11, 5, 13, 7, 15}}); |
| 1577 } |
| 1578 |
| 1579 WASM_EXEC_COMPILED_TEST(S8x16ZipLeft) { |
| 1580 RunBinaryPermuteOpTest<int8_t>( |
| 1581 kExprS8x16ZipLeft, |
| 1582 {{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}}); |
| 1583 } |
| 1584 |
| 1585 WASM_EXEC_COMPILED_TEST(S8x16ZipRight) { |
| 1586 RunBinaryPermuteOpTest<int8_t>( |
| 1587 kExprS8x16ZipRight, |
| 1588 {{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31}}); |
| 1589 } |
| 1590 |
| 1591 WASM_EXEC_COMPILED_TEST(S8x16UnzipLeft) { |
| 1592 RunBinaryPermuteOpTest<int8_t>( |
| 1593 kExprS8x16UnzipLeft, |
| 1594 {{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}); |
| 1595 } |
| 1596 |
| 1597 WASM_EXEC_COMPILED_TEST(S8x16UnzipRight) { |
| 1598 RunBinaryPermuteOpTest<int8_t>( |
| 1599 kExprS8x16UnzipRight, |
| 1600 {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}}); |
| 1601 } |
| 1602 |
| 1603 WASM_EXEC_COMPILED_TEST(S8x16TransposeLeft) { |
| 1604 RunBinaryPermuteOpTest<int8_t>( |
| 1605 kExprS8x16TransposeLeft, |
| 1606 {{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30}}); |
| 1607 } |
| 1608 |
| 1609 WASM_EXEC_COMPILED_TEST(S8x16TransposeRight) { |
| 1610 RunBinaryPermuteOpTest<int8_t>( |
| 1611 kExprS8x16TransposeRight, |
| 1612 {{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31}}); |
| 1613 } |
| 1614 |
| 1615 template <typename T> |
| 1616 void RunConcatOpTest(WasmOpcode simd_op, int bytes, |
| 1617 const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
| 1618 FLAG_wasm_simd_prototype = true; |
| 1619 WasmRunner<int32_t> r(kExecuteCompiled); |
| 1620 // Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7]. |
| 1621 T* global1 = r.module().AddGlobal<T>(kWasmS128); |
| 1622 T* global2 = r.module().AddGlobal<T>(kWasmS128); |
| 1623 static const size_t kElems = kSimd128Size / sizeof(T); |
| 1624 for (size_t i = 0; i < kElems; i++) { |
| 1625 global1[i] = i; |
| 1626 global2[i] = kElems + i; |
| 1627 } |
| 1628 BUILD( |
| 1629 r, |
| 1630 WASM_SET_GLOBAL(0, WASM_SIMD_CONCAT_OP(simd_op, bytes, WASM_GET_GLOBAL(0), |
| 1631 WASM_GET_GLOBAL(1))), |
| 1632 WASM_ONE); |
| 1633 |
| 1634 CHECK_EQ(1, r.Call()); |
| 1635 for (size_t i = 0; i < expected.size(); i++) { |
| 1636 CHECK_EQ(global1[i], expected[i]); |
| 1637 } |
| 1638 } |
| 1639 |
| 1640 WASM_EXEC_COMPILED_TEST(S8x16Concat) { |
| 1641 std::array<int8_t, kSimd128Size> expected; |
| 1642 for (int k = 1; k < 16; k++) { |
| 1643 int j = 0; |
| 1644 // last 16 - k bytes of first vector. |
| 1645 for (int i = k; i < kSimd128Size; i++) { |
| 1646 expected[j++] = i; |
| 1647 } |
| 1648 // first k bytes of second vector |
| 1649 for (int i = 0; i < k; i++) { |
| 1650 expected[j++] = i + kSimd128Size; |
| 1651 } |
| 1652 RunConcatOpTest<int8_t>(kExprS8x16Concat, k, expected); |
| 1653 } |
| 1654 } |
| 1655 |
1445 // Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer | 1656 // Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer |
1446 // result. Use relational ops on numeric vectors to create the boolean vector | 1657 // result. Use relational ops on numeric vectors to create the boolean vector |
1447 // test inputs. Test inputs with all true, all false, one true, and one false. | 1658 // test inputs. Test inputs with all true, all false, one true, and one false. |
1448 #define WASM_SIMD_BOOL_REDUCTION_TEST(format, lanes) \ | 1659 #define WASM_SIMD_BOOL_REDUCTION_TEST(format, lanes) \ |
1449 WASM_EXEC_TEST(ReductionTest##lanes) { \ | 1660 WASM_EXEC_TEST(ReductionTest##lanes) { \ |
1450 FLAG_wasm_simd_prototype = true; \ | 1661 FLAG_wasm_simd_prototype = true; \ |
1451 WasmRunner<int32_t> r(kExecuteCompiled); \ | 1662 WasmRunner<int32_t> r(kExecuteCompiled); \ |
1452 byte zero = r.AllocateLocal(kWasmS128); \ | 1663 byte zero = r.AllocateLocal(kWasmS128); \ |
1453 byte one_one = r.AllocateLocal(kWasmS128); \ | 1664 byte one_one = r.AllocateLocal(kWasmS128); \ |
1454 byte reduced = r.AllocateLocal(kWasmI32); \ | 1665 byte reduced = r.AllocateLocal(kWasmI32); \ |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 WASM_SIMD_I32x4_EXTRACT_LANE( | 2071 WASM_SIMD_I32x4_EXTRACT_LANE( |
1861 0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO))); | 2072 0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO))); |
1862 | 2073 |
1863 FOR_INT32_INPUTS(i) { | 2074 FOR_INT32_INPUTS(i) { |
1864 int32_t expected = *i; | 2075 int32_t expected = *i; |
1865 r.module().WriteMemory(&memory[0], expected); | 2076 r.module().WriteMemory(&memory[0], expected); |
1866 CHECK_EQ(expected, r.Call()); | 2077 CHECK_EQ(expected, r.Call()); |
1867 } | 2078 } |
1868 } | 2079 } |
1869 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET | 2080 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
OLD | NEW |