diff options
Diffstat (limited to 'src/osd')
-rw-r--r-- | src/osd/eigcc.h | 60 | ||||
-rw-r--r-- | src/osd/eigccarm.h | 62 | ||||
-rw-r--r-- | src/osd/eigccppc.h | 62 | ||||
-rw-r--r-- | src/osd/eigccx86.h | 64 | ||||
-rw-r--r-- | src/osd/eivc.h | 57 | ||||
-rw-r--r-- | src/osd/eivcarm.h | 75 | ||||
-rw-r--r-- | src/osd/eminline.h | 47 |
7 files changed, 388 insertions, 39 deletions
diff --git a/src/osd/eigcc.h b/src/osd/eigcc.h index 69bbeffde07..2c5bf34ba72 100644 --- a/src/osd/eigcc.h +++ b/src/osd/eigcc.h @@ -55,6 +55,66 @@ inline bool _addu_64x64_co(uint64_t a, uint64_t b, uint64_t &sum) ***************************************************************************/ /*------------------------------------------------- + count_leading_zeros_32 - return the number of + leading zero bits in a 32-bit value +-------------------------------------------------*/ + +#ifndef count_leading_zeros_32 +#define count_leading_zeros_32 _count_leading_zeros_32 +inline uint8_t _count_leading_zeros_32(uint32_t val) +{ + // uses CPU feature if available, otherwise falls back to runtime library call + static_assert(sizeof(val) == sizeof(unsigned), "expected 32-bit unsigned int"); + return uint8_t(unsigned(val ? __builtin_clz(val) : 32)); +} +#endif + + +/*------------------------------------------------- + count_leading_ones_32 - return the number of + leading one bits in a 32-bit value +-------------------------------------------------*/ + +#ifndef count_leading_ones_32 +#define count_leading_ones_32 _count_leading_ones_32 +inline uint8_t _count_leading_ones_32(uint32_t val) +{ + return count_leading_zeros_32(~val); +} +#endif + + +/*------------------------------------------------- + count_leading_zeros_64 - return the number of + leading zero bits in a 64-bit value +-------------------------------------------------*/ + +#ifndef count_leading_zeros_64 +#define count_leading_zeros_64 _count_leading_zeros_64 +inline uint8_t _count_leading_zeros_64(uint64_t val) +{ + // uses CPU feature if available, otherwise falls back to runtime library call + static_assert(sizeof(val) == sizeof(unsigned long long), "expected 64-bit unsigned long long int"); + return uint8_t(unsigned(val ? __builtin_clzll(val) : 64)); +} +#endif + + +/*------------------------------------------------- + count_leading_ones_64 - return the number of + leading one bits in a 64-bit value +-------------------------------------------------*/ + +#ifndef count_leading_ones_64 +#define count_leading_ones_64 _count_leading_ones_64 +inline uint8_t _count_leading_ones_64(uint64_t val) +{ + return count_leading_zeros_64(~val); +} +#endif + + +/*------------------------------------------------- population_count_32 - return the number of one bits in a 32-bit value -------------------------------------------------*/ diff --git a/src/osd/eigccarm.h b/src/osd/eigccarm.h index 27d79c4a5c6..90004daf9d4 100644 --- a/src/osd/eigccarm.h +++ b/src/osd/eigccarm.h @@ -239,14 +239,14 @@ _mulu_64x64(uint64_t a, uint64_t b, uint64_t &hi) ***************************************************************************/ /*------------------------------------------------- - count_leading_zeros - return the number of + count_leading_zeros_32 - return the number of leading zero bits in a 32-bit value -------------------------------------------------*/ #if defined(__aarch64__) -#define count_leading_zeros _count_leading_zeros +#define count_leading_zeros_32 _count_leading_zeros_32 inline uint8_t ATTR_CONST ATTR_FORCE_INLINE -_count_leading_zeros(uint32_t value) +_count_leading_zeros_32(uint32_t value) { uint32_t result; @@ -256,20 +256,20 @@ _count_leading_zeros(uint32_t value) : [value] "r" (value) ); - return result; + return uint8_t(result); } #endif /*------------------------------------------------- - count_leading_ones - return the number of + count_leading_ones_32 - return the number of leading one bits in a 32-bit value -------------------------------------------------*/ #if defined(__aarch64__) -#define count_leading_ones _count_leading_ones +#define count_leading_ones_32 _count_leading_ones_32 inline uint8_t ATTR_CONST ATTR_FORCE_INLINE -_count_leading_ones(uint32_t value) +_count_leading_ones_32(uint32_t value) { uint32_t result; @@ -279,7 +279,53 @@ _count_leading_ones(uint32_t value) : [value] "r" (~value) ); - return result; + return uint8_t(result); +} +#endif + + +/*------------------------------------------------- + count_leading_zeros_64 - return the number of + leading zero bits in a 64-bit value +-------------------------------------------------*/ + +#if defined(__aarch64__) +#define count_leading_zeros_64 _count_leading_zeros_64 +inline uint8_t ATTR_CONST ATTR_FORCE_INLINE +_count_leading_zeros_64(uint64_t value) +{ + uint64_t result; + + __asm__ ( + " clz %[result], %[value] \n" + : [result] "=r" (result) + : [value] "r" (value) + ); + + return uint8_t(result); +} +#endif + + +/*------------------------------------------------- + count_leading_ones_64 - return the number of + leading one bits in a 64-bit value +-------------------------------------------------*/ + +#if defined(__aarch64__) +#define count_leading_ones_64 _count_leading_ones_64 +inline uint8_t ATTR_CONST ATTR_FORCE_INLINE +_count_leading_ones_64(uint64_t value) +{ + uint64_t result; + + __asm__ ( + " clz %[result], %[value] \n" + : [result] "=r" (result) + : [value] "r" (~value) + ); + + return uint8_t(result); } #endif diff --git a/src/osd/eigccppc.h b/src/osd/eigccppc.h index 3a1b2093d4e..de1372ff39b 100644 --- a/src/osd/eigccppc.h +++ b/src/osd/eigccppc.h @@ -239,13 +239,13 @@ _mulu_64x64(uint64_t a, uint64_t b, uint64_t &hi) ***************************************************************************/ /*------------------------------------------------- - count_leading_zeros - return the number of + count_leading_zeros_32 - return the number of leading zero bits in a 32-bit value -------------------------------------------------*/ -#define count_leading_zeros _count_leading_zeros +#define count_leading_zeros_32 _count_leading_zeros_32 inline uint8_t ATTR_CONST ATTR_FORCE_INLINE -_count_leading_zeros(uint32_t value) +_count_leading_zeros_32(uint32_t value) { uint32_t result; @@ -255,18 +255,18 @@ _count_leading_zeros(uint32_t value) : [value] "r" (value) ); - return result; + return uint8_t(result); } /*------------------------------------------------- - count_leading_ones - return the number of + count_leading_ones_32 - return the number of leading one bits in a 32-bit value -------------------------------------------------*/ -#define count_leading_ones _count_leading_ones +#define count_leading_ones_32 _count_leading_ones_32 inline uint8_t ATTR_CONST ATTR_FORCE_INLINE -_count_leading_ones(uint32_t value) +_count_leading_ones_32(uint32_t value) { uint32_t result; @@ -276,7 +276,53 @@ _count_leading_ones(uint32_t value) : [value] "r" (~value) ); - return result; + return uint8_t(result); +} + + +/*------------------------------------------------- + count_leading_zeros_64 - return the number of + leading zero bits in a 64-bit value +-------------------------------------------------*/ + +#if defined(__ppc64__) +#define count_leading_zeros_64 _count_leading_zeros_64 +inline uint8_t ATTR_CONST ATTR_FORCE_INLINE +_count_leading_zeros_64(uint64_t value) +{ + uint64_t result; + + __asm__ ( + " cntlzd %[result], %[value] \n" + : [result] "=r" (result) + : [value] "r" (value) + ); + + return uint8_t(result); } +#endif + + +/*------------------------------------------------- + count_leading_ones_64 - return the number of + leading one bits in a 64-bit value +-------------------------------------------------*/ + +#if defined(__ppc64__) +#define count_leading_ones_64 _count_leading_ones_64 +inline uint8_t ATTR_CONST ATTR_FORCE_INLINE +_count_leading_ones_64(uint64_t value) +{ + uint64_t result; + + __asm__ ( + " cntlzd %[result], %[value] \n" + : [result] "=r" (result) + : [value] "r" (~value) + ); + + return uint8_t(result); +} +#endif #endif // MAME_OSD_EIGCCPPC_H diff --git a/src/osd/eigccx86.h b/src/osd/eigccx86.h index b3bbf7bd0ec..35f02e12f5e 100644 --- a/src/osd/eigccx86.h +++ b/src/osd/eigccx86.h @@ -433,13 +433,13 @@ _mulu_64x64(uint64_t a, uint64_t b, uint64_t &hi) ***************************************************************************/ /*------------------------------------------------- - count_leading_zeros - return the number of + count_leading_zeros_32 - return the number of leading zero bits in a 32-bit value -------------------------------------------------*/ -#define count_leading_zeros _count_leading_zeros +#define count_leading_zeros_32 _count_leading_zeros_32 inline uint8_t ATTR_CONST ATTR_FORCE_INLINE -_count_leading_zeros(uint32_t value) +_count_leading_zeros_32(uint32_t value) { uint32_t result; __asm__ ( @@ -450,18 +450,18 @@ _count_leading_zeros(uint32_t value) , [bias] "rm" (~uint32_t(0)) // 'bias' can be register or memory : "cc" // clobbers condition codes ); - return 31U - result; + return uint8_t(31U - result); } /*------------------------------------------------- - count_leading_ones - return the number of + count_leading_ones_32 - return the number of leading one bits in a 32-bit value -------------------------------------------------*/ -#define count_leading_ones _count_leading_ones +#define count_leading_ones_32 _count_leading_ones_32 inline uint8_t ATTR_CONST ATTR_FORCE_INLINE -_count_leading_ones(uint32_t value) +_count_leading_ones_32(uint32_t value) { uint32_t result; __asm__ ( @@ -472,7 +472,55 @@ _count_leading_ones(uint32_t value) , [bias] "rm" (~uint32_t(0)) // 'bias' can be register or memory : "cc" // clobbers condition codes ); - return 31U - result; + return uint8_t(31U - result); } + +/*------------------------------------------------- + count_leading_zeros_64 - return the number of + leading zero bits in a 64-bit value +-------------------------------------------------*/ + +#ifdef __x86_64__ +#define count_leading_zeros_64 _count_leading_zeros_64 +inline uint8_t ATTR_CONST ATTR_FORCE_INLINE +_count_leading_zeros_64(uint64_t value) +{ + uint64_t result; + __asm__ ( + " bsrq %[value], %[result] ;" + " cmovzq %[bias], %[result] ;" + : [result] "=&r" (result) // result can be in any register + : [value] "rm" (value) // 'value' can be register or memory + , [bias] "rm" (~uint64_t(0)) // 'bias' can be register or memory + : "cc" // clobbers condition codes + ); + return uint8_t(63U - result); +} +#endif + + +/*------------------------------------------------- + count_leading_ones_64 - return the number of + leading one bits in a 64-bit value +-------------------------------------------------*/ + +#ifdef __x86_64__ +#define count_leading_ones_64 _count_leading_ones_64 +inline uint8_t ATTR_CONST ATTR_FORCE_INLINE +_count_leading_ones_64(uint64_t value) +{ + uint64_t result; + __asm__ ( + " bsrq %[value], %[result] ;" + " cmovzq %[bias], %[result] ;" + : [result] "=&r" (result) // result can be in any register + : [value] "rm" (~value) // 'value' can be register or memory + , [bias] "rm" (~uint64_t(0)) // 'bias' can be register or memory + : "cc" // clobbers condition codes + ); + return uint8_t(63U - result); +} +#endif + #endif // MAME_OSD_EIGCCX86_H diff --git a/src/osd/eivc.h b/src/osd/eivc.h index 56d1dcc3ab8..2ffd0e7633b 100644 --- a/src/osd/eivc.h +++ b/src/osd/eivc.h @@ -15,6 +15,9 @@ #include <intrin.h> #pragma intrinsic(_BitScanReverse) +#ifdef PTR64 +#pragma intrinsic(_BitScanReverse64) +#endif /*************************************************************************** @@ -22,13 +25,13 @@ ***************************************************************************/ /*------------------------------------------------- - 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 -#define count_leading_zeros _count_leading_zeros -__forceinline uint8_t _count_leading_zeros(uint32_t value) +#ifndef count_leading_zeros_32 +#define count_leading_zeros_32 _count_leading_zeros_32 +__forceinline uint8_t _count_leading_zeros_32(uint32_t value) { unsigned long index; return _BitScanReverse(&index, value) ? (31U - index) : 32U; @@ -37,17 +40,55 @@ __forceinline uint8_t _count_leading_zeros(uint32_t value) /*------------------------------------------------- - 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 -#define count_leading_ones _count_leading_ones -__forceinline uint8_t _count_leading_ones(uint32_t value) +#ifndef count_leading_ones_32 +#define count_leading_ones_32 _count_leading_ones_32 +__forceinline uint8_t _count_leading_ones_32(uint32_t value) { unsigned long index; return _BitScanReverse(&index, ~value) ? (31U - index) : 32U; } #endif + +/*------------------------------------------------- + count_leading_zeros_64 - return the number of + leading zero bits in a 64-bit value +-------------------------------------------------*/ + +#ifndef count_leading_zeros_64 +#define count_leading_zeros_64 _count_leading_zeros_64 +__forceinline uint8_t _count_leading_zeros_64(uint64_t value) +{ + unsigned long index; +#ifdef PTR64 + return _BitScanReverse64(&index, value) ? (63U - index) : 64U; +#else + return _BitScanReverse(&index, uint32_t(value >> 32)) ? (31U - index) : _BitScanReverse(&index, uint32_t(value)) ? (63U - index) : 64U; +#endif +} +#endif + + +/*------------------------------------------------- + count_leading_ones_64 - return the number of + leading one bits in a 64-bit value +-------------------------------------------------*/ + +#ifndef count_leading_ones_64 +#define count_leading_ones_64 _count_leading_ones_64 +__forceinline uint8_t _count_leading_ones_64(uint64_t value) +{ + unsigned long index; +#ifdef PTR64 + return _BitScanReverse64(&index, ~value) ? (63U - index) : 64U; +#else + return _BitScanReverse(&index, ~uint32_t(value >> 32)) ? (31U - index) : _BitScanReverse(&index, ~uint32_t(value)) ? (63U - index) : 64U; +#endif +} +#endif + #endif // MAME_OSD_EIVC_H diff --git a/src/osd/eivcarm.h b/src/osd/eivcarm.h new file mode 100644 index 00000000000..5e612cb25fb --- /dev/null +++ b/src/osd/eivcarm.h @@ -0,0 +1,75 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// eivcarm.h +// +// ARM/AArch64 inline implementations for MSVC compiler. +// +//============================================================ + +#ifndef MAME_OSD_EIVCARM_H +#define MAME_OSD_EIVCARM_H + +#pragma once + +#include <intrin.h> + +#pragma intrinsic(_CountLeadingZeros) +#pragma intrinsic(_CountLeadingZeros64) +#pragma intrinsic(_CountLeadingOnes) +#pragma intrinsic(_CountLeadingOnes64) + + +/*************************************************************************** + INLINE BIT MANIPULATION FUNCTIONS +***************************************************************************/ + +/*------------------------------------------------- + count_leading_zeros_32 - return the number of + leading zero bits in a 32-bit value +-------------------------------------------------*/ + +#define count_leading_zeros_32 _count_leading_zeros_32 +__forceinline uint8_t _count_leading_zeros_32(uint32_t value) +{ + return uint8_t(_CountLeadingZeros(value)); +} + + +/*------------------------------------------------- + count_leading_ones_32 - return the number of + leading one bits in a 32-bit value +-------------------------------------------------*/ + +#define count_leading_ones_32 _count_leading_ones_32 +__forceinline uint8_t _count_leading_ones_32(uint32_t value) +{ + return uint8_t(_CountLeadingOnes(value)); +} + + +/*------------------------------------------------- + count_leading_zeros_64 - return the number of + leading zero bits in a 64-bit value +-------------------------------------------------*/ + +#define count_leading_zeros_64 _count_leading_zeros_64 +__forceinline uint8_t _count_leading_zeros_64(uint64_t value) +{ + return uint8_t(_CountLeadingZeros64(value)); +} + + +/*------------------------------------------------- + count_leading_ones_64 - return the number of + leading one bits in a 64-bit value +-------------------------------------------------*/ + +#define count_leading_ones_64 _count_leading_ones_64 +__forceinline uint8_t _count_leading_ones_64(uint64_t value) +{ + return uint8_t(_CountLeadingOnes64(value)); +} + +#endif // MAME_OSD_EIVCARM_H diff --git a/src/osd/eminline.h b/src/osd/eminline.h index a7cc4cfee3d..02bd22b3fdb 100644 --- a/src/osd/eminline.h +++ b/src/osd/eminline.h @@ -33,8 +33,10 @@ #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" @@ -352,12 +354,12 @@ inline bool addu_64x64_co(uint64_t a, uint64_t b, uint64_t &sum) ***************************************************************************/ /*------------------------------------------------- - 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; @@ -368,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; @@ -383,6 +385,37 @@ 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 -------------------------------------------------*/ |