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 | 269 | 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 | - | |
| 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 | 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 | 1784 | void do_pmon (int function) |
| 1804 | 1785 | { |
| 1805 | 1786 | function /= 2; | ... | ... |
target-mips/translate.c
| ... | ... | @@ -2771,6 +2771,60 @@ fail: |
| 2771 | 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 | 2828 | #ifndef CONFIG_USER_ONLY |
| 2775 | 2829 | /* CP0 (MMU and control) */ |
| 2776 | 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 | 8007 | case OPC_BSHFL: |
| 7954 | 8008 | check_insn(env, ctx, ISA_MIPS32R2); |
| 7955 | 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 | 8011 | break; |
| 7985 | 8012 | case OPC_RDHWR: |
| 7986 | 8013 | check_insn(env, ctx, ISA_MIPS32R2); |
| ... | ... | @@ -8056,28 +8083,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 8056 | 8083 | check_insn(env, ctx, ISA_MIPS64R2); |
| 8057 | 8084 | check_mips_64(ctx); |
| 8058 | 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 | 8087 | break; |
| 8082 | 8088 | #endif |
| 8083 | 8089 | default: /* Invalid */ | ... | ... |