diff options
Diffstat (limited to 'src/osd/eminline.h')
-rw-r--r-- | src/osd/eminline.h | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/osd/eminline.h b/src/osd/eminline.h index bb0aec63468..eb8ffaa9748 100644 --- a/src/osd/eminline.h +++ b/src/osd/eminline.h @@ -260,6 +260,64 @@ inline float recip_approx(float value) #endif +/*------------------------------------------------- + mul_64x64 - perform a signed 64 bit x 64 bit + multiply and return the full 128 bit result +-------------------------------------------------*/ + +#ifndef mul_64x64 +inline int64_t mul_64x64(int64_t a, int64_t b, int64_t *hi) +{ + uint64_t const a_hi = uint64_t(a) >> 32; + uint64_t const b_hi = uint64_t(b) >> 32; + uint64_t const a_lo = uint32_t(uint64_t(a)); + uint64_t const b_lo = uint32_t(uint64_t(b)); + + uint64_t const ab_lo = a_lo * b_lo; + uint64_t const ab_m1 = a_hi * b_lo; + uint64_t const ab_m2 = a_lo * b_hi; + uint64_t const ab_hi = a_hi * b_hi; + uint64_t const carry = ((ab_lo >> 32) + uint32_t(ab_m1) + uint32_t(ab_m2)) >> 32; + + *hi = ab_hi + (ab_m1 >> 32) + (ab_m2 >> 32) + carry; + + // adjust for sign + if (a < 0) + *hi -= b; + if (b < 0) + *hi -= a; + + return ab_lo + (ab_m1 << 32) + (ab_m2 << 32); +} +#endif + + +/*------------------------------------------------- + mulu_64x64 - perform an unsigned 64 bit x 64 + bit multiply and return the full 128 bit result +-------------------------------------------------*/ + +#ifndef mulu_64x64 +inline uint64_t mulu_64x64(uint64_t a, uint64_t b, uint64_t *hi) +{ + uint64_t const a_hi = uint32_t(a >> 32); + uint64_t const b_hi = uint32_t(b >> 32); + uint64_t const a_lo = uint32_t(a); + uint64_t const b_lo = uint32_t(b); + + uint64_t const ab_lo = a_lo * b_lo; + uint64_t const ab_m1 = a_hi * b_lo; + uint64_t const ab_m2 = a_lo * b_hi; + uint64_t const ab_hi = a_hi * b_hi; + uint64_t const carry = ((ab_lo >> 32) + uint32_t(ab_m1) + uint32_t(ab_m2)) >> 32; + + *hi = ab_hi + (ab_m1 >> 32) + (ab_m2 >> 32) + carry; + + return ab_lo + (ab_m1 << 32) + (ab_m2 << 32); +} +#endif + + /*************************************************************************** INLINE BIT MANIPULATION FUNCTIONS |