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,13 +270,9 @@ DEF_HELPER(target_ulong, do_rdhwr_ccres, (void)) | ||
| 270 | DEF_HELPER(void, do_pmon, (int function)) | 270 | DEF_HELPER(void, do_pmon, (int function)) |
| 271 | DEF_HELPER(void, do_wait, (void)) | 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 | DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1)) | 274 | DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1)) |
| 277 | #ifdef TARGET_MIPS64 | 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 | DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1)) | 276 | DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1)) |
| 281 | DEF_HELPER(target_ulong, do_dshd, (target_ulong t1)) | 277 | DEF_HELPER(target_ulong, do_dshd, (target_ulong t1)) |
| 282 | #endif | 278 | #endif |
target-mips/op_helper.c
| @@ -1781,37 +1781,13 @@ target_ulong do_rdhwr_ccres(void) | @@ -1781,37 +1781,13 @@ target_ulong do_rdhwr_ccres(void) | ||
| 1781 | return 0; | 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 | target_ulong do_wsbh(target_ulong t1) | 1785 | target_ulong do_wsbh(target_ulong t1) |
| 1798 | { | 1786 | { |
| 1799 | return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF)); | 1787 | return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF)); |
| 1800 | } | 1788 | } |
| 1801 | 1789 | ||
| 1802 | #if defined(TARGET_MIPS64) | 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 | target_ulong do_dsbh(target_ulong t1) | 1791 | target_ulong do_dsbh(target_ulong t1) |
| 1816 | { | 1792 | { |
| 1817 | return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 0x00FF00FF00FF00FFULL); | 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,57 +2682,80 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | ||
| 2682 | static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, | 2682 | static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, |
| 2683 | int rs, int lsb, int msb) | 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 | gen_load_gpr(t1, rs); | 2689 | gen_load_gpr(t1, rs); |
| 2689 | switch (opc) { | 2690 | switch (opc) { |
| 2690 | case OPC_EXT: | 2691 | case OPC_EXT: |
| 2691 | if (lsb + msb > 31) | 2692 | if (lsb + msb > 31) |
| 2692 | goto fail; | 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 | break; | 2700 | break; |
| 2695 | #if defined(TARGET_MIPS64) | 2701 | #if defined(TARGET_MIPS64) |
| 2696 | case OPC_DEXTM: | 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 | break; | 2707 | break; |
| 2701 | case OPC_DEXTU: | 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 | break; | 2711 | break; |
| 2706 | case OPC_DEXT: | 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 | break; | 2715 | break; |
| 2711 | #endif | 2716 | #endif |
| 2712 | case OPC_INS: | 2717 | case OPC_INS: |
| 2713 | if (lsb > msb) | 2718 | if (lsb > msb) |
| 2714 | goto fail; | 2719 | goto fail; |
| 2720 | + mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb; | ||
| 2715 | gen_load_gpr(t0, rt); | 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 | break; | 2727 | break; |
| 2718 | #if defined(TARGET_MIPS64) | 2728 | #if defined(TARGET_MIPS64) |
| 2719 | case OPC_DINSM: | 2729 | case OPC_DINSM: |
| 2720 | if (lsb > msb) | 2730 | if (lsb > msb) |
| 2721 | goto fail; | 2731 | goto fail; |
| 2732 | + mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb; | ||
| 2722 | gen_load_gpr(t0, rt); | 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 | break; | 2738 | break; |
| 2725 | case OPC_DINSU: | 2739 | case OPC_DINSU: |
| 2726 | if (lsb > msb) | 2740 | if (lsb > msb) |
| 2727 | goto fail; | 2741 | goto fail; |
| 2742 | + mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb; | ||
| 2728 | gen_load_gpr(t0, rt); | 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 | break; | 2748 | break; |
| 2731 | case OPC_DINS: | 2749 | case OPC_DINS: |
| 2732 | if (lsb > msb) | 2750 | if (lsb > msb) |
| 2733 | goto fail; | 2751 | goto fail; |
| 2734 | gen_load_gpr(t0, rt); | 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 | break; | 2759 | break; |
| 2737 | #endif | 2760 | #endif |
| 2738 | default: | 2761 | default: |