Commit 505ad7c2ffd1caf82a6789b610bff82b8b6ad472

Authored by aurel32
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
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:
... ...