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 | 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 >> t2 (unsigned). Undefined behavior if t2 < 0 or t2 >= 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 | ... | ... |