Commit 158245714ecbd9263bfe34ad47089fcc1fa34f82

Authored by aurel32
1 parent f02bb954

tcg-ops.h: add rotl/rotli and rotr/rotri TCG instructions

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

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5607 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 127 additions and 1 deletions
tcg/README
... ... @@ -225,7 +225,7 @@ t0=~(t1|t2)
225 225  
226 226 t0=t1|~t2
227 227  
228   -********* Shifts
  228 +********* Shifts/Rotates
229 229  
230 230 * shl_i32/i64 t0, t1, t2
231 231  
... ... @@ -239,6 +239,14 @@ t0=t1 &gt;&gt; t2 (unsigned). Undefined behavior if t2 &lt; 0 or t2 &gt;= 32 (resp 64)
239 239  
240 240 t0=t1 >> t2 (signed). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
241 241  
  242 +* rotl_i32/i64 t0, t1, t2
  243 +
  244 +Rotation of t2 bits to the left. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
  245 +
  246 +* rotr_i32/i64 t0, t1, t2
  247 +
  248 +Rotation of t2 bits to the right. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
  249 +
242 250 ********* Misc
243 251  
244 252 * mov_i32/i64 t0, t1
... ...
tcg/tcg-op.h
... ... @@ -1518,6 +1518,116 @@ static inline void tcg_gen_orc_i64(TCGv ret, TCGv arg1, TCGv arg2)
1518 1518 tcg_temp_free(t0);
1519 1519 }
1520 1520  
  1521 +static inline void tcg_gen_rotl_i32(TCGv ret, TCGv arg1, TCGv arg2)
  1522 +{
  1523 + TCGv t0, t1;
  1524 +
  1525 + t0 = tcg_temp_new(TCG_TYPE_I32);
  1526 + t1 = tcg_temp_new(TCG_TYPE_I32);
  1527 + tcg_gen_shl_i32(t0, arg1, arg2);
  1528 + tcg_gen_subfi_i32(t1, 32, arg2);
  1529 + tcg_gen_shr_i32(t1, arg1, t1);
  1530 + tcg_gen_or_i32(ret, t0, t1);
  1531 + tcg_temp_free(t0);
  1532 + tcg_temp_free(t1);
  1533 +}
  1534 +
  1535 +static inline void tcg_gen_rotl_i64(TCGv ret, TCGv arg1, TCGv arg2)
  1536 +{
  1537 + TCGv t0, t1;
  1538 +
  1539 + t0 = tcg_temp_new(TCG_TYPE_I64);
  1540 + t1 = tcg_temp_new(TCG_TYPE_I64);
  1541 + tcg_gen_shl_i64(t0, arg1, arg2);
  1542 + tcg_gen_subfi_i64(t1, 64, arg2);
  1543 + tcg_gen_shr_i64(t1, arg1, t1);
  1544 + tcg_gen_or_i64(ret, t0, t1);
  1545 + tcg_temp_free(t0);
  1546 + tcg_temp_free(t1);
  1547 +}
  1548 +
  1549 +static inline void tcg_gen_rotli_i32(TCGv ret, TCGv arg1, int32_t arg2)
  1550 +{
  1551 + /* some cases can be optimized here */
  1552 + if (arg2 == 0) {
  1553 + tcg_gen_mov_i32(ret, arg1);
  1554 + } else {
  1555 + TCGv t0, t1;
  1556 + t0 = tcg_temp_new(TCG_TYPE_I32);
  1557 + t1 = tcg_temp_new(TCG_TYPE_I32);
  1558 + tcg_gen_shli_i32(t0, arg1, arg2);
  1559 + tcg_gen_shri_i32(t1, arg1, 32 - arg2);
  1560 + tcg_gen_or_i32(ret, t0, t1);
  1561 + tcg_temp_free(t0);
  1562 + tcg_temp_free(t1);
  1563 + }
  1564 +}
  1565 +
  1566 +static inline void tcg_gen_rotli_i64(TCGv ret, TCGv arg1, int64_t arg2)
  1567 +{
  1568 + /* some cases can be optimized here */
  1569 + if (arg2 == 0) {
  1570 + tcg_gen_mov_i64(ret, arg1);
  1571 + } else {
  1572 + TCGv t0, t1;
  1573 + t0 = tcg_temp_new(TCG_TYPE_I64);
  1574 + t1 = tcg_temp_new(TCG_TYPE_I64);
  1575 + tcg_gen_shli_i64(t0, arg1, arg2);
  1576 + tcg_gen_shri_i64(t1, arg1, 64 - arg2);
  1577 + tcg_gen_or_i64(ret, t0, t1);
  1578 + tcg_temp_free(t0);
  1579 + tcg_temp_free(t1);
  1580 + }
  1581 +}
  1582 +
  1583 +static inline void tcg_gen_rotr_i32(TCGv ret, TCGv arg1, TCGv arg2)
  1584 +{
  1585 + TCGv t0, t1;
  1586 +
  1587 + t0 = tcg_temp_new(TCG_TYPE_I32);
  1588 + t1 = tcg_temp_new(TCG_TYPE_I32);
  1589 + tcg_gen_shr_i32(t0, arg1, arg2);
  1590 + tcg_gen_subfi_i32(t1, 32, arg2);
  1591 + tcg_gen_shl_i32(t1, arg1, t1);
  1592 + tcg_gen_or_i32(ret, t0, t1);
  1593 + tcg_temp_free(t0);
  1594 + tcg_temp_free(t1);
  1595 +}
  1596 +
  1597 +static inline void tcg_gen_rotr_i64(TCGv ret, TCGv arg1, TCGv arg2)
  1598 +{
  1599 + TCGv t0, t1;
  1600 +
  1601 + t0 = tcg_temp_new(TCG_TYPE_I64);
  1602 + t1 = tcg_temp_new(TCG_TYPE_I64);
  1603 + tcg_gen_shl_i64(t0, arg1, arg2);
  1604 + tcg_gen_subfi_i64(t1, 64, arg2);
  1605 + tcg_gen_shl_i64(t1, arg1, t1);
  1606 + tcg_gen_or_i64(ret, t0, t1);
  1607 + tcg_temp_free(t0);
  1608 + tcg_temp_free(t1);
  1609 +}
  1610 +
  1611 +static inline void tcg_gen_rotri_i32(TCGv ret, TCGv arg1, int32_t arg2)
  1612 +{
  1613 + /* some cases can be optimized here */
  1614 + if (arg2 == 0) {
  1615 + tcg_gen_mov_i32(ret, arg1);
  1616 + } else {
  1617 + tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
  1618 + }
  1619 +}
  1620 +
  1621 +static inline void tcg_gen_rotri_i64(TCGv ret, TCGv arg1, int64_t arg2)
  1622 +{
  1623 + /* some cases can be optimized here */
  1624 + if (arg2 == 0) {
  1625 + tcg_gen_mov_i32(ret, arg1);
  1626 + } else {
  1627 + tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
  1628 + }
  1629 +}
  1630 +
1521 1631 /***************************************/
1522 1632 /* QEMU specific operations. Their type depend on the QEMU CPU
1523 1633 type. */
... ... @@ -1777,6 +1887,10 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
1777 1887 #define tcg_gen_nand_tl tcg_gen_nand_i64
1778 1888 #define tcg_gen_nor_tl tcg_gen_nor_i64
1779 1889 #define tcg_gen_orc_tl tcg_gen_orc_i64
  1890 +#define tcg_gen_rotl_tl tcg_gen_rotl_i64
  1891 +#define tcg_gen_rotli_tl tcg_gen_rotli_i64
  1892 +#define tcg_gen_rotr_tl tcg_gen_rotr_i64
  1893 +#define tcg_gen_rotri_tl tcg_gen_rotri_i64
1780 1894 #define tcg_const_tl tcg_const_i64
1781 1895 #define tcg_const_local_tl tcg_const_local_i64
1782 1896 #else
... ... @@ -1836,6 +1950,10 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
1836 1950 #define tcg_gen_nand_tl tcg_gen_nand_i32
1837 1951 #define tcg_gen_nor_tl tcg_gen_nor_i32
1838 1952 #define tcg_gen_orc_tl tcg_gen_orc_i32
  1953 +#define tcg_gen_rotl_tl tcg_gen_rotl_i32
  1954 +#define tcg_gen_rotli_tl tcg_gen_rotli_i32
  1955 +#define tcg_gen_rotr_tl tcg_gen_rotr_i32
  1956 +#define tcg_gen_rotri_tl tcg_gen_rotri_i32
1839 1957 #define tcg_const_tl tcg_const_i32
1840 1958 #define tcg_const_local_tl tcg_const_local_i32
1841 1959 #endif
... ...