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 | ... | ... |