summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/windows/eivcx86.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/windows/eivcx86.h')
-rw-r--r--src/osd/windows/eivcx86.h463
1 files changed, 463 insertions, 0 deletions
diff --git a/src/osd/windows/eivcx86.h b/src/osd/windows/eivcx86.h
new file mode 100644
index 00000000000..fb40091dd9a
--- /dev/null
+++ b/src/osd/windows/eivcx86.h
@@ -0,0 +1,463 @@
+//============================================================
+//
+// eivcx86.h
+//
+// x86 inline implementations for MSVC compiler.
+//
+// Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
+// Visit http://mamedev.org for licensing and usage restrictions.
+//
+//============================================================
+
+#ifndef __EIVCX86__
+#define __EIVCX86__
+
+#ifdef PTR64
+#include <emmintrin.h>
+#endif
+
+
+/***************************************************************************
+ INLINE MATH FUNCTIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ mul_32x32 - perform a signed 32 bit x 32 bit
+ multiply and return the full 64 bit result
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mul_32x32 _mul_32x32
+INLINE INT64 _mul_32x32(INT32 a, INT32 b)
+{
+ // in theory this should work, but it is untested
+ __asm
+ {
+ mov eax,a
+ imul b
+ // leave results in edx:eax
+ }
+}
+#endif
+
+
+/*-------------------------------------------------
+ mulu_32x32 - perform an unsigned 32 bit x
+ 32 bit multiply and return the full 64 bit
+ result
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mulu_32x32 _mulu_32x32
+INLINE UINT64 _mulu_32x32(UINT32 a, UINT32 b)
+{
+ // in theory this should work, but it is untested
+ __asm
+ {
+ mov eax,a
+ mul b
+ // leave results in edx:eax
+ }
+}
+#endif
+
+
+/*-------------------------------------------------
+ mul_32x32_hi - perform a signed 32 bit x 32 bit
+ multiply and return the upper 32 bits of the
+ result
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mul_32x32_hi _mul_32x32_hi
+INLINE INT32 _mul_32x32_hi(INT32 a, INT32 b)
+{
+ INT32 result;
+
+ __asm
+ {
+ mov eax,a
+ imul b
+ mov result,edx
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ mulu_32x32_hi - perform an unsigned 32 bit x
+ 32 bit multiply and return the upper 32 bits
+ of the result
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mulu_32x32_hi _mulu_32x32_hi
+INLINE UINT32 _mulu_32x32_hi(UINT32 a, UINT32 b)
+{
+ INT32 result;
+
+ __asm
+ {
+ mov eax,a
+ mul b
+ mov result,edx
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ mul_32x32_shift - perform a signed 32 bit x
+ 32 bit multiply and shift the result by the
+ given number of bits before truncating the
+ result to 32 bits
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mul_32x32_shift _mul_32x32_shift
+INLINE INT32 _mul_32x32_shift(INT32 a, INT32 b, UINT8 shift)
+{
+ INT32 result;
+
+ __asm
+ {
+ mov eax,a
+ imul b
+ mov cl,shift
+ shrd eax,edx,cl
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ mulu_32x32_shift - perform an unsigned 32 bit x
+ 32 bit multiply and shift the result by the
+ given number of bits before truncating the
+ result to 32 bits
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mulu_32x32_shift _mulu_32x32_shift
+INLINE UINT32 _mulu_32x32_shift(UINT32 a, UINT32 b, UINT8 shift)
+{
+ INT32 result;
+
+ __asm
+ {
+ mov eax,a
+ mul b
+ mov cl,shift
+ shrd eax,edx,cl
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ div_64x32 - perform a signed 64 bit x 32 bit
+ divide and return the 32 bit quotient
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define div_64x32 _div_64x32
+INLINE INT32 _div_64x32(INT64 a, INT32 b)
+{
+ INT32 result;
+ INT32 alow = a;
+ INT32 ahigh = a >> 32;
+
+ __asm
+ {
+ mov eax,alow
+ mov edx,ahigh
+ idiv b
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ divu_64x32 - perform an unsigned 64 bit x 32 bit
+ divide and return the 32 bit quotient
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define divu_64x32 _divu_64x32
+INLINE UINT32 _divu_64x32(UINT64 a, UINT32 b)
+{
+ UINT32 result;
+ UINT32 alow = a;
+ UINT32 ahigh = a >> 32;
+
+ __asm
+ {
+ mov eax,alow
+ mov edx,ahigh
+ div b
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ div_64x32_rem - perform a signed 64 bit x 32
+ bit divide and return the 32 bit quotient and
+ 32 bit remainder
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define div_64x32_rem _div_64x32_rem
+INLINE INT32 _div_64x32_rem(INT64 a, INT32 b, INT32 *remainder)
+{
+ INT32 result;
+ INT32 alow = a;
+ INT32 ahigh = a >> 32;
+ INT32 rem;
+
+ __asm
+ {
+ mov eax,alow
+ mov edx,ahigh
+ idiv b
+ mov result,eax
+ mov rem,edx
+ }
+
+ *remainder = rem;
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ divu_64x32_rem - perform an unsigned 64 bit x
+ 32 bit divide and return the 32 bit quotient
+ and 32 bit remainder
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define divu_64x32_rem _divu_64x32_rem
+INLINE UINT32 _divu_64x32_rem(UINT64 a, UINT32 b, UINT32 *remainder)
+{
+ UINT32 result;
+ UINT32 alow = a;
+ UINT32 ahigh = a >> 32;
+ UINT32 rem;
+
+ __asm
+ {
+ mov eax,alow
+ mov edx,ahigh
+ div b
+ mov result,eax
+ mov rem,edx
+ }
+
+ *remainder = rem;
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ div_32x32_shift - perform a signed divide of
+ two 32 bit values, shifting the first before
+ division, and returning the 32 bit quotient
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define div_32x32_shift _div_32x32_shift
+INLINE INT32 _div_32x32_shift(INT32 a, INT32 b, UINT8 shift)
+{
+ INT32 result;
+
+ __asm
+ {
+ mov eax,a
+ cdq
+ mov cl,shift
+ shld edx,eax,cl
+ shl eax,cl
+ idiv b
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ divu_32x32_shift - perform an unsigned divide of
+ two 32 bit values, shifting the first before
+ division, and returning the 32 bit quotient
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define divu_32x32_shift _divu_32x32_shift
+INLINE UINT32 _divu_32x32_shift(UINT32 a, UINT32 b, UINT8 shift)
+{
+ UINT32 result;
+
+ __asm
+ {
+ mov eax,a
+ xor edx,edx
+ mov cl,shift
+ shld edx,eax,cl
+ shl eax,cl
+ div b
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ mod_64x32 - perform a signed 64 bit x 32 bit
+ divide and return the 32 bit remainder
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define mod_64x32 _mod_64x32
+INLINE INT32 _mod_64x32(INT64 a, INT32 b)
+{
+ INT32 result;
+ INT32 alow = a;
+ INT32 ahigh = a >> 32;
+
+ __asm
+ {
+ mov eax,alow
+ mov edx,ahigh
+ idiv b
+ mov result,edx
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ modu_64x32 - perform an unsigned 64 bit x 32 bit
+ divide and return the 32 bit remainder
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define modu_64x32 _modu_64x32
+INLINE UINT32 _modu_64x32(UINT64 a, UINT32 b)
+{
+ UINT32 result;
+ UINT32 alow = a;
+ UINT32 ahigh = a >> 32;
+
+ __asm
+ {
+ mov eax,alow
+ mov edx,ahigh
+ div b
+ mov result,edx
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ recip_approx - compute an approximate floating
+ point reciprocal
+-------------------------------------------------*/
+
+#ifdef PTR64
+#define recip_approx _recip_approx
+INLINE float _recip_approx(float z)
+{
+ __m128 mz = _mm_set_ss(z);
+ __m128 mooz = _mm_rcp_ss(mz);
+ float ooz;
+ _mm_store_ss(&ooz, mooz);
+ return ooz;
+}
+#endif
+
+
+
+/***************************************************************************
+ INLINE BIT MANIPULATION FUNCTIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ count_leading_zeros - return the number of
+ leading zero bits in a 32-bit value
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define count_leading_zeros _count_leading_zeros
+INLINE UINT8 _count_leading_zeros(UINT32 value)
+{
+ INT32 result;
+
+ __asm
+ {
+ bsr eax,value
+ jnz skip
+ mov eax,63
+ skip:
+ xor eax,31
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+
+/*-------------------------------------------------
+ count_leading_ones - return the number of
+ leading one bits in a 32-bit value
+-------------------------------------------------*/
+
+#ifndef PTR64
+#define count_leading_ones _count_leading_ones
+INLINE UINT8 _count_leading_ones(UINT32 value)
+{
+ INT32 result;
+
+ __asm
+ {
+ mov eax,value
+ not eax
+ bsr eax,eax
+ jnz skip
+ mov eax,63
+ skip:
+ xor eax,31
+ mov result,eax
+ }
+
+ return result;
+}
+#endif
+
+#endif /* __EIVCX86__ */