diff options
author | Richard Henderson <rth@twiddle.net> | 2013-01-21 11:52:26 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-02-19 23:05:18 -0800 |
commit | f1300734cbca515d30953b2c87e259fa378ea301 (patch) | |
tree | e61083d1d2fc5eb5e7fe1eda95973e3f16231c58 | |
parent | cd7f97cafdd80d6bd4950ccfdcd9acb7850184b2 (diff) | |
download | qemu-f1300734cbca515d30953b2c87e259fa378ea301.tar.gz qemu-f1300734cbca515d30953b2c87e259fa378ea301.tar.bz2 qemu-f1300734cbca515d30953b2c87e259fa378ea301.zip |
target-i386: Use clz/ctz for bsf/bsr helpers
And mark the helpers as NO_RWG_SE.
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | target-i386/helper.h | 6 | ||||
-rw-r--r-- | target-i386/int_helper.c | 45 |
2 files changed, 14 insertions, 37 deletions
diff --git a/target-i386/helper.h b/target-i386/helper.h index 81e0fbdd6d..e1ecdb81e9 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -195,9 +195,9 @@ DEF_HELPER_3(frstor, void, env, tl, int) DEF_HELPER_3(fxsave, void, env, tl, int) DEF_HELPER_3(fxrstor, void, env, tl, int) -DEF_HELPER_1(bsf, tl, tl) -DEF_HELPER_1(bsr, tl, tl) -DEF_HELPER_2(lzcnt, tl, tl, int) +DEF_HELPER_FLAGS_1(bsf, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(bsr, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_2(lzcnt, TCG_CALL_NO_RWG_SE, tl, tl, int) DEF_HELPER_FLAGS_2(pdep, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_FLAGS_2(pext, TCG_CALL_NO_RWG_SE, tl, tl, tl) diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c index 527af40281..7bec4ebdd6 100644 --- a/target-i386/int_helper.c +++ b/target-i386/int_helper.c @@ -447,53 +447,30 @@ void helper_idivq_EAX(CPUX86State *env, target_ulong t0) } #endif +#if TARGET_LONG_BITS == 32 +# define ctztl ctz32 +# define clztl clz32 +#else +# define ctztl ctz64 +# define clztl clz64 +#endif + /* bit operations */ target_ulong helper_bsf(target_ulong t0) { - int count; - target_ulong res; - - res = t0; - count = 0; - while ((res & 1) == 0) { - count++; - res >>= 1; - } - return count; + return ctztl(t0); } target_ulong helper_lzcnt(target_ulong t0, int wordsize) { - int count; - target_ulong res, mask; - - if (wordsize > 0 && t0 == 0) { - return wordsize; - } - res = t0; - count = TARGET_LONG_BITS - 1; - mask = (target_ulong)1 << (TARGET_LONG_BITS - 1); - while ((res & mask) == 0) { - count--; - res <<= 1; - } - if (wordsize > 0) { - return wordsize - 1 - count; - } - return count; + return clztl(t0) - (TARGET_LONG_BITS - wordsize); } target_ulong helper_bsr(target_ulong t0) { - return helper_lzcnt(t0, 0); + return clztl(t0) ^ (TARGET_LONG_BITS - 1); } -#if TARGET_LONG_BITS == 32 -# define ctztl ctz32 -#else -# define ctztl ctz64 -#endif - target_ulong helper_pdep(target_ulong src, target_ulong mask) { target_ulong dest = 0; |