Commit 8cd6345d00a25ffa8828bce31154c88f76fb7fc6

Authored by malc
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);
... ...