summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/eminline.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/eminline.h')
-rw-r--r--src/osd/eminline.h227
1 files changed, 172 insertions, 55 deletions
diff --git a/src/osd/eminline.h b/src/osd/eminline.h
index eb8ffaa9748..6d54a21a45f 100644
--- a/src/osd/eminline.h
+++ b/src/osd/eminline.h
@@ -25,22 +25,22 @@
#include "eigccx86.h"
#elif defined(__ppc__) || defined (__PPC__) || defined(__ppc64__) || defined(__PPC64__)
#include "eigccppc.h"
-#else
-#error "no matching assembler implementations found - please compile with NOASM=1"
+#elif defined(__arm__) || defined(__aarch64__)
+#include "eigccarm.h"
#endif
+#include "eigcc.h"
+
#elif defined(_MSC_VER)
-#if (defined(_M_IX86) || defined(_M_X64))
+#if defined(_M_IX86) || defined(_M_X64)
#include "eivcx86.h"
+#elif defined(_M_ARM) || defined(_M_ARM64)
+#include "eivcarm.h"
#endif
#include "eivc.h"
-#else
-
-#error "no matching assembler implementations found - please compile with NOASM=1"
-
#endif
#endif // !defined(MAME_NOASM)
@@ -56,7 +56,7 @@
-------------------------------------------------*/
#ifndef mul_32x32
-inline int64_t mul_32x32(int32_t a, int32_t b)
+constexpr int64_t mul_32x32(int32_t a, int32_t b)
{
return int64_t(a) * int64_t(b);
}
@@ -70,7 +70,7 @@ inline int64_t mul_32x32(int32_t a, int32_t b)
-------------------------------------------------*/
#ifndef mulu_32x32
-inline uint64_t mulu_32x32(uint32_t a, uint32_t b)
+constexpr uint64_t mulu_32x32(uint32_t a, uint32_t b)
{
return uint64_t(a) * uint64_t(b);
}
@@ -84,7 +84,7 @@ inline uint64_t mulu_32x32(uint32_t a, uint32_t b)
-------------------------------------------------*/
#ifndef mul_32x32_hi
-inline int32_t mul_32x32_hi(int32_t a, int32_t b)
+constexpr int32_t mul_32x32_hi(int32_t a, int32_t b)
{
return uint32_t((int64_t(a) * int64_t(b)) >> 32);
}
@@ -98,7 +98,7 @@ inline int32_t mul_32x32_hi(int32_t a, int32_t b)
-------------------------------------------------*/
#ifndef mulu_32x32_hi
-inline uint32_t mulu_32x32_hi(uint32_t a, uint32_t b)
+constexpr uint32_t mulu_32x32_hi(uint32_t a, uint32_t b)
{
return uint32_t((uint64_t(a) * uint64_t(b)) >> 32);
}
@@ -113,7 +113,7 @@ inline uint32_t mulu_32x32_hi(uint32_t a, uint32_t b)
-------------------------------------------------*/
#ifndef mul_32x32_shift
-inline int32_t mul_32x32_shift(int32_t a, int32_t b, uint8_t shift)
+constexpr int32_t mul_32x32_shift(int32_t a, int32_t b, uint8_t shift)
{
return int32_t((int64_t(a) * int64_t(b)) >> shift);
}
@@ -128,7 +128,7 @@ inline int32_t mul_32x32_shift(int32_t a, int32_t b, uint8_t shift)
-------------------------------------------------*/
#ifndef mulu_32x32_shift
-inline uint32_t mulu_32x32_shift(uint32_t a, uint32_t b, uint8_t shift)
+constexpr uint32_t mulu_32x32_shift(uint32_t a, uint32_t b, uint8_t shift)
{
return uint32_t((uint64_t(a) * uint64_t(b)) >> shift);
}
@@ -141,7 +141,7 @@ inline uint32_t mulu_32x32_shift(uint32_t a, uint32_t b, uint8_t shift)
-------------------------------------------------*/
#ifndef div_64x32
-inline int32_t div_64x32(int64_t a, int32_t b)
+constexpr int32_t div_64x32(int64_t a, int32_t b)
{
return a / int64_t(b);
}
@@ -154,7 +154,7 @@ inline int32_t div_64x32(int64_t a, int32_t b)
-------------------------------------------------*/
#ifndef divu_64x32
-inline uint32_t divu_64x32(uint64_t a, uint32_t b)
+constexpr uint32_t divu_64x32(uint64_t a, uint32_t b)
{
return a / uint64_t(b);
}
@@ -168,10 +168,10 @@ inline uint32_t divu_64x32(uint64_t a, uint32_t b)
-------------------------------------------------*/
#ifndef div_64x32_rem
-inline int32_t div_64x32_rem(int64_t a, int32_t b, int32_t *remainder)
+inline int32_t div_64x32_rem(int64_t a, int32_t b, int32_t &remainder)
{
- int32_t const res = div_64x32(a, b);
- *remainder = a - (int64_t(b) * res);
+ int32_t const res(div_64x32(a, b));
+ remainder = a - (int64_t(b) * res);
return res;
}
#endif
@@ -184,10 +184,10 @@ inline int32_t div_64x32_rem(int64_t a, int32_t b, int32_t *remainder)
-------------------------------------------------*/
#ifndef divu_64x32_rem
-inline uint32_t divu_64x32_rem(uint64_t a, uint32_t b, uint32_t *remainder)
+inline uint32_t divu_64x32_rem(uint64_t a, uint32_t b, uint32_t &remainder)
{
- uint32_t const res = divu_64x32(a, b);
- *remainder = a - (uint64_t(b) * res);
+ uint32_t const res(divu_64x32(a, b));
+ remainder = a - (uint64_t(b) * res);
return res;
}
#endif
@@ -200,7 +200,7 @@ inline uint32_t divu_64x32_rem(uint64_t a, uint32_t b, uint32_t *remainder)
-------------------------------------------------*/
#ifndef div_32x32_shift
-inline int32_t div_32x32_shift(int32_t a, int32_t b, uint8_t shift)
+constexpr int32_t div_32x32_shift(int32_t a, int32_t b, uint8_t shift)
{
return (int64_t(a) << shift) / int64_t(b);
}
@@ -214,7 +214,7 @@ inline int32_t div_32x32_shift(int32_t a, int32_t b, uint8_t shift)
-------------------------------------------------*/
#ifndef divu_32x32_shift
-inline uint32_t divu_32x32_shift(uint32_t a, uint32_t b, uint8_t shift)
+constexpr uint32_t divu_32x32_shift(uint32_t a, uint32_t b, uint8_t shift)
{
return (uint64_t(a) << shift) / uint64_t(b);
}
@@ -227,7 +227,7 @@ inline uint32_t divu_32x32_shift(uint32_t a, uint32_t b, uint8_t shift)
-------------------------------------------------*/
#ifndef mod_64x32
-inline int32_t mod_64x32(int64_t a, int32_t b)
+constexpr int32_t mod_64x32(int64_t a, int32_t b)
{
return a - (b * div_64x32(a, b));
}
@@ -240,7 +240,7 @@ inline int32_t mod_64x32(int64_t a, int32_t b)
-------------------------------------------------*/
#ifndef modu_64x32
-inline uint32_t modu_64x32(uint64_t a, uint32_t b)
+constexpr uint32_t modu_64x32(uint64_t a, uint32_t b)
{
return a - (b * divu_64x32(a, b));
}
@@ -253,7 +253,7 @@ inline uint32_t modu_64x32(uint64_t a, uint32_t b)
-------------------------------------------------*/
#ifndef recip_approx
-inline float recip_approx(float value)
+constexpr float recip_approx(float value)
{
return 1.0f / value;
}
@@ -266,7 +266,7 @@ inline float recip_approx(float value)
-------------------------------------------------*/
#ifndef mul_64x64
-inline int64_t mul_64x64(int64_t a, int64_t b, int64_t *hi)
+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;
@@ -279,13 +279,13 @@ inline int64_t mul_64x64(int64_t a, int64_t b, int64_t *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;
+ hi = ab_hi + (ab_m1 >> 32) + (ab_m2 >> 32) + carry;
// adjust for sign
if (a < 0)
- *hi -= b;
+ hi -= b;
if (b < 0)
- *hi -= a;
+ hi -= a;
return ab_lo + (ab_m1 << 32) + (ab_m2 << 32);
}
@@ -298,7 +298,7 @@ inline int64_t mul_64x64(int64_t a, int64_t b, int64_t *hi)
-------------------------------------------------*/
#ifndef mulu_64x64
-inline uint64_t mulu_64x64(uint64_t a, uint64_t b, uint64_t *hi)
+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);
@@ -311,25 +311,55 @@ inline uint64_t mulu_64x64(uint64_t a, uint64_t b, uint64_t *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;
+ hi = ab_hi + (ab_m1 >> 32) + (ab_m2 >> 32) + carry;
return ab_lo + (ab_m1 << 32) + (ab_m2 << 32);
}
#endif
+/*-------------------------------------------------
+ addu_32x32_co - perform an unsigned 32 bit + 32
+ bit addition and return the result with carry
+ out
+-------------------------------------------------*/
+
+#ifndef addu_32x32_co
+inline bool addu_32x32_co(uint32_t a, uint32_t b, uint32_t &sum)
+{
+ sum = a + b;
+ return (a > sum) || (b > sum);
+}
+#endif
+
+
+/*-------------------------------------------------
+ addu_64x64_co - perform an unsigned 64 bit + 64
+ bit addition and return the result with carry
+ out
+-------------------------------------------------*/
+
+#ifndef addu_64x64_co
+inline bool addu_64x64_co(uint64_t a, uint64_t b, uint64_t &sum)
+{
+ sum = a + b;
+ return (a > sum) || (b > sum);
+}
+#endif
+
+
/***************************************************************************
INLINE BIT MANIPULATION FUNCTIONS
***************************************************************************/
/*-------------------------------------------------
- count_leading_zeros - return the number of
+ count_leading_zeros_32 - return the number of
leading zero bits in a 32-bit value
-------------------------------------------------*/
-#ifndef count_leading_zeros
-inline uint8_t count_leading_zeros(uint32_t val)
+#ifndef count_leading_zeros_32
+inline uint8_t count_leading_zeros_32(uint32_t val)
{
if (!val) return 32U;
uint8_t count;
@@ -340,12 +370,12 @@ inline uint8_t count_leading_zeros(uint32_t val)
/*-------------------------------------------------
- count_leading_ones - return the number of
+ count_leading_ones_32 - return the number of
leading one bits in a 32-bit value
-------------------------------------------------*/
-#ifndef count_leading_ones
-inline uint8_t count_leading_ones(uint32_t val)
+#ifndef count_leading_ones_32
+inline uint8_t count_leading_ones_32(uint32_t val)
{
uint8_t count;
for (count = 0; int32_t(val) < 0; count++) val <<= 1;
@@ -355,22 +385,48 @@ inline uint8_t count_leading_ones(uint32_t val)
/*-------------------------------------------------
+ count_leading_zeros_64 - return the number of
+ leading zero bits in a 64-bit value
+-------------------------------------------------*/
+
+#ifndef count_leading_zeros_64
+inline uint8_t count_leading_zeros_64(uint64_t val)
+{
+ if (!val) return 64U;
+ uint8_t count;
+ for (count = 0; int64_t(val) >= 0; count++) val <<= 1;
+ return count;
+}
+#endif
+
+
+/*-------------------------------------------------
+ count_leading_ones_64 - return the number of
+ leading one bits in a 64-bit value
+-------------------------------------------------*/
+
+#ifndef count_leading_ones_64
+inline uint8_t count_leading_ones_64(uint64_t val)
+{
+ uint8_t count;
+ for (count = 0; int64_t(val) < 0; count++) val <<= 1;
+ return count;
+}
+#endif
+
+
+/*-------------------------------------------------
population_count_32 - return the number of
one bits in a 32-bit value
-------------------------------------------------*/
#ifndef population_count_32
-#if defined(__NetBSD__)
-#define population_count_32 popcount32
-#else
inline unsigned population_count_32(uint32_t val)
{
-#if defined(__GNUC__)
- // uses CPU feature if available, otherwise falls back to implementation similar to what follows
- static_assert(sizeof(val) == sizeof(unsigned), "expected 32-bit unsigned int");
- return unsigned(__builtin_popcount(static_cast<unsigned>(val)));
+#if defined(__NetBSD__)
+ return popcount32(val);
#else
- // optimal Hamming weight assuing fast 32*32->32
+ // optimal Hamming weight assuming fast 32*32->32
constexpr uint32_t m1(0x55555555);
constexpr uint32_t m2(0x33333333);
constexpr uint32_t m4(0x0f0f0f0f);
@@ -382,7 +438,6 @@ inline unsigned population_count_32(uint32_t val)
#endif
}
#endif
-#endif
/*-------------------------------------------------
@@ -391,15 +446,10 @@ inline unsigned population_count_32(uint32_t val)
-------------------------------------------------*/
#ifndef population_count_64
-#if defined(__NetBSD__)
-#define population_count_64 popcount64
-#else
inline unsigned population_count_64(uint64_t val)
{
-#if defined(__GNUC__)
- // uses CPU feature if available, otherwise falls back to implementation similar to what follows
- static_assert(sizeof(val) == sizeof(unsigned long long), "expected 64-bit unsigned long long int");
- return unsigned(__builtin_popcountll(static_cast<unsigned long long>(val)));
+#if defined(__NetBSD__)
+ return popcount64(val);
#else
// guess that architectures with 64-bit pointers have 64-bit multiplier
if (sizeof(void *) >= sizeof(uint64_t))
@@ -422,6 +472,73 @@ inline unsigned population_count_64(uint64_t val)
#endif
}
#endif
+
+
+/*-------------------------------------------------
+ rotl_32 - circularly shift a 32-bit value left
+ by the specified number of bits (modulo 32)
+-------------------------------------------------*/
+
+#ifndef rotl_32
+constexpr uint32_t rotl_32(uint32_t val, int shift)
+{
+ shift &= 31;
+ if (shift)
+ return val << shift | val >> (32 - shift);
+ else
+ return val;
+}
+#endif
+
+
+/*-------------------------------------------------
+ rotr_32 - circularly shift a 32-bit value right
+ by the specified number of bits (modulo 32)
+-------------------------------------------------*/
+
+#ifndef rotr_32
+constexpr uint32_t rotr_32(uint32_t val, int shift)
+{
+ shift &= 31;
+ if (shift)
+ return val >> shift | val << (32 - shift);
+ else
+ return val;
+}
+#endif
+
+
+/*-------------------------------------------------
+ rotl_64 - circularly shift a 64-bit value left
+ by the specified number of bits (modulo 64)
+-------------------------------------------------*/
+
+#ifndef rotl_64
+constexpr uint64_t rotl_64(uint64_t val, int shift)
+{
+ shift &= 63;
+ if (shift)
+ return val << shift | val >> (64 - shift);
+ else
+ return val;
+}
+#endif
+
+
+/*-------------------------------------------------
+ rotr_64 - circularly shift a 64-bit value right
+ by the specified number of bits (modulo 64)
+-------------------------------------------------*/
+
+#ifndef rotr_64
+constexpr uint64_t rotr_64(uint64_t val, int shift)
+{
+ shift &= 63;
+ if (shift)
+ return val >> shift | val << (64 - shift);
+ else
+ return val;
+}
#endif
@@ -437,7 +554,7 @@ inline unsigned population_count_64(uint64_t val)
-------------------------------------------------*/
#ifndef get_profile_ticks
-inline int64_t get_profile_ticks()
+inline int64_t get_profile_ticks() noexcept
{
return osd_ticks();
}