Revision 8cd6345d
b/target-i386/translate.c | ||
---|---|---|
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 | 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 | 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); |
Also available in: Unified diff