aboutsummaryrefslogtreecommitdiff
path: root/target-i386/int_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-01-21 11:52:26 -0800
committerRichard Henderson <rth@twiddle.net>2013-02-19 23:05:18 -0800
commitf1300734cbca515d30953b2c87e259fa378ea301 (patch)
treee61083d1d2fc5eb5e7fe1eda95973e3f16231c58 /target-i386/int_helper.c
parentcd7f97cafdd80d6bd4950ccfdcd9acb7850184b2 (diff)
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>
Diffstat (limited to 'target-i386/int_helper.c')
-rw-r--r--target-i386/int_helper.c45
1 files changed, 11 insertions, 34 deletions
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;