Commit 158245714ecbd9263bfe34ad47089fcc1fa34f82
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,7 +225,7 @@ t0=~(t1|t2) | ||
225 | 225 | ||
226 | t0=t1|~t2 | 226 | t0=t1|~t2 |
227 | 227 | ||
228 | -********* Shifts | 228 | +********* Shifts/Rotates |
229 | 229 | ||
230 | * shl_i32/i64 t0, t1, t2 | 230 | * shl_i32/i64 t0, t1, t2 |
231 | 231 | ||
@@ -239,6 +239,14 @@ t0=t1 >> t2 (unsigned). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) | @@ -239,6 +239,14 @@ t0=t1 >> t2 (unsigned). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) | ||
239 | 239 | ||
240 | t0=t1 >> t2 (signed). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) | 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 | ********* Misc | 250 | ********* Misc |
243 | 251 | ||
244 | * mov_i32/i64 t0, t1 | 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,6 +1518,116 @@ static inline void tcg_gen_orc_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
1518 | tcg_temp_free(t0); | 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 | /* QEMU specific operations. Their type depend on the QEMU CPU | 1632 | /* QEMU specific operations. Their type depend on the QEMU CPU |
1523 | type. */ | 1633 | type. */ |
@@ -1777,6 +1887,10 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index) | @@ -1777,6 +1887,10 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index) | ||
1777 | #define tcg_gen_nand_tl tcg_gen_nand_i64 | 1887 | #define tcg_gen_nand_tl tcg_gen_nand_i64 |
1778 | #define tcg_gen_nor_tl tcg_gen_nor_i64 | 1888 | #define tcg_gen_nor_tl tcg_gen_nor_i64 |
1779 | #define tcg_gen_orc_tl tcg_gen_orc_i64 | 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 | #define tcg_const_tl tcg_const_i64 | 1894 | #define tcg_const_tl tcg_const_i64 |
1781 | #define tcg_const_local_tl tcg_const_local_i64 | 1895 | #define tcg_const_local_tl tcg_const_local_i64 |
1782 | #else | 1896 | #else |
@@ -1836,6 +1950,10 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index) | @@ -1836,6 +1950,10 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index) | ||
1836 | #define tcg_gen_nand_tl tcg_gen_nand_i32 | 1950 | #define tcg_gen_nand_tl tcg_gen_nand_i32 |
1837 | #define tcg_gen_nor_tl tcg_gen_nor_i32 | 1951 | #define tcg_gen_nor_tl tcg_gen_nor_i32 |
1838 | #define tcg_gen_orc_tl tcg_gen_orc_i32 | 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 | #define tcg_const_tl tcg_const_i32 | 1957 | #define tcg_const_tl tcg_const_i32 |
1840 | #define tcg_const_local_tl tcg_const_local_i32 | 1958 | #define tcg_const_local_tl tcg_const_local_i32 |
1841 | #endif | 1959 | #endif |