Commit 49bcf33cc7c94655c0a48f8de9b3473d29bb6ed0
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
Showing
3 changed files
with
56 additions
and
76 deletions
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 */ |