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