Commit 49bcf33cc7c94655c0a48f8de9b3473d29bb6ed0

Authored by aurel32
1 parent 505ad7c2

target-mips: convert bit shuffle ops to TCG

Bit shuffle operations can be written with very few TCG instructions
(between 5 and 8), so it is worth converting them to TCG.

This code also move all bit shuffle generation code to a separate
function in order to have a cleaner exception code path, that is it
doesn't store back the TCG register to the target register after the
exception, as the TCG register doesn't exist anymore.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5679 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/helper.h
@@ -269,10 +269,3 @@ DEF_HELPER(target_ulong, do_rdhwr_cc, (void)) @@ -269,10 +269,3 @@ DEF_HELPER(target_ulong, do_rdhwr_cc, (void))
269 DEF_HELPER(target_ulong, do_rdhwr_ccres, (void)) 269 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 -  
273 -/* Bit shuffle operations. */  
274 -DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1))  
275 -#ifdef TARGET_MIPS64  
276 -DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1))  
277 -DEF_HELPER(target_ulong, do_dshd, (target_ulong t1))  
278 -#endif  
target-mips/op_helper.c
@@ -1781,25 +1781,6 @@ target_ulong do_rdhwr_ccres(void) @@ -1781,25 +1781,6 @@ target_ulong do_rdhwr_ccres(void)
1781 return 0; 1781 return 0;
1782 } 1782 }
1783 1783
1784 -/* Bit shuffle operations. */  
1785 -target_ulong do_wsbh(target_ulong t1)  
1786 -{  
1787 - return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF));  
1788 -}  
1789 -  
1790 -#if defined(TARGET_MIPS64)  
1791 -target_ulong do_dsbh(target_ulong t1)  
1792 -{  
1793 - return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 0x00FF00FF00FF00FFULL);  
1794 -}  
1795 -  
1796 -target_ulong do_dshd(target_ulong t1)  
1797 -{  
1798 - t1 = ((t1 << 16) & ~0x0000FFFF0000FFFFULL) | ((t1 >> 16) & 0x0000FFFF0000FFFFULL);  
1799 - return (t1 << 32) | (t1 >> 32);  
1800 -}  
1801 -#endif  
1802 -  
1803 void do_pmon (int function) 1784 void do_pmon (int function)
1804 { 1785 {
1805 function /= 2; 1786 function /= 2;
target-mips/translate.c
@@ -2771,6 +2771,60 @@ fail: @@ -2771,6 +2771,60 @@ fail:
2771 tcg_temp_free(t1); 2771 tcg_temp_free(t1);
2772 } 2772 }
2773 2773
  2774 +static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
  2775 +{
  2776 + TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
  2777 + TCGv t1 = tcg_temp_new(TCG_TYPE_TL);
  2778 +
  2779 + gen_load_gpr(t1, rt);
  2780 + switch (op2) {
  2781 + case OPC_WSBH:
  2782 + tcg_gen_shri_tl(t0, t1, 8);
  2783 + tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
  2784 + tcg_gen_shli_tl(t1, t1, 8);
  2785 + tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
  2786 + tcg_gen_or_tl(t0, t0, t1);
  2787 + tcg_gen_ext32s_tl(t0, t0);
  2788 + break;
  2789 + case OPC_SEB:
  2790 + tcg_gen_ext8s_tl(t0, t1);
  2791 + break;
  2792 + case OPC_SEH:
  2793 + tcg_gen_ext16s_tl(t0, t1);
  2794 + break;
  2795 +#if defined(TARGET_MIPS64)
  2796 + case OPC_DSBH:
  2797 + gen_load_gpr(t1, rt);
  2798 + tcg_gen_shri_tl(t0, t1, 8);
  2799 + tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
  2800 + tcg_gen_shli_tl(t1, t1, 8);
  2801 + tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
  2802 + tcg_gen_or_tl(t0, t0, t1);
  2803 + break;
  2804 + case OPC_DSHD:
  2805 + gen_load_gpr(t1, rt);
  2806 + tcg_gen_shri_tl(t0, t1, 16);
  2807 + tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
  2808 + tcg_gen_shli_tl(t1, t1, 16);
  2809 + tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
  2810 + tcg_gen_or_tl(t1, t0, t1);
  2811 + tcg_gen_shri_tl(t0, t1, 32);
  2812 + tcg_gen_shli_tl(t1, t1, 32);
  2813 + tcg_gen_or_tl(t0, t0, t1);
  2814 + break;
  2815 +#endif
  2816 + default:
  2817 + MIPS_INVAL("bsfhl");
  2818 + generate_exception(ctx, EXCP_RI);
  2819 + tcg_temp_free(t0);
  2820 + tcg_temp_free(t1);
  2821 + return;
  2822 + }
  2823 + gen_store_gpr(t0, rd);
  2824 + tcg_temp_free(t0);
  2825 + tcg_temp_free(t1);
  2826 +}
  2827 +
2774 #ifndef CONFIG_USER_ONLY 2828 #ifndef CONFIG_USER_ONLY
2775 /* CP0 (MMU and control) */ 2829 /* CP0 (MMU and control) */
2776 static inline void gen_mfc0_load32 (TCGv t, target_ulong off) 2830 static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
@@ -7953,34 +8007,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -7953,34 +8007,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
7953 case OPC_BSHFL: 8007 case OPC_BSHFL:
7954 check_insn(env, ctx, ISA_MIPS32R2); 8008 check_insn(env, ctx, ISA_MIPS32R2);
7955 op2 = MASK_BSHFL(ctx->opcode); 8009 op2 = MASK_BSHFL(ctx->opcode);
7956 - {  
7957 - TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);  
7958 - TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);  
7959 -  
7960 - switch (op2) {  
7961 - case OPC_WSBH:  
7962 - gen_load_gpr(t1, rt);  
7963 - tcg_gen_helper_1_1(do_wsbh, t0, t1);  
7964 - gen_store_gpr(t0, rd);  
7965 - break;  
7966 - case OPC_SEB:  
7967 - gen_load_gpr(t1, rt);  
7968 - tcg_gen_ext8s_tl(t0, t1);  
7969 - gen_store_gpr(t0, rd);  
7970 - break;  
7971 - case OPC_SEH:  
7972 - gen_load_gpr(t1, rt);  
7973 - tcg_gen_ext16s_tl(t0, t1);  
7974 - gen_store_gpr(t0, rd);  
7975 - break;  
7976 - default: /* Invalid */  
7977 - MIPS_INVAL("bshfl");  
7978 - generate_exception(ctx, EXCP_RI);  
7979 - break;  
7980 - }  
7981 - tcg_temp_free(t0);  
7982 - tcg_temp_free(t1);  
7983 - } 8010 + gen_bshfl(ctx, op2, rt, rd);
7984 break; 8011 break;
7985 case OPC_RDHWR: 8012 case OPC_RDHWR:
7986 check_insn(env, ctx, ISA_MIPS32R2); 8013 check_insn(env, ctx, ISA_MIPS32R2);
@@ -8056,28 +8083,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -8056,28 +8083,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
8056 check_insn(env, ctx, ISA_MIPS64R2); 8083 check_insn(env, ctx, ISA_MIPS64R2);
8057 check_mips_64(ctx); 8084 check_mips_64(ctx);
8058 op2 = MASK_DBSHFL(ctx->opcode); 8085 op2 = MASK_DBSHFL(ctx->opcode);
8059 - {  
8060 - TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);  
8061 - TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);  
8062 -  
8063 - switch (op2) {  
8064 - case OPC_DSBH:  
8065 - gen_load_gpr(t1, rt);  
8066 - tcg_gen_helper_1_1(do_dsbh, t0, t1);  
8067 - break;  
8068 - case OPC_DSHD:  
8069 - gen_load_gpr(t1, rt);  
8070 - tcg_gen_helper_1_1(do_dshd, t0, t1);  
8071 - break;  
8072 - default: /* Invalid */  
8073 - MIPS_INVAL("dbshfl");  
8074 - generate_exception(ctx, EXCP_RI);  
8075 - break;  
8076 - }  
8077 - gen_store_gpr(t0, rd);  
8078 - tcg_temp_free(t0);  
8079 - tcg_temp_free(t1);  
8080 - } 8086 + gen_bshfl(ctx, op2, rt, rd);
8081 break; 8087 break;
8082 #endif 8088 #endif
8083 default: /* Invalid */ 8089 default: /* Invalid */