diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-11 11:47:06 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-11 11:47:06 +0000 |
commit | 49bcf33cc7c94655c0a48f8de9b3473d29bb6ed0 (patch) | |
tree | 94df6bd0899b13b0e9d5cbc00551bf7472ff1d49 /target-mips | |
parent | 505ad7c2ffd1caf82a6789b610bff82b8b6ad472 (diff) | |
download | qemu-49bcf33cc7c94655c0a48f8de9b3473d29bb6ed0.zip qemu-49bcf33cc7c94655c0a48f8de9b3473d29bb6ed0.tar.gz qemu-49bcf33cc7c94655c0a48f8de9b3473d29bb6ed0.tar.bz2 |
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
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/helper.h | 7 | ||||
-rw-r--r-- | target-mips/op_helper.c | 19 | ||||
-rw-r--r-- | target-mips/translate.c | 106 |
3 files changed, 56 insertions, 76 deletions
diff --git a/target-mips/helper.h b/target-mips/helper.h index 5926921..f67c82a 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -269,10 +269,3 @@ DEF_HELPER(target_ulong, do_rdhwr_cc, (void)) DEF_HELPER(target_ulong, do_rdhwr_ccres, (void)) DEF_HELPER(void, do_pmon, (int function)) DEF_HELPER(void, do_wait, (void)) - -/* Bit shuffle operations. */ -DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1)) -#ifdef TARGET_MIPS64 -DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1)) -DEF_HELPER(target_ulong, do_dshd, (target_ulong t1)) -#endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index b642593..3fe62fb 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1781,25 +1781,6 @@ target_ulong do_rdhwr_ccres(void) return 0; } -/* Bit shuffle operations. */ -target_ulong do_wsbh(target_ulong t1) -{ - return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF)); -} - -#if defined(TARGET_MIPS64) -target_ulong do_dsbh(target_ulong t1) -{ - return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 0x00FF00FF00FF00FFULL); -} - -target_ulong do_dshd(target_ulong t1) -{ - t1 = ((t1 << 16) & ~0x0000FFFF0000FFFFULL) | ((t1 >> 16) & 0x0000FFFF0000FFFFULL); - return (t1 << 32) | (t1 >> 32); -} -#endif - void do_pmon (int function) { function /= 2; diff --git a/target-mips/translate.c b/target-mips/translate.c index 00122f1..f637d2b 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2771,6 +2771,60 @@ fail: tcg_temp_free(t1); } +static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd) +{ + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); + + gen_load_gpr(t1, rt); + switch (op2) { + case OPC_WSBH: + tcg_gen_shri_tl(t0, t1, 8); + tcg_gen_andi_tl(t0, t0, 0x00FF00FF); + tcg_gen_shli_tl(t1, t1, 8); + tcg_gen_andi_tl(t1, t1, ~0x00FF00FF); + tcg_gen_or_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); + break; + case OPC_SEB: + tcg_gen_ext8s_tl(t0, t1); + break; + case OPC_SEH: + tcg_gen_ext16s_tl(t0, t1); + break; +#if defined(TARGET_MIPS64) + case OPC_DSBH: + gen_load_gpr(t1, rt); + tcg_gen_shri_tl(t0, t1, 8); + tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL); + tcg_gen_shli_tl(t1, t1, 8); + tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL); + tcg_gen_or_tl(t0, t0, t1); + break; + case OPC_DSHD: + gen_load_gpr(t1, rt); + tcg_gen_shri_tl(t0, t1, 16); + tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL); + tcg_gen_shli_tl(t1, t1, 16); + tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL); + tcg_gen_or_tl(t1, t0, t1); + tcg_gen_shri_tl(t0, t1, 32); + tcg_gen_shli_tl(t1, t1, 32); + tcg_gen_or_tl(t0, t0, t1); + break; +#endif + default: + MIPS_INVAL("bsfhl"); + generate_exception(ctx, EXCP_RI); + tcg_temp_free(t0); + tcg_temp_free(t1); + return; + } + gen_store_gpr(t0, rd); + tcg_temp_free(t0); + tcg_temp_free(t1); +} + #ifndef CONFIG_USER_ONLY /* CP0 (MMU and control) */ static inline void gen_mfc0_load32 (TCGv t, target_ulong off) @@ -7953,34 +8007,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_BSHFL: check_insn(env, ctx, ISA_MIPS32R2); op2 = MASK_BSHFL(ctx->opcode); - { - TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); - - switch (op2) { - case OPC_WSBH: - gen_load_gpr(t1, rt); - tcg_gen_helper_1_1(do_wsbh, t0, t1); - gen_store_gpr(t0, rd); - break; - case OPC_SEB: - gen_load_gpr(t1, rt); - tcg_gen_ext8s_tl(t0, t1); - gen_store_gpr(t0, rd); - break; - case OPC_SEH: - gen_load_gpr(t1, rt); - tcg_gen_ext16s_tl(t0, t1); - gen_store_gpr(t0, rd); - break; - default: /* Invalid */ - MIPS_INVAL("bshfl"); - generate_exception(ctx, EXCP_RI); - break; - } - tcg_temp_free(t0); - tcg_temp_free(t1); - } + gen_bshfl(ctx, op2, rt, rd); break; case OPC_RDHWR: check_insn(env, ctx, ISA_MIPS32R2); @@ -8056,28 +8083,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) check_insn(env, ctx, ISA_MIPS64R2); check_mips_64(ctx); op2 = MASK_DBSHFL(ctx->opcode); - { - TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); - - switch (op2) { - case OPC_DSBH: - gen_load_gpr(t1, rt); - tcg_gen_helper_1_1(do_dsbh, t0, t1); - break; - case OPC_DSHD: - gen_load_gpr(t1, rt); - tcg_gen_helper_1_1(do_dshd, t0, t1); - break; - default: /* Invalid */ - MIPS_INVAL("dbshfl"); - generate_exception(ctx, EXCP_RI); - break; - } - gen_store_gpr(t0, rd); - tcg_temp_free(t0); - tcg_temp_free(t1); - } + gen_bshfl(ctx, op2, rt, rd); break; #endif default: /* Invalid */ |