Commit 505ad7c2ffd1caf82a6789b610bff82b8b6ad472
1 parent
2623c1ec
target-mips: convert bitfield ops to TCG
Bitfield operations can be written with very few TCG instructions (between 2 and 5), so it is worth converting them to TCG. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5678 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
41 additions
and
46 deletions
target-mips/helper.h
| ... | ... | @@ -270,13 +270,9 @@ DEF_HELPER(target_ulong, do_rdhwr_ccres, (void)) |
| 270 | 270 | DEF_HELPER(void, do_pmon, (int function)) |
| 271 | 271 | DEF_HELPER(void, do_wait, (void)) |
| 272 | 272 | |
| 273 | -/* Bitfield operations. */ | |
| 274 | -DEF_HELPER(target_ulong, do_ext, (target_ulong t1, uint32_t pos, uint32_t size)) | |
| 275 | -DEF_HELPER(target_ulong, do_ins, (target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size)) | |
| 273 | +/* Bit shuffle operations. */ | |
| 276 | 274 | DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1)) |
| 277 | 275 | #ifdef TARGET_MIPS64 |
| 278 | -DEF_HELPER(target_ulong, do_dext, (target_ulong t1, uint32_t pos, uint32_t size)) | |
| 279 | -DEF_HELPER(target_ulong, do_dins, (target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size)) | |
| 280 | 276 | DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1)) |
| 281 | 277 | DEF_HELPER(target_ulong, do_dshd, (target_ulong t1)) |
| 282 | 278 | #endif | ... | ... |
target-mips/op_helper.c
| ... | ... | @@ -1781,37 +1781,13 @@ target_ulong do_rdhwr_ccres(void) |
| 1781 | 1781 | return 0; |
| 1782 | 1782 | } |
| 1783 | 1783 | |
| 1784 | -/* Bitfield operations. */ | |
| 1785 | -target_ulong do_ext(target_ulong t1, uint32_t pos, uint32_t size) | |
| 1786 | -{ | |
| 1787 | - return (int32_t)((t1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0)); | |
| 1788 | -} | |
| 1789 | - | |
| 1790 | -target_ulong do_ins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) | |
| 1791 | -{ | |
| 1792 | - target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos; | |
| 1793 | - | |
| 1794 | - return (int32_t)((t0 & ~mask) | ((t1 << pos) & mask)); | |
| 1795 | -} | |
| 1796 | - | |
| 1784 | +/* Bit shuffle operations. */ | |
| 1797 | 1785 | target_ulong do_wsbh(target_ulong t1) |
| 1798 | 1786 | { |
| 1799 | 1787 | return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF)); |
| 1800 | 1788 | } |
| 1801 | 1789 | |
| 1802 | 1790 | #if defined(TARGET_MIPS64) |
| 1803 | -target_ulong do_dext(target_ulong t1, uint32_t pos, uint32_t size) | |
| 1804 | -{ | |
| 1805 | - return (t1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL); | |
| 1806 | -} | |
| 1807 | - | |
| 1808 | -target_ulong do_dins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) | |
| 1809 | -{ | |
| 1810 | - target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos; | |
| 1811 | - | |
| 1812 | - return (t0 & ~mask) | ((t1 << pos) & mask); | |
| 1813 | -} | |
| 1814 | - | |
| 1815 | 1791 | target_ulong do_dsbh(target_ulong t1) |
| 1816 | 1792 | { |
| 1817 | 1793 | return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 0x00FF00FF00FF00FFULL); | ... | ... |
target-mips/translate.c
| ... | ... | @@ -2682,57 +2682,80 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, |
| 2682 | 2682 | static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, |
| 2683 | 2683 | int rs, int lsb, int msb) |
| 2684 | 2684 | { |
| 2685 | - TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 2686 | - TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 2685 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 2686 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 2687 | + target_ulong mask; | |
| 2687 | 2688 | |
| 2688 | 2689 | gen_load_gpr(t1, rs); |
| 2689 | 2690 | switch (opc) { |
| 2690 | 2691 | case OPC_EXT: |
| 2691 | 2692 | if (lsb + msb > 31) |
| 2692 | 2693 | goto fail; |
| 2693 | - tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1); | |
| 2694 | + tcg_gen_shri_tl(t0, t1, lsb); | |
| 2695 | + if (msb != 31) { | |
| 2696 | + tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1); | |
| 2697 | + } else { | |
| 2698 | + tcg_gen_ext32s_tl(t0, t0); | |
| 2699 | + } | |
| 2694 | 2700 | break; |
| 2695 | 2701 | #if defined(TARGET_MIPS64) |
| 2696 | 2702 | case OPC_DEXTM: |
| 2697 | - if (lsb + msb > 63) | |
| 2698 | - goto fail; | |
| 2699 | - tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32); | |
| 2703 | + tcg_gen_shri_tl(t0, t1, lsb); | |
| 2704 | + if (msb != 31) { | |
| 2705 | + tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1); | |
| 2706 | + } | |
| 2700 | 2707 | break; |
| 2701 | 2708 | case OPC_DEXTU: |
| 2702 | - if (lsb + msb > 63) | |
| 2703 | - goto fail; | |
| 2704 | - tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1); | |
| 2709 | + tcg_gen_shri_tl(t0, t1, lsb + 32); | |
| 2710 | + tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); | |
| 2705 | 2711 | break; |
| 2706 | 2712 | case OPC_DEXT: |
| 2707 | - if (lsb + msb > 63) | |
| 2708 | - goto fail; | |
| 2709 | - tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1); | |
| 2713 | + tcg_gen_shri_tl(t0, t1, lsb); | |
| 2714 | + tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); | |
| 2710 | 2715 | break; |
| 2711 | 2716 | #endif |
| 2712 | 2717 | case OPC_INS: |
| 2713 | 2718 | if (lsb > msb) |
| 2714 | 2719 | goto fail; |
| 2720 | + mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb; | |
| 2715 | 2721 | gen_load_gpr(t0, rt); |
| 2716 | - tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1); | |
| 2722 | + tcg_gen_andi_tl(t0, t0, ~mask); | |
| 2723 | + tcg_gen_shli_tl(t1, t1, lsb); | |
| 2724 | + tcg_gen_andi_tl(t1, t1, mask); | |
| 2725 | + tcg_gen_or_tl(t0, t0, t1); | |
| 2726 | + tcg_gen_ext32s_tl(t0, t0); | |
| 2717 | 2727 | break; |
| 2718 | 2728 | #if defined(TARGET_MIPS64) |
| 2719 | 2729 | case OPC_DINSM: |
| 2720 | 2730 | if (lsb > msb) |
| 2721 | 2731 | goto fail; |
| 2732 | + mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb; | |
| 2722 | 2733 | gen_load_gpr(t0, rt); |
| 2723 | - tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32); | |
| 2734 | + tcg_gen_andi_tl(t0, t0, ~mask); | |
| 2735 | + tcg_gen_shli_tl(t1, t1, lsb); | |
| 2736 | + tcg_gen_andi_tl(t1, t1, mask); | |
| 2737 | + tcg_gen_or_tl(t0, t0, t1); | |
| 2724 | 2738 | break; |
| 2725 | 2739 | case OPC_DINSU: |
| 2726 | 2740 | if (lsb > msb) |
| 2727 | 2741 | goto fail; |
| 2742 | + mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb; | |
| 2728 | 2743 | gen_load_gpr(t0, rt); |
| 2729 | - tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1); | |
| 2744 | + tcg_gen_andi_tl(t0, t0, ~mask); | |
| 2745 | + tcg_gen_shli_tl(t1, t1, lsb + 32); | |
| 2746 | + tcg_gen_andi_tl(t1, t1, mask); | |
| 2747 | + tcg_gen_or_tl(t0, t0, t1); | |
| 2730 | 2748 | break; |
| 2731 | 2749 | case OPC_DINS: |
| 2732 | 2750 | if (lsb > msb) |
| 2733 | 2751 | goto fail; |
| 2734 | 2752 | gen_load_gpr(t0, rt); |
| 2735 | - tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1); | |
| 2753 | + mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb; | |
| 2754 | + gen_load_gpr(t0, rt); | |
| 2755 | + tcg_gen_andi_tl(t0, t0, ~mask); | |
| 2756 | + tcg_gen_shli_tl(t1, t1, lsb); | |
| 2757 | + tcg_gen_andi_tl(t1, t1, mask); | |
| 2758 | + tcg_gen_or_tl(t0, t0, t1); | |
| 2736 | 2759 | break; |
| 2737 | 2760 | #endif |
| 2738 | 2761 | default: | ... | ... |