| 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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 int64_t res = reinterpret_cast<LongAddRegCode>(entry)(a, b); | 1493 int64_t res = reinterpret_cast<LongAddRegCode>(entry)(a, b); |
| 1494 EXPECT_EQ((a + b), res); | 1494 EXPECT_EQ((a + b), res); |
| 1495 a = 2147483647; | 1495 a = 2147483647; |
| 1496 b = 600000; | 1496 b = 600000; |
| 1497 res = reinterpret_cast<LongAddRegCode>(entry)(a, b); | 1497 res = reinterpret_cast<LongAddRegCode>(entry)(a, b); |
| 1498 EXPECT_EQ((a + b), res); | 1498 EXPECT_EQ((a + b), res); |
| 1499 } | 1499 } |
| 1500 | 1500 |
| 1501 | 1501 |
| 1502 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { | 1502 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { |
| 1503 // Preserve clobbered callee-saved register (EBX). | |
| 1504 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. | 1503 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. |
| 1505 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. | 1504 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. |
| 1506 __ addl(EAX, Address(ESP, 3 * kWordSize)); // low. | 1505 __ addl(EAX, Address(ESP, 3 * kWordSize)); // low. |
| 1507 __ adcl(EDX, Address(ESP, 4 * kWordSize)); // high. | 1506 __ adcl(EDX, Address(ESP, 4 * kWordSize)); // high. |
| 1508 // Result is in EAX/EDX. | 1507 // Result is in EAX/EDX. |
| 1509 __ ret(); | 1508 __ ret(); |
| 1510 } | 1509 } |
| 1511 | 1510 |
| 1512 | 1511 |
| 1513 ASSEMBLER_TEST_RUN(LongAddAddress, entry) { | 1512 ASSEMBLER_TEST_RUN(LongAddAddress, entry) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 int64_t res = reinterpret_cast<LongSubRegCode>(entry)(a, b); | 1544 int64_t res = reinterpret_cast<LongSubRegCode>(entry)(a, b); |
| 1546 EXPECT_EQ((a - b), res); | 1545 EXPECT_EQ((a - b), res); |
| 1547 a = 600000; | 1546 a = 600000; |
| 1548 b = 2147483647; | 1547 b = 2147483647; |
| 1549 res = reinterpret_cast<LongSubRegCode>(entry)(a, b); | 1548 res = reinterpret_cast<LongSubRegCode>(entry)(a, b); |
| 1550 EXPECT_EQ((a - b), res); | 1549 EXPECT_EQ((a - b), res); |
| 1551 } | 1550 } |
| 1552 | 1551 |
| 1553 | 1552 |
| 1554 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { | 1553 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { |
| 1555 // Preserve clobbered callee-saved register (EBX). | |
| 1556 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. | 1554 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. |
| 1557 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. | 1555 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. |
| 1558 __ subl(EAX, Address(ESP, 3 * kWordSize)); // low. | 1556 __ subl(EAX, Address(ESP, 3 * kWordSize)); // low. |
| 1559 __ sbbl(EDX, Address(ESP, 4 * kWordSize)); // high. | 1557 __ sbbl(EDX, Address(ESP, 4 * kWordSize)); // high. |
| 1560 // Result is in EAX/EDX. | 1558 // Result is in EAX/EDX. |
| 1561 __ ret(); | 1559 __ ret(); |
| 1562 } | 1560 } |
| 1563 | 1561 |
| 1564 | 1562 |
| 1565 ASSEMBLER_TEST_RUN(LongSubAddress, entry) { | 1563 ASSEMBLER_TEST_RUN(LongSubAddress, entry) { |
| 1566 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); | 1564 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); |
| 1567 int64_t a = 12; | 1565 int64_t a = 12; |
| 1568 int64_t b = 14; | 1566 int64_t b = 14; |
| 1569 int64_t res = reinterpret_cast<LongSubAddressCode>(entry)(a, b); | 1567 int64_t res = reinterpret_cast<LongSubAddressCode>(entry)(a, b); |
| 1570 EXPECT_EQ((a - b), res); | 1568 EXPECT_EQ((a - b), res); |
| 1571 a = 600000; | 1569 a = 600000; |
| 1572 b = 2147483647; | 1570 b = 2147483647; |
| 1573 res = reinterpret_cast<LongSubAddressCode>(entry)(a, b); | 1571 res = reinterpret_cast<LongSubAddressCode>(entry)(a, b); |
| 1574 EXPECT_EQ((a - b), res); | 1572 EXPECT_EQ((a - b), res); |
| 1575 } | 1573 } |
| 1576 | 1574 |
| 1577 | 1575 |
| 1576 ASSEMBLER_TEST_GENERATE(LongSubAddress2, assembler) { |
| 1577 // Preserve clobbered callee-saved register (EBX). |
| 1578 __ pushl(EBX); |
| 1579 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 1580 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 1581 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| 1582 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high |
| 1583 __ subl(ESP, Immediate(2 * kWordSize)); |
| 1584 __ movl(Address(ESP, 0 * kWordSize), EAX); // left low. |
| 1585 __ movl(Address(ESP, 1 * kWordSize), EDX); // left high. |
| 1586 __ subl(Address(ESP, 0 * kWordSize), ECX); |
| 1587 __ sbbl(Address(ESP, 1 * kWordSize), EBX); |
| 1588 __ movl(EAX, Address(ESP, 0 * kWordSize)); |
| 1589 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 1590 __ addl(ESP, Immediate(2 * kWordSize)); |
| 1591 __ popl(EBX); |
| 1592 // Result is in EAX/EDX. |
| 1593 __ ret(); |
| 1594 } |
| 1595 |
| 1596 |
| 1597 ASSEMBLER_TEST_RUN(LongSubAddress2, entry) { |
| 1598 typedef int64_t (*LongSubAddress2Code)(int64_t a, int64_t b); |
| 1599 int64_t a = 12; |
| 1600 int64_t b = 14; |
| 1601 int64_t res = reinterpret_cast<LongSubAddress2Code>(entry)(a, b); |
| 1602 EXPECT_EQ((a - b), res); |
| 1603 a = 600000; |
| 1604 b = 2147483647; |
| 1605 res = reinterpret_cast<LongSubAddress2Code>(entry)(a, b); |
| 1606 EXPECT_EQ((a - b), res); |
| 1607 } |
| 1608 |
| 1609 |
| 1610 ASSEMBLER_TEST_GENERATE(LongAddAddress2, assembler) { |
| 1611 // Preserve clobbered callee-saved register (EBX). |
| 1612 __ pushl(EBX); |
| 1613 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 1614 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 1615 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| 1616 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high |
| 1617 __ subl(ESP, Immediate(2 * kWordSize)); |
| 1618 __ movl(Address(ESP, 0 * kWordSize), EAX); // left low. |
| 1619 __ movl(Address(ESP, 1 * kWordSize), EDX); // left high. |
| 1620 __ addl(Address(ESP, 0 * kWordSize), ECX); |
| 1621 __ adcl(Address(ESP, 1 * kWordSize), EBX); |
| 1622 __ movl(EAX, Address(ESP, 0 * kWordSize)); |
| 1623 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 1624 __ addl(ESP, Immediate(2 * kWordSize)); |
| 1625 __ popl(EBX); |
| 1626 // Result is in EAX/EDX. |
| 1627 __ ret(); |
| 1628 } |
| 1629 |
| 1630 |
| 1631 ASSEMBLER_TEST_RUN(LongAddAddress2, entry) { |
| 1632 typedef int64_t (*LongAddAddress2Code)(int64_t a, int64_t b); |
| 1633 int64_t a = 12; |
| 1634 int64_t b = 14; |
| 1635 int64_t res = reinterpret_cast<LongAddAddress2Code>(entry)(a, b); |
| 1636 EXPECT_EQ((a + b), res); |
| 1637 a = 600000; |
| 1638 b = 2147483647; |
| 1639 res = reinterpret_cast<LongAddAddress2Code>(entry)(a, b); |
| 1640 EXPECT_EQ((a + b), res); |
| 1641 } |
| 1642 |
| 1643 |
| 1578 // Testing only the lower 64-bit value of 'cvtdq2pd'. | 1644 // Testing only the lower 64-bit value of 'cvtdq2pd'. |
| 1579 ASSEMBLER_TEST_GENERATE(IntegerToDoubleConversion, assembler) { | 1645 ASSEMBLER_TEST_GENERATE(IntegerToDoubleConversion, assembler) { |
| 1580 __ movsd(XMM1, Address(ESP, kWordSize)); | 1646 __ movsd(XMM1, Address(ESP, kWordSize)); |
| 1581 __ cvtdq2pd(XMM2, XMM1); | 1647 __ cvtdq2pd(XMM2, XMM1); |
| 1582 __ pushl(EAX); | 1648 __ pushl(EAX); |
| 1583 __ pushl(EAX); | 1649 __ pushl(EAX); |
| 1584 __ movsd(Address(ESP, 0), XMM2); | 1650 __ movsd(Address(ESP, 0), XMM2); |
| 1585 __ fldl(Address(ESP, 0)); | 1651 __ fldl(Address(ESP, 0)); |
| 1586 __ popl(EAX); | 1652 __ popl(EAX); |
| 1587 __ popl(EAX); | 1653 __ popl(EAX); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 typedef double (*OrpdCode)(double d); | 1740 typedef double (*OrpdCode)(double d); |
| 1675 double res = reinterpret_cast<OrpdCode>(entry)(12.56e3); | 1741 double res = reinterpret_cast<OrpdCode>(entry)(12.56e3); |
| 1676 EXPECT_FLOAT_EQ(-12.56e3, res, 0.0); | 1742 EXPECT_FLOAT_EQ(-12.56e3, res, 0.0); |
| 1677 } | 1743 } |
| 1678 | 1744 |
| 1679 | 1745 |
| 1680 ASSEMBLER_TEST_GENERATE(Pextrd0, assembler) { | 1746 ASSEMBLER_TEST_GENERATE(Pextrd0, assembler) { |
| 1681 if (CPUFeatures::sse4_1_supported()) { | 1747 if (CPUFeatures::sse4_1_supported()) { |
| 1682 __ movsd(XMM0, Address(ESP, kWordSize)); | 1748 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 1683 __ pextrd(EAX, XMM0, Immediate(0)); | 1749 __ pextrd(EAX, XMM0, Immediate(0)); |
| 1684 __ ret(); | |
| 1685 } | 1750 } |
| 1751 __ ret(); |
| 1686 } | 1752 } |
| 1687 | 1753 |
| 1688 | 1754 |
| 1689 ASSEMBLER_TEST_RUN(Pextrd0, entry) { | 1755 ASSEMBLER_TEST_RUN(Pextrd0, entry) { |
| 1690 if (CPUFeatures::sse4_1_supported()) { | 1756 if (CPUFeatures::sse4_1_supported()) { |
| 1691 typedef int32_t (*PextrdCode0)(double d); | 1757 typedef int32_t (*PextrdCode0)(double d); |
| 1692 int32_t res = reinterpret_cast<PextrdCode0>(entry)(123456789); | 1758 int32_t res = reinterpret_cast<PextrdCode0>(entry)(123456789); |
| 1693 EXPECT_EQ(0x54000000, res); | 1759 EXPECT_EQ(0x54000000, res); |
| 1694 } | 1760 } |
| 1695 } | 1761 } |
| 1696 | 1762 |
| 1697 | 1763 |
| 1698 ASSEMBLER_TEST_GENERATE(Pextrd1, assembler) { | 1764 ASSEMBLER_TEST_GENERATE(Pextrd1, assembler) { |
| 1699 if (CPUFeatures::sse4_1_supported()) { | 1765 if (CPUFeatures::sse4_1_supported()) { |
| 1700 __ movsd(XMM0, Address(ESP, kWordSize)); | 1766 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 1701 __ pextrd(EAX, XMM0, Immediate(1)); | 1767 __ pextrd(EAX, XMM0, Immediate(1)); |
| 1702 __ ret(); | |
| 1703 } | 1768 } |
| 1769 __ ret(); |
| 1704 } | 1770 } |
| 1705 | 1771 |
| 1706 | 1772 |
| 1707 ASSEMBLER_TEST_RUN(Pextrd1, entry) { | 1773 ASSEMBLER_TEST_RUN(Pextrd1, entry) { |
| 1708 if (CPUFeatures::sse4_1_supported()) { | 1774 if (CPUFeatures::sse4_1_supported()) { |
| 1709 typedef int32_t (*PextrdCode1)(double d); | 1775 typedef int32_t (*PextrdCode1)(double d); |
| 1710 int32_t res = reinterpret_cast<PextrdCode1>(entry)(123456789); | 1776 int32_t res = reinterpret_cast<PextrdCode1>(entry)(123456789); |
| 1711 EXPECT_EQ(0x419d6f34, res); | 1777 EXPECT_EQ(0x419d6f34, res); |
| 1712 } | 1778 } |
| 1713 } | 1779 } |
| 1714 | 1780 |
| 1715 | 1781 |
| 1716 ASSEMBLER_TEST_GENERATE(Pmovsxdq, assembler) { | 1782 ASSEMBLER_TEST_GENERATE(Pmovsxdq, assembler) { |
| 1717 if (CPUFeatures::sse4_1_supported()) { | 1783 if (CPUFeatures::sse4_1_supported()) { |
| 1718 __ movsd(XMM0, Address(ESP, kWordSize)); | 1784 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 1719 __ pmovsxdq(XMM0, XMM0); | 1785 __ pmovsxdq(XMM0, XMM0); |
| 1720 __ pextrd(EAX, XMM0, Immediate(1)); | 1786 __ pextrd(EAX, XMM0, Immediate(1)); |
| 1721 __ ret(); | |
| 1722 } | 1787 } |
| 1788 __ ret(); |
| 1723 } | 1789 } |
| 1724 | 1790 |
| 1725 | 1791 |
| 1726 ASSEMBLER_TEST_RUN(Pmovsxdq, entry) { | 1792 ASSEMBLER_TEST_RUN(Pmovsxdq, entry) { |
| 1727 if (CPUFeatures::sse4_1_supported()) { | 1793 if (CPUFeatures::sse4_1_supported()) { |
| 1728 typedef int32_t (*PmovsxdqCode)(double d); | 1794 typedef int32_t (*PmovsxdqCode)(double d); |
| 1729 int32_t res = reinterpret_cast<PmovsxdqCode>(entry)(123456789); | 1795 int32_t res = reinterpret_cast<PmovsxdqCode>(entry)(123456789); |
| 1730 EXPECT_EQ(0, res); | 1796 EXPECT_EQ(0, res); |
| 1731 } | 1797 } |
| 1732 } | 1798 } |
| 1733 | 1799 |
| 1734 | 1800 |
| 1735 ASSEMBLER_TEST_GENERATE(Pcmpeqq, assembler) { | 1801 ASSEMBLER_TEST_GENERATE(Pcmpeqq, assembler) { |
| 1736 if (CPUFeatures::sse4_1_supported()) { | 1802 if (CPUFeatures::sse4_1_supported()) { |
| 1737 __ movsd(XMM0, Address(ESP, kWordSize)); | 1803 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 1738 __ xorpd(XMM1, XMM1); | 1804 __ xorpd(XMM1, XMM1); |
| 1739 __ pcmpeqq(XMM0, XMM1); | 1805 __ pcmpeqq(XMM0, XMM1); |
| 1740 __ movd(EAX, XMM0); | 1806 __ movd(EAX, XMM0); |
| 1741 __ ret(); | |
| 1742 } | 1807 } |
| 1808 __ ret(); |
| 1743 } | 1809 } |
| 1744 | 1810 |
| 1745 | 1811 |
| 1746 ASSEMBLER_TEST_RUN(Pcmpeqq, entry) { | 1812 ASSEMBLER_TEST_RUN(Pcmpeqq, entry) { |
| 1747 if (CPUFeatures::sse4_1_supported()) { | 1813 if (CPUFeatures::sse4_1_supported()) { |
| 1748 typedef int32_t (*PcmpeqqCode)(double d); | 1814 typedef int32_t (*PcmpeqqCode)(double d); |
| 1749 int32_t res = reinterpret_cast<PcmpeqqCode>(entry)(0); | 1815 int32_t res = reinterpret_cast<PcmpeqqCode>(entry)(0); |
| 1750 EXPECT_EQ(-1, res); | 1816 EXPECT_EQ(-1, res); |
| 1751 } | 1817 } |
| 1752 } | 1818 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1765 } | 1831 } |
| 1766 | 1832 |
| 1767 | 1833 |
| 1768 ASSEMBLER_TEST_RUN(AndPd, entry) { | 1834 ASSEMBLER_TEST_RUN(AndPd, entry) { |
| 1769 typedef double (*AndpdCode)(double d); | 1835 typedef double (*AndpdCode)(double d); |
| 1770 double res = reinterpret_cast<AndpdCode>(entry)(12.56e3); | 1836 double res = reinterpret_cast<AndpdCode>(entry)(12.56e3); |
| 1771 EXPECT_FLOAT_EQ(12.56e3, res, 0.0); | 1837 EXPECT_FLOAT_EQ(12.56e3, res, 0.0); |
| 1772 } | 1838 } |
| 1773 | 1839 |
| 1774 | 1840 |
| 1841 ASSEMBLER_TEST_GENERATE(Movq, assembler) { |
| 1842 __ movq(XMM0, Address(ESP, kWordSize)); |
| 1843 __ subl(ESP, Immediate(kDoubleSize)); |
| 1844 __ movq(Address(ESP, 0), XMM0); |
| 1845 __ fldl(Address(ESP, 0)); |
| 1846 __ addl(ESP, Immediate(kDoubleSize)); |
| 1847 __ ret(); |
| 1848 } |
| 1849 |
| 1850 |
| 1851 ASSEMBLER_TEST_RUN(Movq, entry) { |
| 1852 typedef double (*MovqCode)(double d); |
| 1853 double res = reinterpret_cast<MovqCode>(entry)(12.34e5); |
| 1854 EXPECT_FLOAT_EQ(12.34e5, res, 0.0); |
| 1855 } |
| 1856 |
| 1857 |
| 1775 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) { | 1858 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) { |
| 1776 __ movsd(XMM0, Address(ESP, kWordSize)); | 1859 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 1777 __ DoubleAbs(XMM0); | 1860 __ DoubleAbs(XMM0); |
| 1778 __ pushl(EAX); | 1861 __ pushl(EAX); |
| 1779 __ pushl(EAX); | 1862 __ pushl(EAX); |
| 1780 __ movsd(Address(ESP, 0), XMM0); | 1863 __ movsd(Address(ESP, 0), XMM0); |
| 1781 __ fldl(Address(ESP, 0)); | 1864 __ fldl(Address(ESP, 0)); |
| 1782 __ popl(EAX); | 1865 __ popl(EAX); |
| 1783 __ popl(EAX); | 1866 __ popl(EAX); |
| 1784 __ ret(); | 1867 __ ret(); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1980 EAX); | 2063 EAX); |
| 1981 __ popl(EAX); | 2064 __ popl(EAX); |
| 1982 __ popl(CTX); | 2065 __ popl(CTX); |
| 1983 __ ret(); | 2066 __ ret(); |
| 1984 } | 2067 } |
| 1985 | 2068 |
| 1986 | 2069 |
| 1987 } // namespace dart | 2070 } // namespace dart |
| 1988 | 2071 |
| 1989 #endif // defined TARGET_ARCH_IA32 | 2072 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |