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 | 1391 |
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 } | |
1715 | |
1716 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { | 1392 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { |
1717 __ movq(RAX, Immediate(bit_cast<int64_t, double>(1024.67))); | 1393 __ movq(RAX, Immediate(bit_cast<int64_t, double>(1024.67))); |
1718 __ pushq(R15); // Callee saved. | 1394 __ pushq(R15); // Callee saved. |
1719 __ pushq(RAX); | 1395 __ pushq(RAX); |
1720 __ movsd(XMM0, Address(RSP, 0)); | 1396 __ movsd(XMM0, Address(RSP, 0)); |
1721 __ movsd(XMM1, XMM0); | 1397 __ movsd(XMM1, XMM0); |
1722 __ movsd(XMM2, XMM1); | 1398 __ movsd(XMM2, XMM1); |
1723 __ movsd(XMM3, XMM2); | 1399 __ movsd(XMM3, XMM2); |
1724 __ movsd(XMM4, XMM3); | 1400 __ movsd(XMM4, XMM3); |
1725 __ movsd(XMM5, XMM4); | 1401 __ movsd(XMM5, XMM4); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2265 EXPECT_EQ(0, res); | 1941 EXPECT_EQ(0, res); |
2266 res = reinterpret_cast<ExtractSignBits>(entry)(-1.0); | 1942 res = reinterpret_cast<ExtractSignBits>(entry)(-1.0); |
2267 EXPECT_EQ(1, res); | 1943 EXPECT_EQ(1, res); |
2268 res = reinterpret_cast<ExtractSignBits>(entry)(-0.0); | 1944 res = reinterpret_cast<ExtractSignBits>(entry)(-0.0); |
2269 EXPECT_EQ(1, res); | 1945 EXPECT_EQ(1, res); |
2270 } | 1946 } |
2271 | 1947 |
2272 } // namespace dart | 1948 } // namespace dart |
2273 | 1949 |
2274 #endif // defined TARGET_ARCH_X64 | 1950 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |