diff options
Diffstat (limited to 'target-i386/int_helper.c')
-rw-r--r-- | target-i386/int_helper.c | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c index 84b812dcca..3b56075a9d 100644 --- a/target-i386/int_helper.c +++ b/target-i386/int_helper.c @@ -385,6 +385,13 @@ void helper_mulq_EAX_T0(CPUX86State *env, target_ulong t0) CC_SRC = r1; } +target_ulong helper_umulh(target_ulong t0, target_ulong t1) +{ + uint64_t h, l; + mulu64(&l, &h, t0, t1); + return h; +} + void helper_imulq_EAX_T0(CPUX86State *env, target_ulong t0) { uint64_t r0, r1; @@ -440,45 +447,49 @@ 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) +target_ulong helper_ctz(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) +target_ulong helper_clz(target_ulong t0) { - int count; - target_ulong res, mask; + return clztl(t0); +} - 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; +target_ulong helper_pdep(target_ulong src, target_ulong mask) +{ + target_ulong dest = 0; + int i, o; + + for (i = 0; mask != 0; i++) { + o = ctztl(mask); + mask &= mask - 1; + dest |= ((src >> i) & 1) << o; } - return count; + return dest; } -target_ulong helper_bsr(target_ulong t0) +target_ulong helper_pext(target_ulong src, target_ulong mask) { - return helper_lzcnt(t0, 0); + target_ulong dest = 0; + int i, o; + + for (o = 0; mask != 0; o++) { + i = ctztl(mask); + mask &= mask - 1; + dest |= ((src >> i) & 1) << o; + } + return dest; } #define SHIFT 0 |