Commit d42f183c0452a9c769b91e3911566566724983ff

Authored by aurel32
1 parent a1f6684d

Implement TCG rotation ops for x86-64

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6795 c046a42c-6fe2-441c-8c8c-71466251a162
tcg/tcg-op.h
... ... @@ -1573,6 +1573,9 @@ static inline void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1573 1573  
1574 1574 static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1575 1575 {
  1576 +#ifdef TCG_TARGET_HAS_rot_i32
  1577 + tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
  1578 +#else
1576 1579 TCGv_i32 t0, t1;
1577 1580  
1578 1581 t0 = tcg_temp_new_i32();
... ... @@ -1583,10 +1586,14 @@ static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1583 1586 tcg_gen_or_i32(ret, t0, t1);
1584 1587 tcg_temp_free_i32(t0);
1585 1588 tcg_temp_free_i32(t1);
  1589 +#endif
1586 1590 }
1587 1591  
1588 1592 static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1589 1593 {
  1594 +#ifdef TCG_TARGET_HAS_rot_i64
  1595 + tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
  1596 +#else
1590 1597 TCGv_i64 t0, t1;
1591 1598  
1592 1599 t0 = tcg_temp_new_i64();
... ... @@ -1597,6 +1604,7 @@ static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1597 1604 tcg_gen_or_i64(ret, t0, t1);
1598 1605 tcg_temp_free_i64(t0);
1599 1606 tcg_temp_free_i64(t1);
  1607 +#endif
1600 1608 }
1601 1609  
1602 1610 static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
... ... @@ -1605,6 +1613,11 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
1605 1613 if (arg2 == 0) {
1606 1614 tcg_gen_mov_i32(ret, arg1);
1607 1615 } else {
  1616 +#ifdef TCG_TARGET_HAS_rot_i32
  1617 + TCGv_i32 t0 = tcg_const_i32(arg2);
  1618 + tcg_gen_rotl_i32(ret, arg1, t0);
  1619 + tcg_temp_free_i32(t0);
  1620 +#else
1608 1621 TCGv_i32 t0, t1;
1609 1622 t0 = tcg_temp_new_i32();
1610 1623 t1 = tcg_temp_new_i32();
... ... @@ -1613,6 +1626,7 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
1613 1626 tcg_gen_or_i32(ret, t0, t1);
1614 1627 tcg_temp_free_i32(t0);
1615 1628 tcg_temp_free_i32(t1);
  1629 +#endif
1616 1630 }
1617 1631 }
1618 1632  
... ... @@ -1622,6 +1636,11 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1622 1636 if (arg2 == 0) {
1623 1637 tcg_gen_mov_i64(ret, arg1);
1624 1638 } else {
  1639 +#ifdef TCG_TARGET_HAS_rot_i64
  1640 + TCGv_i64 t0 = tcg_const_i64(arg2);
  1641 + tcg_gen_rotl_i64(ret, arg1, t0);
  1642 + tcg_temp_free_i64(t0);
  1643 +#else
1625 1644 TCGv_i64 t0, t1;
1626 1645 t0 = tcg_temp_new_i64();
1627 1646 t1 = tcg_temp_new_i64();
... ... @@ -1630,11 +1649,15 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1630 1649 tcg_gen_or_i64(ret, t0, t1);
1631 1650 tcg_temp_free_i64(t0);
1632 1651 tcg_temp_free_i64(t1);
  1652 +#endif
1633 1653 }
1634 1654 }
1635 1655  
1636 1656 static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1637 1657 {
  1658 +#ifdef TCG_TARGET_HAS_rot_i32
  1659 + tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
  1660 +#else
1638 1661 TCGv_i32 t0, t1;
1639 1662  
1640 1663 t0 = tcg_temp_new_i32();
... ... @@ -1645,10 +1668,14 @@ static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1645 1668 tcg_gen_or_i32(ret, t0, t1);
1646 1669 tcg_temp_free_i32(t0);
1647 1670 tcg_temp_free_i32(t1);
  1671 +#endif
1648 1672 }
1649 1673  
1650 1674 static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1651 1675 {
  1676 +#ifdef TCG_TARGET_HAS_rot_i64
  1677 + tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
  1678 +#else
1652 1679 TCGv_i64 t0, t1;
1653 1680  
1654 1681 t0 = tcg_temp_new_i64();
... ... @@ -1659,6 +1686,7 @@ static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1659 1686 tcg_gen_or_i64(ret, t0, t1);
1660 1687 tcg_temp_free_i64(t0);
1661 1688 tcg_temp_free_i64(t1);
  1689 +#endif
1662 1690 }
1663 1691  
1664 1692 static inline void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
... ...
tcg/tcg-opc.h
... ... @@ -67,10 +67,12 @@ DEF2(divu2_i32, 2, 3, 0, 0)
67 67 DEF2(and_i32, 1, 2, 0, 0)
68 68 DEF2(or_i32, 1, 2, 0, 0)
69 69 DEF2(xor_i32, 1, 2, 0, 0)
70   -/* shifts */
  70 +/* shifts/rotates */
71 71 DEF2(shl_i32, 1, 2, 0, 0)
72 72 DEF2(shr_i32, 1, 2, 0, 0)
73 73 DEF2(sar_i32, 1, 2, 0, 0)
  74 +DEF2(rotl_i32, 1, 2, 0, 0)
  75 +DEF2(rotr_i32, 1, 2, 0, 0)
74 76  
75 77 DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
76 78 #if TCG_TARGET_REG_BITS == 32
... ... @@ -120,10 +122,12 @@ DEF2(divu2_i64, 2, 3, 0, 0)
120 122 DEF2(and_i64, 1, 2, 0, 0)
121 123 DEF2(or_i64, 1, 2, 0, 0)
122 124 DEF2(xor_i64, 1, 2, 0, 0)
123   -/* shifts */
  125 +/* shifts/rotates */
124 126 DEF2(shl_i64, 1, 2, 0, 0)
125 127 DEF2(shr_i64, 1, 2, 0, 0)
126 128 DEF2(sar_i64, 1, 2, 0, 0)
  129 +DEF2(rotl_i64, 1, 2, 0, 0)
  130 +DEF2(rotr_i64, 1, 2, 0, 0)
127 131  
128 132 DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
129 133 #ifdef TCG_TARGET_HAS_ext8s_i64
... ...
tcg/x86_64/tcg-target.c
... ... @@ -194,6 +194,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
194 194 #define ARITH_XOR 6
195 195 #define ARITH_CMP 7
196 196  
  197 +#define SHIFT_ROL 0
  198 +#define SHIFT_ROR 1
197 199 #define SHIFT_SHL 4
198 200 #define SHIFT_SHR 5
199 201 #define SHIFT_SAR 7
... ... @@ -1049,7 +1051,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1049 1051 case INDEX_op_sar_i32:
1050 1052 c = SHIFT_SAR;
1051 1053 goto gen_shift32;
1052   -
  1054 + case INDEX_op_rotl_i32:
  1055 + c = SHIFT_ROL;
  1056 + goto gen_shift32;
  1057 + case INDEX_op_rotr_i32:
  1058 + c = SHIFT_ROR;
  1059 + goto gen_shift32;
  1060 +
1053 1061 case INDEX_op_shl_i64:
1054 1062 c = SHIFT_SHL;
1055 1063 gen_shift64:
... ... @@ -1070,7 +1078,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1070 1078 case INDEX_op_sar_i64:
1071 1079 c = SHIFT_SAR;
1072 1080 goto gen_shift64;
1073   -
  1081 + case INDEX_op_rotl_i64:
  1082 + c = SHIFT_ROL;
  1083 + goto gen_shift64;
  1084 + case INDEX_op_rotr_i64:
  1085 + c = SHIFT_ROR;
  1086 + goto gen_shift64;
  1087 +
1074 1088 case INDEX_op_brcond_i32:
1075 1089 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1076 1090 args[3], 0);
... ... @@ -1230,6 +1244,8 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
1230 1244 { INDEX_op_shl_i32, { "r", "0", "ci" } },
1231 1245 { INDEX_op_shr_i32, { "r", "0", "ci" } },
1232 1246 { INDEX_op_sar_i32, { "r", "0", "ci" } },
  1247 + { INDEX_op_rotl_i32, { "r", "0", "ci" } },
  1248 + { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1233 1249  
1234 1250 { INDEX_op_brcond_i32, { "r", "ri" } },
1235 1251  
... ... @@ -1259,6 +1275,8 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
1259 1275 { INDEX_op_shl_i64, { "r", "0", "ci" } },
1260 1276 { INDEX_op_shr_i64, { "r", "0", "ci" } },
1261 1277 { INDEX_op_sar_i64, { "r", "0", "ci" } },
  1278 + { INDEX_op_rotl_i64, { "r", "0", "ci" } },
  1279 + { INDEX_op_rotr_i64, { "r", "0", "ci" } },
1262 1280  
1263 1281 { INDEX_op_brcond_i64, { "r", "re" } },
1264 1282  
... ...
tcg/x86_64/tcg-target.h
... ... @@ -65,6 +65,8 @@ enum {
65 65 #define TCG_TARGET_HAS_ext8s_i64
66 66 #define TCG_TARGET_HAS_ext16s_i64
67 67 #define TCG_TARGET_HAS_ext32s_i64
  68 +#define TCG_TARGET_HAS_rot_i32
  69 +#define TCG_TARGET_HAS_rot_i64
68 70  
69 71 /* Note: must be synced with dyngen-exec.h */
70 72 #define TCG_AREG0 TCG_REG_R14
... ...