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,6 +1573,9 @@ static inline void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1573 1573
1574 static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 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 TCGv_i32 t0, t1; 1579 TCGv_i32 t0, t1;
1577 1580
1578 t0 = tcg_temp_new_i32(); 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,10 +1586,14 @@ static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1583 tcg_gen_or_i32(ret, t0, t1); 1586 tcg_gen_or_i32(ret, t0, t1);
1584 tcg_temp_free_i32(t0); 1587 tcg_temp_free_i32(t0);
1585 tcg_temp_free_i32(t1); 1588 tcg_temp_free_i32(t1);
  1589 +#endif
1586 } 1590 }
1587 1591
1588 static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 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 TCGv_i64 t0, t1; 1597 TCGv_i64 t0, t1;
1591 1598
1592 t0 = tcg_temp_new_i64(); 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,6 +1604,7 @@ static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1597 tcg_gen_or_i64(ret, t0, t1); 1604 tcg_gen_or_i64(ret, t0, t1);
1598 tcg_temp_free_i64(t0); 1605 tcg_temp_free_i64(t0);
1599 tcg_temp_free_i64(t1); 1606 tcg_temp_free_i64(t1);
  1607 +#endif
1600 } 1608 }
1601 1609
1602 static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 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,6 +1613,11 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
1605 if (arg2 == 0) { 1613 if (arg2 == 0) {
1606 tcg_gen_mov_i32(ret, arg1); 1614 tcg_gen_mov_i32(ret, arg1);
1607 } else { 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 TCGv_i32 t0, t1; 1621 TCGv_i32 t0, t1;
1609 t0 = tcg_temp_new_i32(); 1622 t0 = tcg_temp_new_i32();
1610 t1 = tcg_temp_new_i32(); 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,6 +1626,7 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
1613 tcg_gen_or_i32(ret, t0, t1); 1626 tcg_gen_or_i32(ret, t0, t1);
1614 tcg_temp_free_i32(t0); 1627 tcg_temp_free_i32(t0);
1615 tcg_temp_free_i32(t1); 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,6 +1636,11 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1622 if (arg2 == 0) { 1636 if (arg2 == 0) {
1623 tcg_gen_mov_i64(ret, arg1); 1637 tcg_gen_mov_i64(ret, arg1);
1624 } else { 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 TCGv_i64 t0, t1; 1644 TCGv_i64 t0, t1;
1626 t0 = tcg_temp_new_i64(); 1645 t0 = tcg_temp_new_i64();
1627 t1 = tcg_temp_new_i64(); 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,11 +1649,15 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1630 tcg_gen_or_i64(ret, t0, t1); 1649 tcg_gen_or_i64(ret, t0, t1);
1631 tcg_temp_free_i64(t0); 1650 tcg_temp_free_i64(t0);
1632 tcg_temp_free_i64(t1); 1651 tcg_temp_free_i64(t1);
  1652 +#endif
1633 } 1653 }
1634 } 1654 }
1635 1655
1636 static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 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 TCGv_i32 t0, t1; 1661 TCGv_i32 t0, t1;
1639 1662
1640 t0 = tcg_temp_new_i32(); 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,10 +1668,14 @@ static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1645 tcg_gen_or_i32(ret, t0, t1); 1668 tcg_gen_or_i32(ret, t0, t1);
1646 tcg_temp_free_i32(t0); 1669 tcg_temp_free_i32(t0);
1647 tcg_temp_free_i32(t1); 1670 tcg_temp_free_i32(t1);
  1671 +#endif
1648 } 1672 }
1649 1673
1650 static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 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 TCGv_i64 t0, t1; 1679 TCGv_i64 t0, t1;
1653 1680
1654 t0 = tcg_temp_new_i64(); 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,6 +1686,7 @@ static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1659 tcg_gen_or_i64(ret, t0, t1); 1686 tcg_gen_or_i64(ret, t0, t1);
1660 tcg_temp_free_i64(t0); 1687 tcg_temp_free_i64(t0);
1661 tcg_temp_free_i64(t1); 1688 tcg_temp_free_i64(t1);
  1689 +#endif
1662 } 1690 }
1663 1691
1664 static inline void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 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,10 +67,12 @@ DEF2(divu2_i32, 2, 3, 0, 0)
67 DEF2(and_i32, 1, 2, 0, 0) 67 DEF2(and_i32, 1, 2, 0, 0)
68 DEF2(or_i32, 1, 2, 0, 0) 68 DEF2(or_i32, 1, 2, 0, 0)
69 DEF2(xor_i32, 1, 2, 0, 0) 69 DEF2(xor_i32, 1, 2, 0, 0)
70 -/* shifts */ 70 +/* shifts/rotates */
71 DEF2(shl_i32, 1, 2, 0, 0) 71 DEF2(shl_i32, 1, 2, 0, 0)
72 DEF2(shr_i32, 1, 2, 0, 0) 72 DEF2(shr_i32, 1, 2, 0, 0)
73 DEF2(sar_i32, 1, 2, 0, 0) 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 DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) 77 DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
76 #if TCG_TARGET_REG_BITS == 32 78 #if TCG_TARGET_REG_BITS == 32
@@ -120,10 +122,12 @@ DEF2(divu2_i64, 2, 3, 0, 0) @@ -120,10 +122,12 @@ DEF2(divu2_i64, 2, 3, 0, 0)
120 DEF2(and_i64, 1, 2, 0, 0) 122 DEF2(and_i64, 1, 2, 0, 0)
121 DEF2(or_i64, 1, 2, 0, 0) 123 DEF2(or_i64, 1, 2, 0, 0)
122 DEF2(xor_i64, 1, 2, 0, 0) 124 DEF2(xor_i64, 1, 2, 0, 0)
123 -/* shifts */ 125 +/* shifts/rotates */
124 DEF2(shl_i64, 1, 2, 0, 0) 126 DEF2(shl_i64, 1, 2, 0, 0)
125 DEF2(shr_i64, 1, 2, 0, 0) 127 DEF2(shr_i64, 1, 2, 0, 0)
126 DEF2(sar_i64, 1, 2, 0, 0) 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 DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) 132 DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
129 #ifdef TCG_TARGET_HAS_ext8s_i64 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,6 +194,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
194 #define ARITH_XOR 6 194 #define ARITH_XOR 6
195 #define ARITH_CMP 7 195 #define ARITH_CMP 7
196 196
  197 +#define SHIFT_ROL 0
  198 +#define SHIFT_ROR 1
197 #define SHIFT_SHL 4 199 #define SHIFT_SHL 4
198 #define SHIFT_SHR 5 200 #define SHIFT_SHR 5
199 #define SHIFT_SAR 7 201 #define SHIFT_SAR 7
@@ -1049,7 +1051,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, @@ -1049,7 +1051,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1049 case INDEX_op_sar_i32: 1051 case INDEX_op_sar_i32:
1050 c = SHIFT_SAR; 1052 c = SHIFT_SAR;
1051 goto gen_shift32; 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 case INDEX_op_shl_i64: 1061 case INDEX_op_shl_i64:
1054 c = SHIFT_SHL; 1062 c = SHIFT_SHL;
1055 gen_shift64: 1063 gen_shift64:
@@ -1070,7 +1078,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, @@ -1070,7 +1078,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1070 case INDEX_op_sar_i64: 1078 case INDEX_op_sar_i64:
1071 c = SHIFT_SAR; 1079 c = SHIFT_SAR;
1072 goto gen_shift64; 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 case INDEX_op_brcond_i32: 1088 case INDEX_op_brcond_i32:
1075 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], 1089 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1076 args[3], 0); 1090 args[3], 0);
@@ -1230,6 +1244,8 @@ static const TCGTargetOpDef x86_64_op_defs[] = { @@ -1230,6 +1244,8 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
1230 { INDEX_op_shl_i32, { "r", "0", "ci" } }, 1244 { INDEX_op_shl_i32, { "r", "0", "ci" } },
1231 { INDEX_op_shr_i32, { "r", "0", "ci" } }, 1245 { INDEX_op_shr_i32, { "r", "0", "ci" } },
1232 { INDEX_op_sar_i32, { "r", "0", "ci" } }, 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 { INDEX_op_brcond_i32, { "r", "ri" } }, 1250 { INDEX_op_brcond_i32, { "r", "ri" } },
1235 1251
@@ -1259,6 +1275,8 @@ static const TCGTargetOpDef x86_64_op_defs[] = { @@ -1259,6 +1275,8 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
1259 { INDEX_op_shl_i64, { "r", "0", "ci" } }, 1275 { INDEX_op_shl_i64, { "r", "0", "ci" } },
1260 { INDEX_op_shr_i64, { "r", "0", "ci" } }, 1276 { INDEX_op_shr_i64, { "r", "0", "ci" } },
1261 { INDEX_op_sar_i64, { "r", "0", "ci" } }, 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 { INDEX_op_brcond_i64, { "r", "re" } }, 1281 { INDEX_op_brcond_i64, { "r", "re" } },
1264 1282
tcg/x86_64/tcg-target.h
@@ -65,6 +65,8 @@ enum { @@ -65,6 +65,8 @@ enum {
65 #define TCG_TARGET_HAS_ext8s_i64 65 #define TCG_TARGET_HAS_ext8s_i64
66 #define TCG_TARGET_HAS_ext16s_i64 66 #define TCG_TARGET_HAS_ext16s_i64
67 #define TCG_TARGET_HAS_ext32s_i64 67 #define TCG_TARGET_HAS_ext32s_i64
  68 +#define TCG_TARGET_HAS_rot_i32
  69 +#define TCG_TARGET_HAS_rot_i64
68 70
69 /* Note: must be synced with dyngen-exec.h */ 71 /* Note: must be synced with dyngen-exec.h */
70 #define TCG_AREG0 TCG_REG_R14 72 #define TCG_AREG0 TCG_REG_R14