OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <assert.h> | 5 #include <assert.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #if V8_TARGET_ARCH_X64 | 9 #if V8_TARGET_ARCH_X64 |
10 | 10 |
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 // These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix. | 1506 // These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix. |
1507 // We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A. | 1507 // We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A. |
1508 int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { | 1508 int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
1509 byte opcode = *(data + 1); | 1509 byte opcode = *(data + 1); |
1510 byte* current = data + 2; | 1510 byte* current = data + 2; |
1511 // At return, "current" points to the start of the next instruction. | 1511 // At return, "current" points to the start of the next instruction. |
1512 const char* mnemonic = TwoByteMnemonic(opcode); | 1512 const char* mnemonic = TwoByteMnemonic(opcode); |
1513 if (operand_size_ == 0x66) { | 1513 if (operand_size_ == 0x66) { |
1514 // 0x66 0x0F prefix. | 1514 // 0x66 0x0F prefix. |
1515 int mod, regop, rm; | 1515 int mod, regop, rm; |
1516 if (opcode == 0x3A) { | 1516 if (opcode == 0x38) { |
| 1517 byte third_byte = *current; |
| 1518 current = data + 3; |
| 1519 if (third_byte == 0x40) { |
| 1520 // pmulld xmm, xmm/m128 |
| 1521 get_modrm(*current, &mod, ®op, &rm); |
| 1522 AppendToBuffer("pmulld %s,", NameOfXMMRegister(regop)); |
| 1523 current += PrintRightXMMOperand(current); |
| 1524 } |
| 1525 } else if (opcode == 0x3A) { |
1517 byte third_byte = *current; | 1526 byte third_byte = *current; |
1518 current = data + 3; | 1527 current = data + 3; |
1519 if (third_byte == 0x17) { | 1528 if (third_byte == 0x17) { |
1520 get_modrm(*current, &mod, ®op, &rm); | 1529 get_modrm(*current, &mod, ®op, &rm); |
1521 AppendToBuffer("extractps "); // reg/m32, xmm, imm8 | 1530 AppendToBuffer("extractps "); // reg/m32, xmm, imm8 |
1522 current += PrintRightOperand(current); | 1531 current += PrintRightOperand(current); |
1523 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); | 1532 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
1524 current += 1; | 1533 current += 1; |
1525 } else if (third_byte == 0x0a) { | 1534 } else if (third_byte == 0x0a) { |
1526 get_modrm(*current, &mod, ®op, &rm); | 1535 get_modrm(*current, &mod, ®op, &rm); |
1527 AppendToBuffer("roundss %s,", NameOfXMMRegister(regop)); | 1536 AppendToBuffer("roundss %s,", NameOfXMMRegister(regop)); |
1528 current += PrintRightXMMOperand(current); | 1537 current += PrintRightXMMOperand(current); |
1529 AppendToBuffer(",0x%x", (*current) & 3); | 1538 AppendToBuffer(",0x%x", (*current) & 3); |
1530 current += 1; | 1539 current += 1; |
1531 } else if (third_byte == 0x0b) { | 1540 } else if (third_byte == 0x0b) { |
1532 get_modrm(*current, &mod, ®op, &rm); | 1541 get_modrm(*current, &mod, ®op, &rm); |
1533 // roundsd xmm, xmm/m64, imm8 | 1542 // roundsd xmm, xmm/m64, imm8 |
1534 AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop)); | 1543 AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop)); |
1535 current += PrintRightXMMOperand(current); | 1544 current += PrintRightXMMOperand(current); |
1536 AppendToBuffer(",0x%x", (*current) & 3); | 1545 AppendToBuffer(",0x%x", (*current) & 3); |
1537 current += 1; | 1546 current += 1; |
1538 } else if (third_byte == 0x16) { | 1547 } else if (third_byte == 0x16) { |
1539 get_modrm(*current, &mod, &rm, ®op); | 1548 get_modrm(*current, &mod, ®op, &rm); |
1540 AppendToBuffer("pextrd "); // reg/m32, xmm, imm8 | 1549 AppendToBuffer("pextrd "); // reg/m32, xmm, imm8 |
1541 current += PrintRightOperand(current); | 1550 current += PrintRightOperand(current); |
1542 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); | 1551 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
1543 current += 1; | 1552 current += 1; |
| 1553 } else if (third_byte == 0x21) { |
| 1554 get_modrm(*current, &mod, ®op, &rm); |
| 1555 // insertps xmm, xmm/m32, imm8 |
| 1556 AppendToBuffer("insertps %s,", NameOfXMMRegister(regop)); |
| 1557 current += PrintRightXMMOperand(current); |
| 1558 AppendToBuffer(",0x%x", (*current) & 3); |
| 1559 current += 1; |
1544 } else if (third_byte == 0x22) { | 1560 } else if (third_byte == 0x22) { |
1545 get_modrm(*current, &mod, ®op, &rm); | 1561 get_modrm(*current, &mod, ®op, &rm); |
1546 AppendToBuffer("pinsrd "); // xmm, reg/m32, imm8 | 1562 AppendToBuffer("pinsrd "); // xmm, reg/m32, imm8 |
1547 AppendToBuffer(" %s,", NameOfXMMRegister(regop)); | 1563 AppendToBuffer(" %s,", NameOfXMMRegister(regop)); |
1548 current += PrintRightOperand(current); | 1564 current += PrintRightOperand(current); |
1549 AppendToBuffer(",%d", (*current) & 3); | 1565 AppendToBuffer(",%d", (*current) & 3); |
1550 current += 1; | 1566 current += 1; |
1551 } else { | 1567 } else { |
1552 UnimplementedInstruction(); | 1568 UnimplementedInstruction(); |
1553 } | 1569 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 AppendToBuffer("movdqa "); | 1605 AppendToBuffer("movdqa "); |
1590 current += PrintRightXMMOperand(current); | 1606 current += PrintRightXMMOperand(current); |
1591 AppendToBuffer(",%s", NameOfXMMRegister(regop)); | 1607 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1592 } else if (opcode == 0xD6) { | 1608 } else if (opcode == 0xD6) { |
1593 AppendToBuffer("movq "); | 1609 AppendToBuffer("movq "); |
1594 current += PrintRightXMMOperand(current); | 1610 current += PrintRightXMMOperand(current); |
1595 AppendToBuffer(",%s", NameOfXMMRegister(regop)); | 1611 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1596 } else if (opcode == 0x50) { | 1612 } else if (opcode == 0x50) { |
1597 AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); | 1613 AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); |
1598 current += PrintRightXMMOperand(current); | 1614 current += PrintRightXMMOperand(current); |
| 1615 } else if (opcode == 0x70) { |
| 1616 AppendToBuffer("pshufd %s,", NameOfXMMRegister(regop)); |
| 1617 current += PrintRightXMMOperand(current); |
| 1618 AppendToBuffer(",0x%x", *current); |
| 1619 current += 1; |
1599 } else if (opcode == 0x72) { | 1620 } else if (opcode == 0x72) { |
1600 current += 1; | 1621 current += 1; |
1601 AppendToBuffer("%s %s,%d", (regop == 6) ? "pslld" : "psrld", | 1622 AppendToBuffer("%s %s,%d", (regop == 6) ? "pslld" : "psrld", |
1602 NameOfXMMRegister(rm), *current & 0x7f); | 1623 NameOfXMMRegister(rm), *current & 0x7f); |
1603 current += 1; | 1624 current += 1; |
1604 } else if (opcode == 0x73) { | 1625 } else if (opcode == 0x73) { |
1605 current += 1; | 1626 current += 1; |
1606 AppendToBuffer("%s %s,%d", (regop == 6) ? "psllq" : "psrlq", | 1627 AppendToBuffer("%s %s,%d", (regop == 6) ? "psllq" : "psrlq", |
1607 NameOfXMMRegister(rm), *current & 0x7f); | 1628 NameOfXMMRegister(rm), *current & 0x7f); |
1608 current += 1; | 1629 current += 1; |
1609 } else if (opcode == 0xB1) { | 1630 } else if (opcode == 0xB1) { |
1610 current += PrintOperands("cmpxchg", OPER_REG_OP_ORDER, current); | 1631 current += PrintOperands("cmpxchg", OPER_REG_OP_ORDER, current); |
1611 } else { | 1632 } else { |
1612 const char* mnemonic = "?"; | 1633 const char* mnemonic = "?"; |
1613 if (opcode == 0x54) { | 1634 if (opcode == 0x54) { |
1614 mnemonic = "andpd"; | 1635 mnemonic = "andpd"; |
1615 } else if (opcode == 0x56) { | 1636 } else if (opcode == 0x56) { |
1616 mnemonic = "orpd"; | 1637 mnemonic = "orpd"; |
1617 } else if (opcode == 0x57) { | 1638 } else if (opcode == 0x57) { |
1618 mnemonic = "xorpd"; | 1639 mnemonic = "xorpd"; |
| 1640 } else if (opcode == 0x5B) { |
| 1641 mnemonic = "cvtps2dq"; |
1619 } else if (opcode == 0x2E) { | 1642 } else if (opcode == 0x2E) { |
1620 mnemonic = "ucomisd"; | 1643 mnemonic = "ucomisd"; |
1621 } else if (opcode == 0x2F) { | 1644 } else if (opcode == 0x2F) { |
1622 mnemonic = "comisd"; | 1645 mnemonic = "comisd"; |
1623 } else if (opcode == 0x76) { | 1646 } else if (opcode == 0x76) { |
1624 mnemonic = "pcmpeqd"; | 1647 mnemonic = "pcmpeqd"; |
1625 } else if (opcode == 0x62) { | 1648 } else if (opcode == 0x62) { |
1626 mnemonic = "punpckldq"; | 1649 mnemonic = "punpckldq"; |
1627 } else if (opcode == 0x6A) { | 1650 } else if (opcode == 0x6A) { |
1628 mnemonic = "punpckhdq"; | 1651 mnemonic = "punpckhdq"; |
| 1652 } else if (opcode == 0xF4) { |
| 1653 mnemonic = "pmuludq"; |
| 1654 } else if (opcode == 0xFA) { |
| 1655 mnemonic = "psubd"; |
| 1656 } else if (opcode == 0xFE) { |
| 1657 mnemonic = "paddd"; |
1629 } else { | 1658 } else { |
1630 UnimplementedInstruction(); | 1659 UnimplementedInstruction(); |
1631 } | 1660 } |
1632 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); | 1661 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
1633 current += PrintRightXMMOperand(current); | 1662 current += PrintRightXMMOperand(current); |
1634 } | 1663 } |
1635 } | 1664 } |
1636 } else if (group_1_prefix_ == 0xF2) { | 1665 } else if (group_1_prefix_ == 0xF2) { |
1637 // Beginning of instructions with prefix 0xF2. | 1666 // Beginning of instructions with prefix 0xF2. |
1638 | 1667 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 get_modrm(*current, &mod, ®op, &rm); | 1789 get_modrm(*current, &mod, ®op, &rm); |
1761 const char* const pseudo_op[] = {"cmpeqss", "cmpltss", "cmpless", | 1790 const char* const pseudo_op[] = {"cmpeqss", "cmpltss", "cmpless", |
1762 "cmpunordss", "cmpneqss", "cmpnltss", | 1791 "cmpunordss", "cmpneqss", "cmpnltss", |
1763 "cmpnless", "cmpordss"}; | 1792 "cmpnless", "cmpordss"}; |
1764 AppendToBuffer("%s %s,%s", pseudo_op[current[1]], | 1793 AppendToBuffer("%s %s,%s", pseudo_op[current[1]], |
1765 NameOfXMMRegister(regop), NameOfXMMRegister(rm)); | 1794 NameOfXMMRegister(regop), NameOfXMMRegister(rm)); |
1766 current += 2; | 1795 current += 2; |
1767 } else { | 1796 } else { |
1768 UnimplementedInstruction(); | 1797 UnimplementedInstruction(); |
1769 } | 1798 } |
| 1799 } else if (opcode == 0x10 || opcode == 0x11) { |
| 1800 // movups xmm, xmm/m128 |
| 1801 // movups xmm/m128, xmm |
| 1802 int mod, regop, rm; |
| 1803 get_modrm(*current, &mod, ®op, &rm); |
| 1804 AppendToBuffer("movups "); |
| 1805 if (opcode == 0x11) { |
| 1806 current += PrintRightXMMOperand(current); |
| 1807 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
| 1808 } else { |
| 1809 AppendToBuffer("%s,", NameOfXMMRegister(regop)); |
| 1810 current += PrintRightXMMOperand(current); |
| 1811 } |
1770 } else if (opcode == 0x1F) { | 1812 } else if (opcode == 0x1F) { |
1771 // NOP | 1813 // NOP |
1772 int mod, regop, rm; | 1814 int mod, regop, rm; |
1773 get_modrm(*current, &mod, ®op, &rm); | 1815 get_modrm(*current, &mod, ®op, &rm); |
1774 current++; | 1816 current++; |
1775 if (rm == 4) { // SIB byte present. | 1817 if (rm == 4) { // SIB byte present. |
1776 current++; | 1818 current++; |
1777 } | 1819 } |
1778 if (mod == 1) { // Byte displacement. | 1820 if (mod == 1) { // Byte displacement. |
1779 current += 1; | 1821 current += 1; |
(...skipping 26 matching lines...) Expand all Loading... |
1806 // CPUID | 1848 // CPUID |
1807 AppendToBuffer("%s", mnemonic); | 1849 AppendToBuffer("%s", mnemonic); |
1808 | 1850 |
1809 } else if ((opcode & 0xF0) == 0x40) { | 1851 } else if ((opcode & 0xF0) == 0x40) { |
1810 // CMOVcc: conditional move. | 1852 // CMOVcc: conditional move. |
1811 int condition = opcode & 0x0F; | 1853 int condition = opcode & 0x0F; |
1812 const InstructionDesc& idesc = cmov_instructions[condition]; | 1854 const InstructionDesc& idesc = cmov_instructions[condition]; |
1813 byte_size_operand_ = idesc.byte_size_operation; | 1855 byte_size_operand_ = idesc.byte_size_operation; |
1814 current += PrintOperands(idesc.mnem, idesc.op_order_, current); | 1856 current += PrintOperands(idesc.mnem, idesc.op_order_, current); |
1815 | 1857 |
1816 } else if (opcode >= 0x53 && opcode <= 0x5F) { | 1858 } else if (opcode >= 0x51 && opcode <= 0x5F) { |
1817 const char* const pseudo_op[] = { | 1859 const char* const pseudo_op[] = { |
1818 "rcpps", | 1860 "sqrtps", "rsqrtps", "rcpps", "andps", "andnps", |
1819 "andps", | 1861 "orps", "xorps", "addps", "mulps", "cvtps2pd", |
1820 "andnps", | 1862 "cvtdq2ps", "subps", "minps", "divps", "maxps", |
1821 "orps", | |
1822 "xorps", | |
1823 "addps", | |
1824 "mulps", | |
1825 "cvtps2pd", | |
1826 "cvtdq2ps", | |
1827 "subps", | |
1828 "minps", | |
1829 "divps", | |
1830 "maxps", | |
1831 }; | 1863 }; |
1832 int mod, regop, rm; | 1864 int mod, regop, rm; |
1833 get_modrm(*current, &mod, ®op, &rm); | 1865 get_modrm(*current, &mod, ®op, &rm); |
1834 AppendToBuffer("%s %s,", | 1866 AppendToBuffer("%s %s,", pseudo_op[opcode - 0x51], |
1835 pseudo_op[opcode - 0x53], | |
1836 NameOfXMMRegister(regop)); | 1867 NameOfXMMRegister(regop)); |
1837 current += PrintRightXMMOperand(current); | 1868 current += PrintRightXMMOperand(current); |
1838 | 1869 |
| 1870 } else if (opcode == 0xC2) { |
| 1871 // cmpps xmm, xmm/m128, imm8 |
| 1872 int mod, regop, rm; |
| 1873 get_modrm(*current, &mod, ®op, &rm); |
| 1874 const char* const pseudo_op[] = {"cmpeqps", "cmpltps", "cmpleps", |
| 1875 "cmpunordps", "cmpneqps", "cmpnltps", |
| 1876 "cmpnleps", "cmpordps"}; |
| 1877 AppendToBuffer("%s %s,%s", pseudo_op[current[1]], NameOfXMMRegister(regop), |
| 1878 NameOfXMMRegister(rm)); |
| 1879 current += 2; |
1839 } else if (opcode == 0xC6) { | 1880 } else if (opcode == 0xC6) { |
1840 // shufps xmm, xmm/m128, imm8 | 1881 // shufps xmm, xmm/m128, imm8 |
1841 int mod, regop, rm; | 1882 int mod, regop, rm; |
1842 get_modrm(*current, &mod, ®op, &rm); | 1883 get_modrm(*current, &mod, ®op, &rm); |
1843 AppendToBuffer("shufps %s, ", NameOfXMMRegister(regop)); | 1884 AppendToBuffer("shufps %s, ", NameOfXMMRegister(regop)); |
1844 current += PrintRightXMMOperand(current); | 1885 current += PrintRightXMMOperand(current); |
1845 AppendToBuffer(", %d", (*current) & 3); | 1886 AppendToBuffer(", %d", (*current) & 3); |
1846 current += 1; | 1887 current += 1; |
1847 | |
1848 } else if (opcode == 0x50) { | 1888 } else if (opcode == 0x50) { |
1849 // movmskps reg, xmm | 1889 // movmskps reg, xmm |
1850 int mod, regop, rm; | 1890 int mod, regop, rm; |
1851 get_modrm(*current, &mod, ®op, &rm); | 1891 get_modrm(*current, &mod, ®op, &rm); |
1852 AppendToBuffer("movmskps %s,", NameOfCPURegister(regop)); | 1892 AppendToBuffer("movmskps %s,", NameOfCPURegister(regop)); |
1853 current += PrintRightXMMOperand(current); | 1893 current += PrintRightXMMOperand(current); |
1854 | 1894 |
1855 } else if ((opcode & 0xF0) == 0x80) { | 1895 } else if ((opcode & 0xF0) == 0x80) { |
1856 // Jcc: Conditional jump (branch). | 1896 // Jcc: Conditional jump (branch). |
1857 current = data + JumpConditional(data); | 1897 current = data + JumpConditional(data); |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2515 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { | 2555 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { |
2516 fprintf(f, " "); | 2556 fprintf(f, " "); |
2517 } | 2557 } |
2518 fprintf(f, " %s\n", buffer.start()); | 2558 fprintf(f, " %s\n", buffer.start()); |
2519 } | 2559 } |
2520 } | 2560 } |
2521 | 2561 |
2522 } // namespace disasm | 2562 } // namespace disasm |
2523 | 2563 |
2524 #endif // V8_TARGET_ARCH_X64 | 2564 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |