Revision 927f621e translate-i386.c
b/translate-i386.c | ||
---|---|---|
5 | 5 |
#include <inttypes.h> |
6 | 6 |
#include <assert.h> |
7 | 7 |
|
8 |
#define IN_OP_I386 |
|
8 | 9 |
#include "cpu-i386.h" |
9 | 10 |
|
10 | 11 |
static uint8_t *gen_code_ptr; |
... | ... | |
39 | 40 |
int prefix; |
40 | 41 |
int aflag, dflag; |
41 | 42 |
uint8_t *pc; /* current pc */ |
42 |
uint8_t *runtime_pc; /* current pc in the runtime generated code */ |
|
43 | 43 |
int cc_op; /* current CC operation */ |
44 | 44 |
int f_st; |
45 | 45 |
} DisasContext; |
... | ... | |
68 | 68 |
OP_SAR = 7, |
69 | 69 |
}; |
70 | 70 |
|
71 |
|
|
72 |
static const int fp_ops[8] = { |
|
73 |
#if 0 |
|
74 |
OP_FADDQ, OP_FMULQ, OP_CMP, OP_CMP, |
|
75 |
OP_FSUBQ, OP_FSUBQ, OP_FDIVQ, OP_FDIVQ |
|
76 |
#endif |
|
77 |
}; |
|
78 |
|
|
79 |
extern char cc_table, rclw_table, rclb_table; |
|
80 |
extern char helper_rcll_T0_T1_cc; |
|
81 |
extern char __udivdi3, __umoddi3; |
|
82 |
|
|
83 | 71 |
#include "op-i386.h" |
84 | 72 |
|
85 | 73 |
/* operand size */ |
... | ... | |
606 | 594 |
}, |
607 | 595 |
}; |
608 | 596 |
|
597 |
static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = { |
|
598 |
gen_op_fadd_ST0_FT0, |
|
599 |
gen_op_fmul_ST0_FT0, |
|
600 |
gen_op_fcom_ST0_FT0, |
|
601 |
gen_op_fcom_ST0_FT0, |
|
602 |
gen_op_fsub_ST0_FT0, |
|
603 |
gen_op_fsubr_ST0_FT0, |
|
604 |
gen_op_fdiv_ST0_FT0, |
|
605 |
gen_op_fdivr_ST0_FT0, |
|
606 |
}; |
|
607 |
|
|
608 |
static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = { |
|
609 |
gen_op_fadd_STN_ST0, |
|
610 |
gen_op_fmul_STN_ST0, |
|
611 |
NULL, |
|
612 |
NULL, |
|
613 |
gen_op_fsub_STN_ST0, |
|
614 |
gen_op_fsubr_STN_ST0, |
|
615 |
gen_op_fdiv_STN_ST0, |
|
616 |
gen_op_fdivr_STN_ST0, |
|
617 |
}; |
|
618 |
|
|
609 | 619 |
static void gen_op(DisasContext *s1, int op, int ot, int d, int s) |
610 | 620 |
{ |
611 | 621 |
if (d != OR_TMP0) |
... | ... | |
1345 | 1355 |
/**************************/ |
1346 | 1356 |
/* push/pop */ |
1347 | 1357 |
case 0x50 ... 0x57: /* push */ |
1348 |
gen_op_mov_TN_reg[OT_LONG][0][(b & 7)]();
|
|
1358 |
gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
|
|
1349 | 1359 |
gen_op_pushl_T0(); |
1350 | 1360 |
break; |
1351 | 1361 |
case 0x58 ... 0x5f: /* pop */ |
1352 | 1362 |
gen_op_popl_T0(); |
1353 |
gen_op_mov_reg_T0[OT_LONG][reg]();
|
|
1363 |
gen_op_mov_reg_T0[OT_LONG][b & 7]();
|
|
1354 | 1364 |
break; |
1355 | 1365 |
case 0x68: /* push Iv */ |
1356 | 1366 |
case 0x6a: |
... | ... | |
1581 | 1591 |
|
1582 | 1592 |
/************************/ |
1583 | 1593 |
/* floats */ |
1584 |
#if 0 |
|
1585 | 1594 |
case 0xd8 ... 0xdf: |
1586 | 1595 |
modrm = ldub(s->pc++); |
1587 | 1596 |
mod = (modrm >> 6) & 3; |
... | ... | |
1597 | 1606 |
case 0x20 ... 0x27: /* fxxxl */ |
1598 | 1607 |
case 0x30 ... 0x37: /* fixxx */ |
1599 | 1608 |
{ |
1600 |
int op1, swap; |
|
1601 |
op1 = fp_ops[op & 7]; |
|
1602 |
|
|
1603 |
swap = 0; |
|
1604 |
if ((op & 7) == 5 || (op & 7) == 7) |
|
1605 |
swap = 1; |
|
1609 |
int op1; |
|
1610 |
op1 = op & 7; |
|
1606 | 1611 |
|
1607 | 1612 |
switch(op >> 4) { |
1608 | 1613 |
case 0: |
1609 |
ot = OT_LONG; |
|
1610 |
is_int = 0; |
|
1614 |
gen_op_flds_FT0_A0(); |
|
1611 | 1615 |
break; |
1612 | 1616 |
case 1: |
1613 |
ot = OT_LONG; |
|
1614 |
is_int = 1; |
|
1617 |
gen_op_fildl_FT0_A0(); |
|
1615 | 1618 |
break; |
1616 | 1619 |
case 2: |
1617 |
ot = OT_QUAD; |
|
1618 |
is_int = 0; |
|
1620 |
gen_op_fldl_FT0_A0(); |
|
1619 | 1621 |
break; |
1620 | 1622 |
case 3: |
1621 | 1623 |
default: |
1622 |
ot = OT_WORD; |
|
1623 |
is_int = 1; |
|
1624 |
gen_op_fild_FT0_A0(); |
|
1624 | 1625 |
break; |
1625 | 1626 |
} |
1626 | 1627 |
|
1627 |
/* if integer, needs to convert to float */ |
|
1628 |
if (is_int) { |
|
1629 |
/* XXX: potential loss of precision if large integer */ |
|
1630 |
gen_ld(OP_LDUB + ot, OR_TMP0, reg_addr, offset_addr); |
|
1631 |
gen_insn2(OP_I2FL, OR_FTMP0, OR_TMP0); |
|
1632 |
} else { |
|
1633 |
gen_ld(OP_LDUB + ot, OR_FTMP0, reg_addr, offset_addr); |
|
1634 |
} |
|
1635 |
if (ot != OT_QUAD) |
|
1636 |
op1 += OP_FADDL - OP_FADDQ; |
|
1637 |
|
|
1638 |
if (!swap) |
|
1639 |
gen_insn3(op1, OR_ST0, OR_ST0, OR_FTMP0); |
|
1640 |
else |
|
1641 |
gen_insn3(op1, OR_ST0, OR_FTMP0, OR_ST0); |
|
1642 |
|
|
1643 |
if ((op & 7) == 3) { |
|
1628 |
gen_op_fp_arith_ST0_FT0[op1](); |
|
1629 |
if (op1 == 3) { |
|
1644 | 1630 |
/* fcomp needs pop */ |
1645 |
gen_insn0(OP_FPOP);
|
|
1631 |
gen_op_fpop();
|
|
1646 | 1632 |
} |
1647 | 1633 |
} |
1648 | 1634 |
break; |
... | ... | |
1659 | 1645 |
case 0x3a: /* fists */ |
1660 | 1646 |
case 0x3b: /* fistps */ |
1661 | 1647 |
|
1662 |
switch(op >> 4) { |
|
1663 |
case 0: |
|
1664 |
ot = OT_LONG; |
|
1665 |
is_int = 0; |
|
1666 |
break; |
|
1667 |
case 1: |
|
1668 |
ot = OT_LONG; |
|
1669 |
is_int = 1; |
|
1670 |
break; |
|
1671 |
case 2: |
|
1672 |
ot = OT_QUAD; |
|
1673 |
is_int = 0; |
|
1674 |
break; |
|
1675 |
case 3: |
|
1676 |
default: |
|
1677 |
ot = OT_WORD; |
|
1678 |
is_int = 1; |
|
1679 |
break; |
|
1680 |
} |
|
1681 |
|
|
1682 | 1648 |
switch(op & 7) { |
1683 | 1649 |
case 0: |
1684 |
gen_insn0(OP_FPUSH); |
|
1685 |
if (is_int) { |
|
1686 |
/* XXX: potential loss of precision */ |
|
1687 |
gen_ld(OP_LDUB + ot, OR_TMP0, reg_addr, offset_addr); |
|
1688 |
gen_insn2(OP_I2FL, OR_ST0, OR_TMP0); |
|
1689 |
} else { |
|
1690 |
gen_ld(OP_LDUB + ot, OR_ST0, reg_addr, offset_addr); |
|
1650 |
gen_op_fpush(); |
|
1651 |
switch(op >> 4) { |
|
1652 |
case 0: |
|
1653 |
gen_op_flds_ST0_A0(); |
|
1654 |
break; |
|
1655 |
case 1: |
|
1656 |
gen_op_fildl_ST0_A0(); |
|
1657 |
break; |
|
1658 |
case 2: |
|
1659 |
gen_op_fldl_ST0_A0(); |
|
1660 |
break; |
|
1661 |
case 3: |
|
1662 |
default: |
|
1663 |
gen_op_fild_ST0_A0(); |
|
1664 |
break; |
|
1691 | 1665 |
} |
1692 | 1666 |
break; |
1693 | 1667 |
default: |
1694 |
if (is_int) { |
|
1695 |
gen_insn2(OP_F2IL, OR_TMP0, OR_ST0); |
|
1696 |
gen_st(OP_STB + ot, OR_TMP0, reg_addr, offset_addr); |
|
1697 |
} else { |
|
1698 |
gen_st(OP_STB + ot, OR_ST0, reg_addr, offset_addr); |
|
1668 |
switch(op >> 4) { |
|
1669 |
case 0: |
|
1670 |
gen_op_fsts_ST0_A0(); |
|
1671 |
break; |
|
1672 |
case 1: |
|
1673 |
gen_op_fistl_ST0_A0(); |
|
1674 |
break; |
|
1675 |
case 2: |
|
1676 |
gen_op_fstl_ST0_A0(); |
|
1677 |
break; |
|
1678 |
case 3: |
|
1679 |
default: |
|
1680 |
gen_op_fist_ST0_A0(); |
|
1681 |
break; |
|
1699 | 1682 |
} |
1700 | 1683 |
if ((op & 7) == 3) |
1701 |
gen_insn0(OP_FPOP);
|
|
1684 |
gen_op_fpop();
|
|
1702 | 1685 |
break; |
1703 | 1686 |
} |
1704 | 1687 |
break; |
1688 |
#if 0 |
|
1705 | 1689 |
case 0x2f: /* fnstsw mem */ |
1706 | 1690 |
gen_insn3(OP_FNSTS, OR_TMP0, OR_ZERO, OR_ZERO); |
1707 | 1691 |
gen_st(OP_STW, OR_TMP0, reg_addr, offset_addr); |
... | ... | |
1711 | 1695 |
case 0x3e: /* fbstp */ |
1712 | 1696 |
error("float BCD not hanlded"); |
1713 | 1697 |
return -1; |
1698 |
#endif |
|
1714 | 1699 |
case 0x3d: /* fildll */ |
1715 |
gen_insn0(OP_FPUSH); |
|
1716 |
gen_ld(OP_LDQ, OR_TMP0, reg_addr, offset_addr); |
|
1717 |
gen_insn2(OP_I2FQ, OR_ST0, OR_TMP0); |
|
1700 |
gen_op_fpush(); |
|
1701 |
gen_op_fildll_ST0_A0(); |
|
1718 | 1702 |
break; |
1719 | 1703 |
case 0x3f: /* fistpll */ |
1720 |
gen_insn2(OP_F2IQ, OR_TMP0, OR_ST0); |
|
1721 |
gen_st(OP_STQ, OR_TMP0, reg_addr, offset_addr); |
|
1722 |
gen_insn0(OP_FPOP); |
|
1704 |
gen_op_fistll_ST0_A0(); |
|
1705 |
gen_op_fpop(); |
|
1723 | 1706 |
break; |
1724 | 1707 |
default: |
1725 | 1708 |
error("unhandled memory FP\n"); |
... | ... | |
1727 | 1710 |
} |
1728 | 1711 |
} else { |
1729 | 1712 |
/* register float ops */ |
1730 |
opreg = rm + OR_ST0;
|
|
1713 |
opreg = rm; |
|
1731 | 1714 |
|
1732 | 1715 |
switch(op) { |
1733 | 1716 |
case 0x08: /* fld sti */ |
1734 |
gen_insn0(OP_FPUSH);
|
|
1735 |
gen_mov(OR_ST0, OR_ST0 + ((rm + 1) & 7));
|
|
1717 |
gen_op_fpush();
|
|
1718 |
gen_op_fmov_ST0_STN((opreg + 1) & 7);
|
|
1736 | 1719 |
break; |
1737 | 1720 |
case 0x09: /* fxchg sti */ |
1738 |
gen_mov(OR_TMP0, OR_ST0); |
|
1739 |
gen_mov(OR_ST0, opreg); |
|
1740 |
gen_mov(opreg, OR_TMP0); |
|
1721 |
gen_op_fxchg_ST0_STN((opreg + 1) & 7); |
|
1741 | 1722 |
break; |
1742 | 1723 |
case 0x0a: /* grp d9/2 */ |
1743 | 1724 |
switch(rm) { |
1744 | 1725 |
case 0: /* fnop */ |
1745 |
gen_insn0(OP_NOP); |
|
1746 | 1726 |
break; |
1747 | 1727 |
default: |
1748 | 1728 |
error("unhandled FP GRP d9/2\n"); |
... | ... | |
1752 | 1732 |
case 0x0c: /* grp d9/4 */ |
1753 | 1733 |
switch(rm) { |
1754 | 1734 |
case 0: /* fchs */ |
1755 |
gen_insn3(OP_FSUBQ, OR_ST0, OR_ZERO, OR_ST0);
|
|
1735 |
gen_op_fchs_ST0();
|
|
1756 | 1736 |
break; |
1757 | 1737 |
case 1: /* fabs */ |
1758 |
gen_insn2(OP_FABSQ, OR_ST0, OR_ST0);
|
|
1738 |
gen_op_fabs_ST0();
|
|
1759 | 1739 |
break; |
1760 | 1740 |
case 4: /* ftst */ |
1761 |
gen_insn3(OP_CMP, OR_ZERO, OR_ST0, OR_ZERO); |
|
1741 |
gen_op_fldz_FT0(); |
|
1742 |
gen_op_fcom_ST0_FT0(); |
|
1762 | 1743 |
break; |
1763 | 1744 |
case 5: /* fxam */ |
1764 |
gen_insn3(OP_FSPECIAL, OR_ZERO, OR_ST0, OR_ZERO);
|
|
1745 |
gen_op_fxam_ST0();
|
|
1765 | 1746 |
break; |
1766 | 1747 |
default: |
1767 | 1748 |
return -1; |
... | ... | |
1769 | 1750 |
break; |
1770 | 1751 |
case 0x0d: /* grp d9/5 */ |
1771 | 1752 |
{ |
1772 |
if (rm == 7) { |
|
1773 |
error("bad GRP d9/5"); |
|
1753 |
switch(rm) { |
|
1754 |
case 0: |
|
1755 |
gen_op_fld1_ST0(); |
|
1756 |
break; |
|
1757 |
case 1: |
|
1758 |
gen_op_fld2t_ST0(); |
|
1759 |
break; |
|
1760 |
case 2: |
|
1761 |
gen_op_fld2e_ST0(); |
|
1762 |
break; |
|
1763 |
case 3: |
|
1764 |
gen_op_fldpi_ST0(); |
|
1765 |
break; |
|
1766 |
case 4: |
|
1767 |
gen_op_fldlg2_ST0(); |
|
1768 |
break; |
|
1769 |
case 5: |
|
1770 |
gen_op_fldln2_ST0(); |
|
1771 |
break; |
|
1772 |
case 6: |
|
1773 |
gen_op_fldz_ST0(); |
|
1774 |
break; |
|
1775 |
default: |
|
1774 | 1776 |
return -1; |
1775 | 1777 |
} |
1776 |
/* XXX: needs constant load or symbol table */ |
|
1777 |
gen_insn0(OP_FPUSH); |
|
1778 |
gen_ld(OP_LDQ, OR_ST0, OR_ZERO, |
|
1779 |
(rm * 8) + FLOAT_CONST_ADDR); |
|
1780 | 1778 |
} |
1781 | 1779 |
break; |
1782 | 1780 |
case 0x0e: /* grp d9/6 */ |
1783 | 1781 |
switch(rm) { |
1784 | 1782 |
case 0: /* f2xm1 */ |
1785 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ZERO);
|
|
1783 |
gen_op_f2xm1();
|
|
1786 | 1784 |
break; |
1787 | 1785 |
case 1: /* fyl2x */ |
1788 |
gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST0, OR_ST1); |
|
1789 |
gen_insn0(OP_FPOP); |
|
1786 |
gen_op_fyl2x(); |
|
1790 | 1787 |
break; |
1791 | 1788 |
case 2: /* fptan */ |
1792 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ZERO); |
|
1793 |
gen_insn0(OP_FPUSH); |
|
1794 |
/* load one */ |
|
1795 |
gen_ld(OP_LDQ, OR_ST0, OR_ZERO, |
|
1796 |
(0 * 8) + FLOAT_CONST_ADDR); |
|
1789 |
gen_op_fptan(); |
|
1797 | 1790 |
break; |
1798 | 1791 |
case 3: /* fpatan */ |
1799 |
gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST0, OR_ST1); |
|
1800 |
gen_insn0(OP_FPOP); |
|
1792 |
gen_op_fpatan(); |
|
1801 | 1793 |
break; |
1802 | 1794 |
case 4: /* fxtract */ |
1803 |
gen_insn0(OP_FPUSH); |
|
1804 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST1, OR_ZERO); |
|
1805 |
gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST1, OR_ZERO); |
|
1795 |
gen_op_fxtract(); |
|
1806 | 1796 |
break; |
1807 | 1797 |
case 5: /* fprem1 */ |
1808 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ST1);
|
|
1798 |
gen_op_fprem1();
|
|
1809 | 1799 |
break; |
1810 | 1800 |
case 6: /* fdecstp */ |
1811 |
gen_insn0(OP_FPUSH);
|
|
1801 |
gen_op_fdecstp();
|
|
1812 | 1802 |
break; |
1813 | 1803 |
default: |
1814 |
case 7: /* fdecstp */
|
|
1815 |
gen_insn0(OP_FPOP);
|
|
1804 |
case 7: /* fincstp */
|
|
1805 |
gen_op_fincstp();
|
|
1816 | 1806 |
break; |
1817 | 1807 |
} |
1818 | 1808 |
break; |
1819 | 1809 |
case 0x0f: /* grp d9/7 */ |
1820 | 1810 |
switch(rm) { |
1821 | 1811 |
case 0: /* fprem */ |
1822 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ST1);
|
|
1812 |
gen_op_fprem();
|
|
1823 | 1813 |
break; |
1824 | 1814 |
case 1: /* fyl2xp1 */ |
1825 |
gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST0, OR_ST1); |
|
1826 |
gen_insn0(OP_FPOP); |
|
1815 |
gen_op_fyl2xp1(); |
|
1816 |
break; |
|
1817 |
case 2: /* fsqrt */ |
|
1818 |
gen_op_fsqrt(); |
|
1827 | 1819 |
break; |
1828 | 1820 |
case 3: /* fsincos */ |
1829 |
gen_insn0(OP_FPUSH); |
|
1830 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST1, OR_ZERO); |
|
1831 |
gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST1, OR_ZERO); |
|
1821 |
gen_op_fsincos(); |
|
1832 | 1822 |
break; |
1833 | 1823 |
case 5: /* fscale */ |
1834 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ST1);
|
|
1824 |
gen_op_fscale();
|
|
1835 | 1825 |
break; |
1836 |
case 2: /* fsqrt */ |
|
1837 | 1826 |
case 4: /* frndint */ |
1827 |
gen_op_frndint(); |
|
1828 |
break; |
|
1838 | 1829 |
case 6: /* fsin */ |
1830 |
gen_op_fsin(); |
|
1831 |
break; |
|
1839 | 1832 |
default: |
1840 | 1833 |
case 7: /* fcos */ |
1841 |
gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ZERO);
|
|
1834 |
gen_op_fcos();
|
|
1842 | 1835 |
break; |
1843 | 1836 |
} |
1844 | 1837 |
break; |
... | ... | |
1846 | 1839 |
case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ |
1847 | 1840 |
case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ |
1848 | 1841 |
{ |
1849 |
int op1, swap;
|
|
1842 |
int op1; |
|
1850 | 1843 |
|
1851 |
op1 = fp_ops[op & 7]; |
|
1852 |
swap = 0; |
|
1853 |
if ((op & 7) == 5 || (op & 7) == 7) |
|
1854 |
swap = 1; |
|
1844 |
op1 = op & 7; |
|
1855 | 1845 |
if (op >= 0x20) { |
1856 |
if (swap) |
|
1857 |
gen_insn3(op1, opreg, OR_ST0, opreg); |
|
1858 |
else |
|
1859 |
gen_insn3(op1, opreg, opreg, OR_ST0); |
|
1846 |
gen_op_fp_arith_STN_ST0[op1](opreg); |
|
1860 | 1847 |
} else { |
1861 |
if (swap) |
|
1862 |
gen_insn3(op1, OR_ST0, opreg, OR_ST0); |
|
1863 |
else |
|
1864 |
gen_insn3(op1, OR_ST0, OR_ST0, opreg); |
|
1848 |
gen_op_fmov_FT0_STN(opreg); |
|
1849 |
gen_op_fp_arith_ST0_FT0[op1](); |
|
1865 | 1850 |
} |
1866 | 1851 |
if (op >= 0x30) |
1867 |
gen_insn0(OP_FPOP);
|
|
1852 |
gen_op_fpop();
|
|
1868 | 1853 |
} |
1869 | 1854 |
break; |
1870 | 1855 |
case 0x02: /* fcom */ |
1871 |
gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg); |
|
1856 |
gen_op_fmov_FT0_STN(opreg); |
|
1857 |
gen_op_fcom_ST0_FT0(); |
|
1872 | 1858 |
break; |
1873 | 1859 |
case 0x03: /* fcomp */ |
1874 |
gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg); |
|
1875 |
gen_insn0(OP_FPOP); |
|
1860 |
gen_op_fmov_FT0_STN(opreg); |
|
1861 |
gen_op_fcom_ST0_FT0(); |
|
1862 |
gen_op_fpop(); |
|
1876 | 1863 |
break; |
1877 | 1864 |
case 0x15: /* da/5 */ |
1878 | 1865 |
switch(rm) { |
1879 | 1866 |
case 1: /* fucompp */ |
1880 |
gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg); |
|
1881 |
gen_insn0(OP_FPOP); |
|
1882 |
gen_insn0(OP_FPOP); |
|
1867 |
gen_op_fmov_FT0_STN(1); |
|
1868 |
gen_op_fcom_ST0_FT0(); |
|
1869 |
gen_op_fpop(); |
|
1870 |
gen_op_fpop(); |
|
1883 | 1871 |
break; |
1884 | 1872 |
default: |
1885 | 1873 |
return -1; |
1886 | 1874 |
} |
1887 | 1875 |
break; |
1888 | 1876 |
case 0x2a: /* fst sti */ |
1889 |
gen_mov(opreg, OR_ST0);
|
|
1877 |
gen_op_fmov_STN_ST0(opreg);
|
|
1890 | 1878 |
break; |
1891 | 1879 |
case 0x2b: /* fstp sti */ |
1892 |
gen_mov(opreg, OR_ST0);
|
|
1893 |
gen_insn0(OP_FPOP);
|
|
1880 |
gen_op_fmov_STN_ST0(opreg);
|
|
1881 |
gen_op_fpop();
|
|
1894 | 1882 |
break; |
1895 | 1883 |
case 0x33: /* de/3 */ |
1896 | 1884 |
switch(rm) { |
1897 | 1885 |
case 1: /* fcompp */ |
1898 |
gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg); |
|
1899 |
gen_insn0(OP_FPOP); |
|
1900 |
gen_insn0(OP_FPOP); |
|
1886 |
gen_op_fmov_FT0_STN(1); |
|
1887 |
gen_op_fcom_ST0_FT0(); |
|
1888 |
gen_op_fpop(); |
|
1889 |
gen_op_fpop(); |
|
1901 | 1890 |
break; |
1902 | 1891 |
default: |
1903 | 1892 |
return -1; |
... | ... | |
1905 | 1894 |
break; |
1906 | 1895 |
case 0x3c: /* df/4 */ |
1907 | 1896 |
switch(rm) { |
1897 |
#if 0 |
|
1908 | 1898 |
case 0: |
1909 | 1899 |
gen_insn3(OP_FNSTS, OR_EAX, OR_ZERO, OR_ZERO); |
1910 | 1900 |
break; |
1901 |
#endif |
|
1911 | 1902 |
default: |
1912 | 1903 |
return -1; |
1913 | 1904 |
} |
... | ... | |
1918 | 1909 |
} |
1919 | 1910 |
} |
1920 | 1911 |
break; |
1921 |
#endif |
|
1922 | 1912 |
/************************/ |
1923 | 1913 |
/* string ops */ |
1924 | 1914 |
case 0xa4: /* movsS */ |
Also available in: Unified diff