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