mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
osd: 64x64 multiply helpers (nw)
Can we have these? I didn't attempt to add implementations for anything other than MSVC, but I believe gcc and clang for 64-bit targets have equivalents.
This commit is contained in:
parent
b113d0c26d
commit
a7c5845317
@ -403,4 +403,24 @@ static inline float _recip_approx(float z)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mul_64x64 - perform a signed 64 bit x 64 bit
|
||||
multiply and return the full 128 bit result
|
||||
-------------------------------------------------*/
|
||||
|
||||
#ifdef PTR64
|
||||
#define mul_64x64 _mul128
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mulu_64x64 - perform an unsigned 64 bit x 64
|
||||
bit multiply and return the full 128 bit result
|
||||
-------------------------------------------------*/
|
||||
|
||||
#ifdef PTR64
|
||||
#define mulu_64x64 _umul128
|
||||
#endif
|
||||
|
||||
#endif // MAME_OSD_EIVCX86_H
|
||||
|
@ -260,6 +260,62 @@ 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 = 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;
|
||||
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user