Commit 8cd6345d00a25ffa8828bce31154c88f76fb7fc6
1 parent
d19076fa
Immediate versions of ro[lr]
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6968 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
83 additions
and
1 deletions
target-i386/translate.c
| ... | ... | @@ -1551,7 +1551,6 @@ static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2) |
| 1551 | 1551 | tcg_gen_shri_tl(ret, arg1, -arg2); |
| 1552 | 1552 | } |
| 1553 | 1553 | |
| 1554 | -/* XXX: add faster immediate case */ | |
| 1555 | 1554 | static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, |
| 1556 | 1555 | int is_right) |
| 1557 | 1556 | { |
| ... | ... | @@ -1648,6 +1647,83 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, |
| 1648 | 1647 | tcg_temp_free(a0); |
| 1649 | 1648 | } |
| 1650 | 1649 | |
| 1650 | +static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, | |
| 1651 | + int is_right) | |
| 1652 | +{ | |
| 1653 | + int mask; | |
| 1654 | + int data_bits; | |
| 1655 | + TCGv t0, t1, a0; | |
| 1656 | + | |
| 1657 | + /* XXX: inefficient, but we must use local temps */ | |
| 1658 | + t0 = tcg_temp_local_new(); | |
| 1659 | + t1 = tcg_temp_local_new(); | |
| 1660 | + a0 = tcg_temp_local_new(); | |
| 1661 | + | |
| 1662 | + if (ot == OT_QUAD) | |
| 1663 | + mask = 0x3f; | |
| 1664 | + else | |
| 1665 | + mask = 0x1f; | |
| 1666 | + | |
| 1667 | + /* load */ | |
| 1668 | + if (op1 == OR_TMP0) { | |
| 1669 | + tcg_gen_mov_tl(a0, cpu_A0); | |
| 1670 | + gen_op_ld_v(ot + s->mem_index, t0, a0); | |
| 1671 | + } else { | |
| 1672 | + gen_op_mov_v_reg(ot, t0, op1); | |
| 1673 | + } | |
| 1674 | + | |
| 1675 | + gen_extu(ot, t0); | |
| 1676 | + tcg_gen_mov_tl(t1, t0); | |
| 1677 | + | |
| 1678 | + op2 &= mask; | |
| 1679 | + data_bits = 8 << ot; | |
| 1680 | + if (op2 != 0) { | |
| 1681 | + int shift = op2 & ((1 << (3 + ot)) - 1); | |
| 1682 | + if (is_right) { | |
| 1683 | + tcg_gen_shri_tl(cpu_tmp4, t0, shift); | |
| 1684 | + tcg_gen_shli_tl(t0, t0, data_bits - shift); | |
| 1685 | + } | |
| 1686 | + else { | |
| 1687 | + tcg_gen_shli_tl(cpu_tmp4, t0, shift); | |
| 1688 | + tcg_gen_shri_tl(t0, t0, data_bits - shift); | |
| 1689 | + } | |
| 1690 | + tcg_gen_or_tl(t0, t0, cpu_tmp4); | |
| 1691 | + } | |
| 1692 | + | |
| 1693 | + /* store */ | |
| 1694 | + if (op1 == OR_TMP0) { | |
| 1695 | + gen_op_st_v(ot + s->mem_index, t0, a0); | |
| 1696 | + } else { | |
| 1697 | + gen_op_mov_reg_v(ot, op1, t0); | |
| 1698 | + } | |
| 1699 | + | |
| 1700 | + if (op2 != 0) { | |
| 1701 | + /* update eflags */ | |
| 1702 | + if (s->cc_op != CC_OP_DYNAMIC) | |
| 1703 | + gen_op_set_cc_op(s->cc_op); | |
| 1704 | + | |
| 1705 | + gen_compute_eflags(cpu_cc_src); | |
| 1706 | + tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C)); | |
| 1707 | + tcg_gen_xor_tl(cpu_tmp0, t1, t0); | |
| 1708 | + tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1)); | |
| 1709 | + tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O); | |
| 1710 | + tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0); | |
| 1711 | + if (is_right) { | |
| 1712 | + tcg_gen_shri_tl(t0, t0, data_bits - 1); | |
| 1713 | + } | |
| 1714 | + tcg_gen_andi_tl(t0, t0, CC_C); | |
| 1715 | + tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0); | |
| 1716 | + | |
| 1717 | + tcg_gen_discard_tl(cpu_cc_dst); | |
| 1718 | + tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS); | |
| 1719 | + s->cc_op = CC_OP_EFLAGS; | |
| 1720 | + } | |
| 1721 | + | |
| 1722 | + tcg_temp_free(t0); | |
| 1723 | + tcg_temp_free(t1); | |
| 1724 | + tcg_temp_free(a0); | |
| 1725 | +} | |
| 1726 | + | |
| 1651 | 1727 | /* XXX: add faster immediate = 1 case */ |
| 1652 | 1728 | static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, |
| 1653 | 1729 | int is_right) |
| ... | ... | @@ -1862,6 +1938,12 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) |
| 1862 | 1938 | static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) |
| 1863 | 1939 | { |
| 1864 | 1940 | switch(op) { |
| 1941 | + case OP_ROL: | |
| 1942 | + gen_rot_rm_im(s1, ot, d, c, 0); | |
| 1943 | + break; | |
| 1944 | + case OP_ROR: | |
| 1945 | + gen_rot_rm_im(s1, ot, d, c, 1); | |
| 1946 | + break; | |
| 1865 | 1947 | case OP_SHL: |
| 1866 | 1948 | case OP_SHL1: |
| 1867 | 1949 | gen_shift_rm_im(s1, ot, d, c, 0, 0); | ... | ... |