target-mips: convert bitfield ops to TCG
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 <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5678 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2623c1ecfc
commit
505ad7c2ff
@ -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
|
||||
|
@ -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);
|
||||
|
@ -2682,57 +2682,80 @@ 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 != 31) {
|
||||
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 != 31) {
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user