OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/os.h" | 9 #include "vm/os.h" |
10 #include "vm/unit_test.h" | 10 #include "vm/unit_test.h" |
(...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 __ ret(); | 1381 __ ret(); |
1382 } | 1382 } |
1383 | 1383 |
1384 | 1384 |
1385 ASSEMBLER_TEST_RUN(SingleFPOperations, entry) { | 1385 ASSEMBLER_TEST_RUN(SingleFPOperations, entry) { |
1386 typedef float (*SingleFPOperationsCode)(); | 1386 typedef float (*SingleFPOperationsCode)(); |
1387 float res = reinterpret_cast<SingleFPOperationsCode>(entry)(); | 1387 float res = reinterpret_cast<SingleFPOperationsCode>(entry)(); |
1388 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); | 1388 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
1389 } | 1389 } |
1390 | 1390 |
| 1391 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { |
| 1392 __ movq(RAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 1393 __ movd(XMM10, RAX); |
| 1394 __ shufps(XMM10, XMM10, Immediate(0x0)); |
| 1395 __ movq(RAX, Immediate(bit_cast<int32_t, float>(3.4f))); |
| 1396 __ movd(XMM9, RAX); |
| 1397 __ shufps(XMM9, XMM9, Immediate(0x0)); |
| 1398 __ addps(XMM10, XMM9); // 15.7f |
| 1399 __ mulps(XMM10, XMM9); // 53.38f |
| 1400 __ subps(XMM10, XMM9); // 49.98f |
| 1401 __ divps(XMM10, XMM9); // 14.7f |
| 1402 __ movaps(XMM0, XMM10); |
| 1403 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. |
| 1404 __ ret(); |
| 1405 } |
| 1406 |
| 1407 |
| 1408 ASSEMBLER_TEST_RUN(PackedFPOperations, entry) { |
| 1409 typedef float (*PackedFPOperationsCode)(); |
| 1410 float res = reinterpret_cast<PackedFPOperationsCode>(entry)(); |
| 1411 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); |
| 1412 } |
| 1413 |
| 1414 |
| 1415 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { |
| 1416 __ movq(RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1417 __ movd(XMM0, RAX); |
| 1418 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1419 |
| 1420 __ movaps(XMM11, XMM0); // Copy XMM0 |
| 1421 __ reciprocalps(XMM11); // 0.25 |
| 1422 __ sqrtps(XMM11); // 0.5 |
| 1423 __ rsqrtps(XMM0); // ~0.5 |
| 1424 __ subps(XMM0, XMM11); // ~0.0 |
| 1425 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. |
| 1426 __ ret(); |
| 1427 } |
| 1428 |
| 1429 |
| 1430 ASSEMBLER_TEST_RUN(PackedFPOperations2, entry) { |
| 1431 typedef float (*PackedFPOperations2Code)(); |
| 1432 float res = reinterpret_cast<PackedFPOperations2Code>(entry)(); |
| 1433 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
| 1434 } |
| 1435 |
| 1436 |
| 1437 ASSEMBLER_TEST_GENERATE(PackedCompareEQ, assembler) { |
| 1438 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1439 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1440 __ cmppseq(XMM0, XMM1); |
| 1441 __ pushq(RAX); |
| 1442 __ movss(Address(RSP, 0), XMM0); |
| 1443 __ popq(RAX); |
| 1444 __ ret(); |
| 1445 } |
| 1446 |
| 1447 |
| 1448 ASSEMBLER_TEST_RUN(PackedCompareEQ, entry) { |
| 1449 typedef uint32_t (*PackedCompareEQCode)(); |
| 1450 uint32_t res = reinterpret_cast<PackedCompareEQCode>(entry)(); |
| 1451 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1452 } |
| 1453 |
| 1454 |
| 1455 ASSEMBLER_TEST_GENERATE(PackedCompareNEQ, assembler) { |
| 1456 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1457 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1458 __ cmppsneq(XMM0, XMM1); |
| 1459 __ pushq(RAX); |
| 1460 __ movss(Address(RSP, 0), XMM0); |
| 1461 __ popq(RAX); |
| 1462 __ ret(); |
| 1463 } |
| 1464 |
| 1465 |
| 1466 ASSEMBLER_TEST_RUN(PackedCompareNEQ, entry) { |
| 1467 typedef uint32_t (*PackedCompareNEQCode)(); |
| 1468 uint32_t res = reinterpret_cast<PackedCompareNEQCode>(entry)(); |
| 1469 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
| 1470 } |
| 1471 |
| 1472 |
| 1473 ASSEMBLER_TEST_GENERATE(PackedCompareLT, assembler) { |
| 1474 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1475 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1476 __ cmppslt(XMM0, XMM1); |
| 1477 __ pushq(RAX); |
| 1478 __ movss(Address(RSP, 0), XMM0); |
| 1479 __ popq(RAX); |
| 1480 __ ret(); |
| 1481 } |
| 1482 |
| 1483 |
| 1484 ASSEMBLER_TEST_RUN(PackedCompareLT, entry) { |
| 1485 typedef uint32_t (*PackedCompareLTCode)(); |
| 1486 uint32_t res = reinterpret_cast<PackedCompareLTCode>(entry)(); |
| 1487 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
| 1488 } |
| 1489 |
| 1490 |
| 1491 ASSEMBLER_TEST_GENERATE(PackedCompareLE, assembler) { |
| 1492 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1493 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1494 __ cmppsle(XMM0, XMM1); |
| 1495 __ pushq(RAX); |
| 1496 __ movss(Address(RSP, 0), XMM0); |
| 1497 __ popq(RAX); |
| 1498 __ ret(); |
| 1499 } |
| 1500 |
| 1501 |
| 1502 ASSEMBLER_TEST_RUN(PackedCompareLE, entry) { |
| 1503 typedef uint32_t (*PackedCompareLECode)(); |
| 1504 uint32_t res = reinterpret_cast<PackedCompareLECode>(entry)(); |
| 1505 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
| 1506 } |
| 1507 |
| 1508 |
| 1509 ASSEMBLER_TEST_GENERATE(PackedCompareNLT, assembler) { |
| 1510 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1511 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1512 __ cmppsnlt(XMM0, XMM1); |
| 1513 __ pushq(RAX); |
| 1514 __ movss(Address(RSP, 0), XMM0); |
| 1515 __ popq(RAX); |
| 1516 __ ret(); |
| 1517 } |
| 1518 |
| 1519 |
| 1520 ASSEMBLER_TEST_RUN(PackedCompareNLT, entry) { |
| 1521 typedef uint32_t (*PackedCompareNLTCode)(); |
| 1522 uint32_t res = reinterpret_cast<PackedCompareNLTCode>(entry)(); |
| 1523 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1524 } |
| 1525 |
| 1526 |
| 1527 ASSEMBLER_TEST_GENERATE(PackedCompareNLE, assembler) { |
| 1528 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1529 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1530 __ cmppsnle(XMM0, XMM1); |
| 1531 __ pushq(RAX); |
| 1532 __ movss(Address(RSP, 0), XMM0); |
| 1533 __ popq(RAX); |
| 1534 __ ret(); |
| 1535 } |
| 1536 |
| 1537 |
| 1538 ASSEMBLER_TEST_RUN(PackedCompareNLE, entry) { |
| 1539 typedef uint32_t (*PackedCompareNLECode)(); |
| 1540 uint32_t res = reinterpret_cast<PackedCompareNLECode>(entry)(); |
| 1541 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1542 } |
| 1543 |
| 1544 |
| 1545 ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) { |
| 1546 __ movl(RAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 1547 __ movd(XMM0, RAX); |
| 1548 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1549 __ negateps(XMM0); |
| 1550 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. |
| 1551 __ ret(); |
| 1552 } |
| 1553 |
| 1554 |
| 1555 ASSEMBLER_TEST_RUN(PackedNegate, entry) { |
| 1556 typedef float (*PackedNegateCode)(); |
| 1557 float res = reinterpret_cast<PackedNegateCode>(entry)(); |
| 1558 EXPECT_FLOAT_EQ(-12.3f, res, 0.001f); |
| 1559 } |
| 1560 |
| 1561 |
| 1562 ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) { |
| 1563 __ movl(RAX, Immediate(bit_cast<int32_t, float>(-15.3f))); |
| 1564 __ movd(XMM0, RAX); |
| 1565 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1566 __ absps(XMM0); |
| 1567 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. |
| 1568 __ ret(); |
| 1569 } |
| 1570 |
| 1571 |
| 1572 ASSEMBLER_TEST_RUN(PackedAbsolute, entry) { |
| 1573 typedef float (*PackedAbsoluteCode)(); |
| 1574 float res = reinterpret_cast<PackedAbsoluteCode>(entry)(); |
| 1575 EXPECT_FLOAT_EQ(15.3f, res, 0.001f); |
| 1576 } |
| 1577 |
| 1578 |
| 1579 ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) { |
| 1580 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 1581 __ zerowps(XMM0); |
| 1582 __ shufps(XMM0, XMM0, Immediate(0xFF)); // Copy the W lane which is now 0.0. |
| 1583 __ ret(); |
| 1584 } |
| 1585 |
| 1586 |
| 1587 ASSEMBLER_TEST_RUN(PackedSetWZero, entry) { |
| 1588 typedef float (*PackedSetWZeroCode)(); |
| 1589 float res = reinterpret_cast<PackedSetWZeroCode>(entry)(); |
| 1590 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
| 1591 } |
| 1592 |
| 1593 |
| 1594 ASSEMBLER_TEST_GENERATE(PackedMin, assembler) { |
| 1595 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1596 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1597 __ minps(XMM0, XMM1); |
| 1598 __ ret(); |
| 1599 } |
| 1600 |
| 1601 |
| 1602 ASSEMBLER_TEST_RUN(PackedMin, entry) { |
| 1603 typedef float (*PackedMinCode)(); |
| 1604 float res = reinterpret_cast<PackedMinCode>(entry)(); |
| 1605 EXPECT_FLOAT_EQ(2.0f, res, 0.001f); |
| 1606 } |
| 1607 |
| 1608 |
| 1609 ASSEMBLER_TEST_GENERATE(PackedMax, assembler) { |
| 1610 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1611 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1612 __ maxps(XMM0, XMM1); |
| 1613 __ ret(); |
| 1614 } |
| 1615 |
| 1616 |
| 1617 ASSEMBLER_TEST_RUN(PackedMax, entry) { |
| 1618 typedef float (*PackedMaxCode)(); |
| 1619 float res = reinterpret_cast<PackedMaxCode>(entry)(); |
| 1620 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); |
| 1621 } |
| 1622 |
| 1623 |
| 1624 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { |
| 1625 static const struct ALIGN16 { |
| 1626 uint32_t a; |
| 1627 uint32_t b; |
| 1628 uint32_t c; |
| 1629 uint32_t d; |
| 1630 } constant1 = |
| 1631 { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0 }; |
| 1632 static const struct ALIGN16 { |
| 1633 uint32_t a; |
| 1634 uint32_t b; |
| 1635 uint32_t c; |
| 1636 uint32_t d; |
| 1637 } constant2 = |
| 1638 { 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F }; |
| 1639 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); |
| 1640 __ movups(XMM0, Address(RAX, 0)); |
| 1641 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant2))); |
| 1642 __ movups(XMM1, Address(RAX, 0)); |
| 1643 __ orps(XMM0, XMM1); |
| 1644 __ pushq(RAX); |
| 1645 __ movss(Address(RSP, 0), XMM0); |
| 1646 __ popq(RAX); |
| 1647 __ ret(); |
| 1648 } |
| 1649 |
| 1650 |
| 1651 ASSEMBLER_TEST_RUN(PackedLogicalOr, entry) { |
| 1652 typedef uint32_t (*PackedLogicalOrCode)(); |
| 1653 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(entry)(); |
| 1654 EXPECT_EQ(0xFFFFFFFF, res); |
| 1655 } |
| 1656 |
| 1657 |
| 1658 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { |
| 1659 static const struct ALIGN16 { |
| 1660 uint32_t a; |
| 1661 uint32_t b; |
| 1662 uint32_t c; |
| 1663 uint32_t d; |
| 1664 } constant1 = |
| 1665 { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0 }; |
| 1666 static const struct ALIGN16 { |
| 1667 uint32_t a; |
| 1668 uint32_t b; |
| 1669 uint32_t c; |
| 1670 uint32_t d; |
| 1671 } constant2 = |
| 1672 { 0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F }; |
| 1673 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); |
| 1674 __ movups(XMM0, Address(RAX, 0)); |
| 1675 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant2))); |
| 1676 __ andps(XMM0, Address(RAX, 0)); |
| 1677 __ pushq(RAX); |
| 1678 __ movss(Address(RSP, 0), XMM0); |
| 1679 __ popq(RAX); |
| 1680 __ ret(); |
| 1681 } |
| 1682 |
| 1683 |
| 1684 ASSEMBLER_TEST_RUN(PackedLogicalAnd, entry) { |
| 1685 typedef uint32_t (*PackedLogicalAndCode)(); |
| 1686 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(entry)(); |
| 1687 EXPECT_EQ(static_cast<uword>(0x0000F000), res); |
| 1688 } |
| 1689 |
| 1690 |
| 1691 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { |
| 1692 static const struct ALIGN16 { |
| 1693 uint32_t a; |
| 1694 uint32_t b; |
| 1695 uint32_t c; |
| 1696 uint32_t d; |
| 1697 } constant1 = |
| 1698 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; |
| 1699 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); |
| 1700 __ movups(XMM9, Address(RAX, 0)); |
| 1701 __ notps(XMM9); |
| 1702 __ movaps(XMM0, XMM9); |
| 1703 __ pushq(RAX); |
| 1704 __ movss(Address(RSP, 0), XMM0); |
| 1705 __ popq(RAX); |
| 1706 __ ret(); |
| 1707 } |
| 1708 |
| 1709 |
| 1710 ASSEMBLER_TEST_RUN(PackedLogicalNot, entry) { |
| 1711 typedef uint32_t (*PackedLogicalNotCode)(); |
| 1712 uint32_t res = reinterpret_cast<PackedLogicalNotCode>(entry)(); |
| 1713 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1714 } |
1391 | 1715 |
1392 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { | 1716 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { |
1393 __ movq(RAX, Immediate(bit_cast<int64_t, double>(1024.67))); | 1717 __ movq(RAX, Immediate(bit_cast<int64_t, double>(1024.67))); |
1394 __ pushq(R15); // Callee saved. | 1718 __ pushq(R15); // Callee saved. |
1395 __ pushq(RAX); | 1719 __ pushq(RAX); |
1396 __ movsd(XMM0, Address(RSP, 0)); | 1720 __ movsd(XMM0, Address(RSP, 0)); |
1397 __ movsd(XMM1, XMM0); | 1721 __ movsd(XMM1, XMM0); |
1398 __ movsd(XMM2, XMM1); | 1722 __ movsd(XMM2, XMM1); |
1399 __ movsd(XMM3, XMM2); | 1723 __ movsd(XMM3, XMM2); |
1400 __ movsd(XMM4, XMM3); | 1724 __ movsd(XMM4, XMM3); |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 EXPECT_EQ(0, res); | 2265 EXPECT_EQ(0, res); |
1942 res = reinterpret_cast<ExtractSignBits>(entry)(-1.0); | 2266 res = reinterpret_cast<ExtractSignBits>(entry)(-1.0); |
1943 EXPECT_EQ(1, res); | 2267 EXPECT_EQ(1, res); |
1944 res = reinterpret_cast<ExtractSignBits>(entry)(-0.0); | 2268 res = reinterpret_cast<ExtractSignBits>(entry)(-0.0); |
1945 EXPECT_EQ(1, res); | 2269 EXPECT_EQ(1, res); |
1946 } | 2270 } |
1947 | 2271 |
1948 } // namespace dart | 2272 } // namespace dart |
1949 | 2273 |
1950 #endif // defined TARGET_ARCH_X64 | 2274 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |