[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 04/11] target-mips: convert bitfield ops to TCG
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH 04/11] target-mips: convert bitfield ops to TCG |
Date: |
Sat, 8 Nov 2008 09:34:16 +0100 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
Bitfield operations can be written with very few TCG instructions
(between 2 and 5), so it is worth converting them to TCG.
Signed-off-by: Aurelien Jarno <address@hidden>
---
target-mips/helper.h | 6 +----
target-mips/op_helper.c | 26 +------------------------
target-mips/translate.c | 49 +++++++++++++++++++++++++++++++++++++---------
3 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 525ccbb..5926921 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -270,13 +270,9 @@ DEF_HELPER(target_ulong, do_rdhwr_ccres, (void))
DEF_HELPER(void, do_pmon, (int function))
DEF_HELPER(void, do_wait, (void))
-/* Bitfield operations. */
-DEF_HELPER(target_ulong, do_ext, (target_ulong t1, uint32_t pos, uint32_t
size))
-DEF_HELPER(target_ulong, do_ins, (target_ulong t0, target_ulong t1, uint32_t
pos, uint32_t size))
+/* Bit shuffle operations. */
DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1))
#ifdef TARGET_MIPS64
-DEF_HELPER(target_ulong, do_dext, (target_ulong t1, uint32_t pos, uint32_t
size))
-DEF_HELPER(target_ulong, do_dins, (target_ulong t0, target_ulong t1, uint32_t
pos, uint32_t size))
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 3744728..b642593 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1781,37 +1781,13 @@ target_ulong do_rdhwr_ccres(void)
return 0;
}
-/* Bitfield operations. */
-target_ulong do_ext(target_ulong t1, uint32_t pos, uint32_t size)
-{
- return (int32_t)((t1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
-}
-
-target_ulong do_ins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t
size)
-{
- target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
-
- return (int32_t)((t0 & ~mask) | ((t1 << pos) & mask));
-}
-
+/* 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_dext(target_ulong t1, uint32_t pos, uint32_t size)
-{
- return (t1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
-}
-
-target_ulong do_dins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t
size)
-{
- target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
-
- return (t0 & ~mask) | ((t1 << pos) & mask);
-}
-
target_ulong do_dsbh(target_ulong t1)
{
return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) &
0x00FF00FF00FF00FFULL);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index af01f73..2cd1868 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2682,57 +2682,86 @@ static void gen_compute_branch (DisasContext *ctx,
uint32_t opc,
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
int rs, int lsb, int msb)
{
- TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
- TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+ TCGv t1 = tcg_temp_new(TCG_TYPE_TL);
+ target_ulong mask;
gen_load_gpr(t1, rs);
switch (opc) {
case OPC_EXT:
if (lsb + msb > 31)
goto fail;
- tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1);
+ tcg_gen_shri_tl(t0, t1, lsb);
+ if (msb + 1 < 32) {
+ tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
+ } else {
+ tcg_gen_ext32s_tl(t0, t0);
+ }
break;
#if defined(TARGET_MIPS64)
case OPC_DEXTM:
if (lsb + msb > 63)
goto fail;
- tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32);
+ tcg_gen_shri_tl(t0, t1, lsb);
+ if (msb + 1 + 32 < 64) {
+ tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
+ }
break;
case OPC_DEXTU:
if (lsb + msb > 63)
goto fail;
- tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1);
+ tcg_gen_shri_tl(t0, t1, lsb + 32);
+ tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
break;
case OPC_DEXT:
if (lsb + msb > 63)
goto fail;
- tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1);
+ tcg_gen_shri_tl(t0, t1, lsb);
+ tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
break;
#endif
case OPC_INS:
if (lsb > msb)
goto fail;
+ mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) <<
lsb;
gen_load_gpr(t0, rt);
- tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
+ tcg_gen_andi_tl(t0, t0, ~mask);
+ tcg_gen_shli_tl(t1, t1, lsb);
+ tcg_gen_andi_tl(t1, t1, mask);
+ tcg_gen_or_tl(t0, t0, t1);
+ tcg_gen_ext32s_tl(t0, t0);
break;
#if defined(TARGET_MIPS64)
case OPC_DINSM:
if (lsb > msb)
goto fail;
+ mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) -
1) : ~0ULL) << lsb;
gen_load_gpr(t0, rt);
- tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
+ tcg_gen_andi_tl(t0, t0, ~mask);
+ tcg_gen_shli_tl(t1, t1, lsb);
+ tcg_gen_andi_tl(t1, t1, mask);
+ tcg_gen_or_tl(t0, t0, t1);
break;
case OPC_DINSU:
if (lsb > msb)
goto fail;
+ mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
gen_load_gpr(t0, rt);
- tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
+ tcg_gen_andi_tl(t0, t0, ~mask);
+ tcg_gen_shli_tl(t1, t1, lsb + 32);
+ tcg_gen_andi_tl(t1, t1, mask);
+ tcg_gen_or_tl(t0, t0, t1);
break;
case OPC_DINS:
if (lsb > msb)
goto fail;
gen_load_gpr(t0, rt);
- tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
+ mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
+ gen_load_gpr(t0, rt);
+ tcg_gen_andi_tl(t0, t0, ~mask);
+ tcg_gen_shli_tl(t1, t1, lsb);
+ tcg_gen_andi_tl(t1, t1, mask);
+ tcg_gen_or_tl(t0, t0, t1);
break;
#endif
default:
--
1.5.6.5
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' address@hidden | address@hidden
`- people.debian.org/~aurel32 | www.aurel32.net
- [Qemu-devel] [PATCH 0/11] target-mips: optimizations, Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 01/11] target-mips: optimize gen_save_pc(), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 02/11] target-mips: optimize gen_op_addr_add() (1/2), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 03/11] target-mips: optimize gen_op_addr_add() (2/2), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 04/11] target-mips: convert bitfield ops to TCG,
Aurelien Jarno <=
- [Qemu-devel] [PATCH 05/11] target-mips: convert bit shuffle ops to TCG, Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 06/11] target-mips: optimize gen_arith()/gen_arith_imm(), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 07/11] target-mips: optimize gen_muldiv(), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 08/11] target-mips: optimize gen_farith(), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 09/11] target-mips: optimize movc*(), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 10/11] target-mips: gen_compute_branch1(), Aurelien Jarno, 2008/11/08
- [Qemu-devel] [PATCH 11/11] target-mips: fix temporary variable freeing in op_ldst_##insn(), Aurelien Jarno, 2008/11/08