OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 // width arguments, we add a single-letter suffix specifying the width. | 673 // width arguments, we add a single-letter suffix specifying the width. |
674 // This is done for the following instructions: mov, cmp, inc, dec, | 674 // This is done for the following instructions: mov, cmp, inc, dec, |
675 // add, sub, and test. | 675 // add, sub, and test. |
676 // There are no versions of these instructions without the suffix. | 676 // There are no versions of these instructions without the suffix. |
677 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. | 677 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. |
678 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. | 678 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. |
679 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. | 679 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. |
680 // - Instructions on 64-bit (quadword) operands/registers use 'q'. | 680 // - Instructions on 64-bit (quadword) operands/registers use 'q'. |
681 // - Instructions on operands/registers with pointer size use 'p'. | 681 // - Instructions on operands/registers with pointer size use 'p'. |
682 | 682 |
| 683 STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); |
| 684 |
683 #define DECLARE_INSTRUCTION(instruction) \ | 685 #define DECLARE_INSTRUCTION(instruction) \ |
684 template<class P1> \ | 686 template<class P1> \ |
685 void instruction##p(P1 p1) { \ | 687 void instruction##p(P1 p1) { \ |
686 emit_##instruction(p1, kPointerSize); \ | 688 emit_##instruction(p1, kPointerSize); \ |
687 } \ | 689 } \ |
688 \ | 690 \ |
689 template<class P1> \ | 691 template<class P1> \ |
690 void instruction##l(P1 p1) { \ | 692 void instruction##l(P1 p1) { \ |
691 emit_##instruction(p1, kInt32Size); \ | 693 emit_##instruction(p1, kInt32Size); \ |
692 } \ | 694 } \ |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 void cmovl(Condition cc, Register dst, Register src); | 801 void cmovl(Condition cc, Register dst, Register src); |
800 void cmovl(Condition cc, Register dst, const Operand& src); | 802 void cmovl(Condition cc, Register dst, const Operand& src); |
801 | 803 |
802 void cmpb(Register dst, Immediate src) { | 804 void cmpb(Register dst, Immediate src) { |
803 immediate_arithmetic_op_8(0x7, dst, src); | 805 immediate_arithmetic_op_8(0x7, dst, src); |
804 } | 806 } |
805 | 807 |
806 void cmpb_al(Immediate src); | 808 void cmpb_al(Immediate src); |
807 | 809 |
808 void cmpb(Register dst, Register src) { | 810 void cmpb(Register dst, Register src) { |
809 arithmetic_op(0x3A, dst, src); | 811 arithmetic_op_8(0x3A, dst, src); |
810 } | 812 } |
811 | 813 |
812 void cmpb(Register dst, const Operand& src) { | 814 void cmpb(Register dst, const Operand& src) { |
813 arithmetic_op(0x3A, dst, src); | 815 arithmetic_op_8(0x3A, dst, src); |
814 } | 816 } |
815 | 817 |
816 void cmpb(const Operand& dst, Register src) { | 818 void cmpb(const Operand& dst, Register src) { |
817 arithmetic_op(0x38, src, dst); | 819 arithmetic_op_8(0x38, src, dst); |
818 } | 820 } |
819 | 821 |
820 void cmpb(const Operand& dst, Immediate src) { | 822 void cmpb(const Operand& dst, Immediate src) { |
821 immediate_arithmetic_op_8(0x7, dst, src); | 823 immediate_arithmetic_op_8(0x7, dst, src); |
822 } | 824 } |
823 | 825 |
824 void cmpw(const Operand& dst, Immediate src) { | 826 void cmpw(const Operand& dst, Immediate src) { |
825 immediate_arithmetic_op_16(0x7, dst, src); | 827 immediate_arithmetic_op_16(0x7, dst, src); |
826 } | 828 } |
827 | 829 |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 // The first argument is the reg field, the second argument is the r/m field. | 1420 // The first argument is the reg field, the second argument is the r/m field. |
1419 void emit_sse_operand(XMMRegister dst, XMMRegister src); | 1421 void emit_sse_operand(XMMRegister dst, XMMRegister src); |
1420 void emit_sse_operand(XMMRegister reg, const Operand& adr); | 1422 void emit_sse_operand(XMMRegister reg, const Operand& adr); |
1421 void emit_sse_operand(XMMRegister dst, Register src); | 1423 void emit_sse_operand(XMMRegister dst, Register src); |
1422 void emit_sse_operand(Register dst, XMMRegister src); | 1424 void emit_sse_operand(Register dst, XMMRegister src); |
1423 | 1425 |
1424 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, | 1426 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, |
1425 // AND, OR, XOR, or CMP. The encodings of these operations are all | 1427 // AND, OR, XOR, or CMP. The encodings of these operations are all |
1426 // similar, differing just in the opcode or in the reg field of the | 1428 // similar, differing just in the opcode or in the reg field of the |
1427 // ModR/M byte. | 1429 // ModR/M byte. |
| 1430 void arithmetic_op_8(byte opcode, Register reg, Register rm_reg); |
| 1431 void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg); |
1428 void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); | 1432 void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); |
1429 void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); | 1433 void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); |
1430 void arithmetic_op_32(byte opcode, Register reg, Register rm_reg); | 1434 // Operate on operands/registers with pointer size, 32-bit or 64-bit size. |
1431 void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg); | 1435 void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size); |
1432 void arithmetic_op(byte opcode, Register reg, Register rm_reg); | 1436 void arithmetic_op(byte opcode, |
1433 void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg); | 1437 Register reg, |
1434 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); | 1438 const Operand& rm_reg, |
1435 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); | 1439 int size); |
1436 // Operate on a byte in memory or register. | 1440 // Operate on a byte in memory or register. |
1437 void immediate_arithmetic_op_8(byte subcode, | 1441 void immediate_arithmetic_op_8(byte subcode, |
1438 Register dst, | 1442 Register dst, |
1439 Immediate src); | 1443 Immediate src); |
1440 void immediate_arithmetic_op_8(byte subcode, | 1444 void immediate_arithmetic_op_8(byte subcode, |
1441 const Operand& dst, | 1445 const Operand& dst, |
1442 Immediate src); | 1446 Immediate src); |
1443 // Operate on a word in memory or register. | 1447 // Operate on a word in memory or register. |
1444 void immediate_arithmetic_op_16(byte subcode, | 1448 void immediate_arithmetic_op_16(byte subcode, |
1445 Register dst, | 1449 Register dst, |
1446 Immediate src); | 1450 Immediate src); |
1447 void immediate_arithmetic_op_16(byte subcode, | 1451 void immediate_arithmetic_op_16(byte subcode, |
1448 const Operand& dst, | 1452 const Operand& dst, |
1449 Immediate src); | 1453 Immediate src); |
1450 // Operate on a 32-bit word in memory or register. | 1454 // Operate on operands/registers with pointer size, 32-bit or 64-bit size. |
1451 void immediate_arithmetic_op_32(byte subcode, | 1455 void immediate_arithmetic_op(byte subcode, |
1452 Register dst, | 1456 Register dst, |
1453 Immediate src); | 1457 Immediate src, |
1454 void immediate_arithmetic_op_32(byte subcode, | 1458 int size); |
1455 const Operand& dst, | 1459 void immediate_arithmetic_op(byte subcode, |
1456 Immediate src); | 1460 const Operand& dst, |
| 1461 Immediate src, |
| 1462 int size); |
1457 | 1463 |
1458 // Emit machine code for a shift operation. | 1464 // Emit machine code for a shift operation. |
1459 void shift(Register dst, Immediate shift_amount, int subcode); | 1465 void shift(Register dst, Immediate shift_amount, int subcode); |
1460 void shift_32(Register dst, Immediate shift_amount, int subcode); | 1466 void shift_32(Register dst, Immediate shift_amount, int subcode); |
1461 // Shift dst by cl % 64 bits. | 1467 // Shift dst by cl % 64 bits. |
1462 void shift(Register dst, int subcode); | 1468 void shift(Register dst, int subcode); |
1463 void shift_32(Register dst, int subcode); | 1469 void shift_32(Register dst, int subcode); |
1464 | 1470 |
1465 void emit_farith(int b1, int b2, int i); | 1471 void emit_farith(int b1, int b2, int i); |
1466 | 1472 |
1467 // labels | 1473 // labels |
1468 // void print(Label* L); | 1474 // void print(Label* L); |
1469 void bind_to(Label* L, int pos); | 1475 void bind_to(Label* L, int pos); |
1470 | 1476 |
1471 // record reloc info for current pc_ | 1477 // record reloc info for current pc_ |
1472 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1478 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1473 | 1479 |
1474 // Arithmetics | 1480 // Arithmetics |
1475 void emit_add(Register dst, Register src, int size) { | 1481 void emit_add(Register dst, Register src, int size) { |
1476 if (size == kInt64Size) { | 1482 arithmetic_op(0x03, dst, src, size); |
1477 arithmetic_op(0x03, dst, src); | |
1478 } else { | |
1479 ASSERT(size == kInt32Size); | |
1480 arithmetic_op_32(0x03, dst, src); | |
1481 } | |
1482 } | 1483 } |
1483 | 1484 |
1484 void emit_add(Register dst, Immediate src, int size) { | 1485 void emit_add(Register dst, Immediate src, int size) { |
1485 if (size == kInt64Size) { | 1486 immediate_arithmetic_op(0x0, dst, src, size); |
1486 immediate_arithmetic_op(0x0, dst, src); | |
1487 } else { | |
1488 ASSERT(size == kInt32Size); | |
1489 immediate_arithmetic_op_32(0x0, dst, src); | |
1490 } | |
1491 } | 1487 } |
1492 | 1488 |
1493 void emit_add(Register dst, const Operand& src, int size) { | 1489 void emit_add(Register dst, const Operand& src, int size) { |
1494 if (size == kInt64Size) { | 1490 arithmetic_op(0x03, dst, src, size); |
1495 arithmetic_op(0x03, dst, src); | |
1496 } else { | |
1497 ASSERT(size == kInt32Size); | |
1498 arithmetic_op_32(0x03, dst, src); | |
1499 } | |
1500 } | 1491 } |
1501 | 1492 |
1502 void emit_add(const Operand& dst, Register src, int size) { | 1493 void emit_add(const Operand& dst, Register src, int size) { |
1503 if (size == kInt64Size) { | 1494 arithmetic_op(0x1, src, dst, size); |
1504 arithmetic_op(0x1, src, dst); | |
1505 } else { | |
1506 ASSERT(size == kInt32Size); | |
1507 arithmetic_op_32(0x1, src, dst); | |
1508 } | |
1509 } | 1495 } |
1510 | 1496 |
1511 void emit_add(const Operand& dst, Immediate src, int size) { | 1497 void emit_add(const Operand& dst, Immediate src, int size) { |
1512 if (size == kInt64Size) { | 1498 immediate_arithmetic_op(0x0, dst, src, size); |
1513 immediate_arithmetic_op(0x0, dst, src); | |
1514 } else { | |
1515 ASSERT(size == kInt32Size); | |
1516 immediate_arithmetic_op_32(0x0, dst, src); | |
1517 } | |
1518 } | 1499 } |
1519 | 1500 |
1520 void emit_and(Register dst, Register src, int size) { | 1501 void emit_and(Register dst, Register src, int size) { |
1521 if (size == kInt64Size) { | 1502 arithmetic_op(0x23, dst, src, size); |
1522 arithmetic_op(0x23, dst, src); | |
1523 } else { | |
1524 ASSERT(size == kInt32Size); | |
1525 arithmetic_op_32(0x23, dst, src); | |
1526 } | |
1527 } | 1503 } |
1528 | 1504 |
1529 void emit_and(Register dst, const Operand& src, int size) { | 1505 void emit_and(Register dst, const Operand& src, int size) { |
1530 if (size == kInt64Size) { | 1506 arithmetic_op(0x23, dst, src, size); |
1531 arithmetic_op(0x23, dst, src); | |
1532 } else { | |
1533 ASSERT(size == kInt32Size); | |
1534 arithmetic_op_32(0x23, dst, src); | |
1535 } | |
1536 } | 1507 } |
1537 | 1508 |
1538 void emit_and(const Operand& dst, Register src, int size) { | 1509 void emit_and(const Operand& dst, Register src, int size) { |
1539 if (size == kInt64Size) { | 1510 arithmetic_op(0x21, src, dst, size); |
1540 arithmetic_op(0x21, src, dst); | |
1541 } else { | |
1542 ASSERT(size == kInt32Size); | |
1543 arithmetic_op_32(0x21, src, dst); | |
1544 } | |
1545 } | 1511 } |
1546 | 1512 |
1547 void emit_and(Register dst, Immediate src, int size) { | 1513 void emit_and(Register dst, Immediate src, int size) { |
1548 if (size == kInt64Size) { | 1514 immediate_arithmetic_op(0x4, dst, src, size); |
1549 immediate_arithmetic_op(0x4, dst, src); | |
1550 } else { | |
1551 ASSERT(size == kInt32Size); | |
1552 immediate_arithmetic_op_32(0x4, dst, src); | |
1553 } | |
1554 } | 1515 } |
1555 | 1516 |
1556 void emit_and(const Operand& dst, Immediate src, int size) { | 1517 void emit_and(const Operand& dst, Immediate src, int size) { |
1557 if (size == kInt64Size) { | 1518 immediate_arithmetic_op(0x4, dst, src, size); |
1558 immediate_arithmetic_op(0x4, dst, src); | |
1559 } else { | |
1560 ASSERT(size == kInt32Size); | |
1561 immediate_arithmetic_op_32(0x4, dst, src); | |
1562 } | |
1563 } | 1519 } |
1564 | 1520 |
1565 void emit_cmp(Register dst, Register src, int size) { | 1521 void emit_cmp(Register dst, Register src, int size) { |
1566 if (size == kInt64Size) { | 1522 arithmetic_op(0x3B, dst, src, size); |
1567 arithmetic_op(0x3B, dst, src); | |
1568 } else { | |
1569 ASSERT(size == kInt32Size); | |
1570 arithmetic_op_32(0x3B, dst, src); | |
1571 } | |
1572 } | 1523 } |
1573 | 1524 |
1574 void emit_cmp(Register dst, const Operand& src, int size) { | 1525 void emit_cmp(Register dst, const Operand& src, int size) { |
1575 if (size == kInt64Size) { | 1526 arithmetic_op(0x3B, dst, src, size); |
1576 arithmetic_op(0x3B, dst, src); | |
1577 } else { | |
1578 ASSERT(size == kInt32Size); | |
1579 arithmetic_op_32(0x3B, dst, src); | |
1580 } | |
1581 } | 1527 } |
1582 | 1528 |
1583 void emit_cmp(const Operand& dst, Register src, int size) { | 1529 void emit_cmp(const Operand& dst, Register src, int size) { |
1584 if (size == kInt64Size) { | 1530 arithmetic_op(0x39, src, dst, size); |
1585 arithmetic_op(0x39, src, dst); | |
1586 } else { | |
1587 ASSERT(size == kInt32Size); | |
1588 arithmetic_op_32(0x39, src, dst); | |
1589 } | |
1590 } | 1531 } |
1591 | 1532 |
1592 void emit_cmp(Register dst, Immediate src, int size) { | 1533 void emit_cmp(Register dst, Immediate src, int size) { |
1593 if (size == kInt64Size) { | 1534 immediate_arithmetic_op(0x7, dst, src, size); |
1594 immediate_arithmetic_op(0x7, dst, src); | |
1595 } else { | |
1596 ASSERT(size == kInt32Size); | |
1597 immediate_arithmetic_op_32(0x7, dst, src); | |
1598 } | |
1599 } | 1535 } |
1600 | 1536 |
1601 void emit_cmp(const Operand& dst, Immediate src, int size) { | 1537 void emit_cmp(const Operand& dst, Immediate src, int size) { |
1602 if (size == kInt64Size) { | 1538 immediate_arithmetic_op(0x7, dst, src, size); |
1603 immediate_arithmetic_op(0x7, dst, src); | |
1604 } else { | |
1605 ASSERT(size == kInt32Size); | |
1606 immediate_arithmetic_op_32(0x7, dst, src); | |
1607 } | |
1608 } | 1539 } |
1609 | 1540 |
1610 void emit_dec(Register dst, int size); | 1541 void emit_dec(Register dst, int size); |
1611 void emit_dec(const Operand& dst, int size); | 1542 void emit_dec(const Operand& dst, int size); |
1612 | 1543 |
1613 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. | 1544 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. |
1614 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx | 1545 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx |
1615 // when size is 32. | 1546 // when size is 32. |
1616 void emit_idiv(Register src, int size); | 1547 void emit_idiv(Register src, int size); |
1617 | 1548 |
(...skipping 19 matching lines...) Expand all Loading... |
1637 void emit_movzxw(Register dst, const Operand& src, int size); | 1568 void emit_movzxw(Register dst, const Operand& src, int size); |
1638 void emit_movzxw(Register dst, Register src, int size); | 1569 void emit_movzxw(Register dst, Register src, int size); |
1639 | 1570 |
1640 void emit_neg(Register dst, int size); | 1571 void emit_neg(Register dst, int size); |
1641 void emit_neg(const Operand& dst, int size); | 1572 void emit_neg(const Operand& dst, int size); |
1642 | 1573 |
1643 void emit_not(Register dst, int size); | 1574 void emit_not(Register dst, int size); |
1644 void emit_not(const Operand& dst, int size); | 1575 void emit_not(const Operand& dst, int size); |
1645 | 1576 |
1646 void emit_or(Register dst, Register src, int size) { | 1577 void emit_or(Register dst, Register src, int size) { |
1647 if (size == kInt64Size) { | 1578 arithmetic_op(0x0B, dst, src, size); |
1648 arithmetic_op(0x0B, dst, src); | |
1649 } else { | |
1650 arithmetic_op_32(0x0B, dst, src); | |
1651 } | |
1652 } | 1579 } |
1653 | 1580 |
1654 void emit_or(Register dst, const Operand& src, int size) { | 1581 void emit_or(Register dst, const Operand& src, int size) { |
1655 if (size == kInt64Size) { | 1582 arithmetic_op(0x0B, dst, src, size); |
1656 arithmetic_op(0x0B, dst, src); | |
1657 } else { | |
1658 arithmetic_op_32(0x0B, dst, src); | |
1659 } | |
1660 } | 1583 } |
1661 | 1584 |
1662 void emit_or(const Operand& dst, Register src, int size) { | 1585 void emit_or(const Operand& dst, Register src, int size) { |
1663 if (size == kInt64Size) { | 1586 arithmetic_op(0x9, src, dst, size); |
1664 arithmetic_op(0x9, src, dst); | |
1665 } else { | |
1666 arithmetic_op_32(0x9, src, dst); | |
1667 } | |
1668 } | 1587 } |
1669 | 1588 |
1670 void emit_or(Register dst, Immediate src, int size) { | 1589 void emit_or(Register dst, Immediate src, int size) { |
1671 if (size == kInt64Size) { | 1590 immediate_arithmetic_op(0x1, dst, src, size); |
1672 immediate_arithmetic_op(0x1, dst, src); | |
1673 } else { | |
1674 immediate_arithmetic_op_32(0x1, dst, src); | |
1675 } | |
1676 } | 1591 } |
1677 | 1592 |
1678 void emit_or(const Operand& dst, Immediate src, int size) { | 1593 void emit_or(const Operand& dst, Immediate src, int size) { |
1679 if (size == kInt64Size) { | 1594 immediate_arithmetic_op(0x1, dst, src, size); |
1680 immediate_arithmetic_op(0x1, dst, src); | |
1681 } else { | |
1682 immediate_arithmetic_op_32(0x1, dst, src); | |
1683 } | |
1684 } | 1595 } |
1685 | 1596 |
1686 void emit_repmovs(int size); | 1597 void emit_repmovs(int size); |
1687 | 1598 |
1688 void emit_sbb(Register dst, Register src, int size) { | 1599 void emit_sbb(Register dst, Register src, int size) { |
1689 if (size == kInt64Size) { | 1600 arithmetic_op(0x1b, dst, src, size); |
1690 arithmetic_op(0x1b, dst, src); | |
1691 } else { | |
1692 ASSERT(size == kInt32Size); | |
1693 arithmetic_op_32(0x1b, dst, src); | |
1694 } | |
1695 } | 1601 } |
1696 | 1602 |
1697 void emit_sub(Register dst, Register src, int size) { | 1603 void emit_sub(Register dst, Register src, int size) { |
1698 if (size == kInt64Size) { | 1604 arithmetic_op(0x2B, dst, src, size); |
1699 arithmetic_op(0x2B, dst, src); | |
1700 } else { | |
1701 ASSERT(size == kInt32Size); | |
1702 arithmetic_op_32(0x2B, dst, src); | |
1703 } | |
1704 } | 1605 } |
1705 | 1606 |
1706 void emit_sub(Register dst, Immediate src, int size) { | 1607 void emit_sub(Register dst, Immediate src, int size) { |
1707 if (size == kInt64Size) { | 1608 immediate_arithmetic_op(0x5, dst, src, size); |
1708 immediate_arithmetic_op(0x5, dst, src); | |
1709 } else { | |
1710 ASSERT(size == kInt32Size); | |
1711 immediate_arithmetic_op_32(0x5, dst, src); | |
1712 } | |
1713 } | 1609 } |
1714 | 1610 |
1715 void emit_sub(Register dst, const Operand& src, int size) { | 1611 void emit_sub(Register dst, const Operand& src, int size) { |
1716 if (size == kInt64Size) { | 1612 arithmetic_op(0x2B, dst, src, size); |
1717 arithmetic_op(0x2B, dst, src); | |
1718 } else { | |
1719 ASSERT(size == kInt32Size); | |
1720 arithmetic_op_32(0x2B, dst, src); | |
1721 } | |
1722 } | 1613 } |
1723 | 1614 |
1724 void emit_sub(const Operand& dst, Register src, int size) { | 1615 void emit_sub(const Operand& dst, Register src, int size) { |
1725 if (size == kInt64Size) { | 1616 arithmetic_op(0x29, src, dst, size); |
1726 arithmetic_op(0x29, src, dst); | |
1727 } else { | |
1728 ASSERT(size == kInt32Size); | |
1729 arithmetic_op_32(0x29, src, dst); | |
1730 } | |
1731 } | 1617 } |
1732 | 1618 |
1733 void emit_sub(const Operand& dst, Immediate src, int size) { | 1619 void emit_sub(const Operand& dst, Immediate src, int size) { |
1734 if (size == kInt64Size) { | 1620 immediate_arithmetic_op(0x5, dst, src, size); |
1735 immediate_arithmetic_op(0x5, dst, src); | |
1736 } else { | |
1737 ASSERT(size == kInt32Size); | |
1738 immediate_arithmetic_op_32(0x5, dst, src); | |
1739 } | |
1740 } | 1621 } |
1741 | 1622 |
1742 void emit_test(Register dst, Register src, int size); | 1623 void emit_test(Register dst, Register src, int size); |
1743 void emit_test(Register reg, Immediate mask, int size); | 1624 void emit_test(Register reg, Immediate mask, int size); |
1744 void emit_test(const Operand& op, Register reg, int size); | 1625 void emit_test(const Operand& op, Register reg, int size); |
1745 void emit_test(const Operand& op, Immediate mask, int size); | 1626 void emit_test(const Operand& op, Immediate mask, int size); |
1746 | 1627 |
1747 // Exchange two registers | 1628 // Exchange two registers |
1748 void emit_xchg(Register dst, Register src, int size); | 1629 void emit_xchg(Register dst, Register src, int size); |
1749 | 1630 |
1750 void emit_xor(Register dst, Register src, int size) { | 1631 void emit_xor(Register dst, Register src, int size) { |
1751 if (size == kInt64Size) { | 1632 if (size == kInt64Size && dst.code() == src.code()) { |
1752 if (dst.code() == src.code()) { | 1633 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore |
1753 arithmetic_op_32(0x33, dst, src); | 1634 // there is no need to make this a 64 bit operation. |
1754 } else { | 1635 arithmetic_op(0x33, dst, src, kInt32Size); |
1755 arithmetic_op(0x33, dst, src); | |
1756 } | |
1757 } else { | 1636 } else { |
1758 ASSERT(size == kInt32Size); | 1637 arithmetic_op(0x33, dst, src, size); |
1759 arithmetic_op_32(0x33, dst, src); | |
1760 } | 1638 } |
1761 } | 1639 } |
1762 | 1640 |
1763 void emit_xor(Register dst, const Operand& src, int size) { | 1641 void emit_xor(Register dst, const Operand& src, int size) { |
1764 if (size == kInt64Size) { | 1642 arithmetic_op(0x33, dst, src, size); |
1765 arithmetic_op(0x33, dst, src); | |
1766 } else { | |
1767 ASSERT(size == kInt32Size); | |
1768 arithmetic_op_32(0x33, dst, src); | |
1769 } | |
1770 } | 1643 } |
1771 | 1644 |
1772 void emit_xor(Register dst, Immediate src, int size) { | 1645 void emit_xor(Register dst, Immediate src, int size) { |
1773 if (size == kInt64Size) { | 1646 immediate_arithmetic_op(0x6, dst, src, size); |
1774 immediate_arithmetic_op(0x6, dst, src); | |
1775 } else { | |
1776 ASSERT(size == kInt32Size); | |
1777 immediate_arithmetic_op_32(0x6, dst, src); | |
1778 } | |
1779 } | 1647 } |
1780 | 1648 |
1781 void emit_xor(const Operand& dst, Immediate src, int size) { | 1649 void emit_xor(const Operand& dst, Immediate src, int size) { |
1782 if (size == kInt64Size) { | 1650 immediate_arithmetic_op(0x6, dst, src, size); |
1783 immediate_arithmetic_op(0x6, dst, src); | |
1784 } else { | |
1785 ASSERT(size == kInt32Size); | |
1786 immediate_arithmetic_op_32(0x6, dst, src); | |
1787 } | |
1788 } | 1651 } |
1789 | 1652 |
1790 void emit_xor(const Operand& dst, Register src, int size) { | 1653 void emit_xor(const Operand& dst, Register src, int size) { |
1791 if (size == kInt64Size) { | 1654 arithmetic_op(0x31, src, dst, size); |
1792 arithmetic_op(0x31, src, dst); | |
1793 } else { | |
1794 ASSERT(size == kInt32Size); | |
1795 arithmetic_op_32(0x31, src, dst); | |
1796 } | |
1797 } | 1655 } |
1798 | 1656 |
1799 friend class CodePatcher; | 1657 friend class CodePatcher; |
1800 friend class EnsureSpace; | 1658 friend class EnsureSpace; |
1801 friend class RegExpMacroAssemblerX64; | 1659 friend class RegExpMacroAssemblerX64; |
1802 | 1660 |
1803 // code generation | 1661 // code generation |
1804 RelocInfoWriter reloc_info_writer; | 1662 RelocInfoWriter reloc_info_writer; |
1805 | 1663 |
1806 List< Handle<Code> > code_targets_; | 1664 List< Handle<Code> > code_targets_; |
(...skipping 26 matching lines...) Expand all Loading... |
1833 private: | 1691 private: |
1834 Assembler* assembler_; | 1692 Assembler* assembler_; |
1835 #ifdef DEBUG | 1693 #ifdef DEBUG |
1836 int space_before_; | 1694 int space_before_; |
1837 #endif | 1695 #endif |
1838 }; | 1696 }; |
1839 | 1697 |
1840 } } // namespace v8::internal | 1698 } } // namespace v8::internal |
1841 | 1699 |
1842 #endif // V8_X64_ASSEMBLER_X64_H_ | 1700 #endif // V8_X64_ASSEMBLER_X64_H_ |
OLD | NEW |