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 */ | ... | ... |