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