mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +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
|
#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
|
#endif // MAME_OSD_EIVCX86_H
|
||||||
|
@ -260,6 +260,62 @@ inline float recip_approx(float value)
|
|||||||
#endif
|
#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
|
INLINE BIT MANIPULATION FUNCTIONS
|
||||||
|
Loading…
Reference in New Issue
Block a user