-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Greg Wright
Sent: Tuesday, June 06, 2006 2:18 PM
To: [email protected]
Subject: [Audio-dev] CR: Move math64.h from inline ASM to
straight C for gccbuilds.
Project
=======
linux builds.
Synopsis
========
Currently we have a bunch of functions of the form:
/* Compute (a * b) >> 31, using 64-bit intermediate result */
static __inline__ int MulShift31(int x, int y) {
int zhi ;
__asm__ volatile ("imull %3\n\t"
"shrdl $31,%1,%0"
: "+a,a" (x), "=d,d" (zhi)
: "%0,%0" (x), "m,r" (y)
);
return x ;
}
/* Compute (a * b) >> 30, using 64-bit intermediate result */
static __inline__ int MulShift30(int x, int y) {
int zhi ;
__asm__ volatile ("imull %3\n\t"
"shrdl $30,%1,%0"
: "+a,a" (x), "=d,d" (zhi)
: "%0,%0" (x), "m,r" (y)
);
return x ;
}
These don't compile on gcc versions >= 4.0 due to
"inconsistent asm operands". Rather then try to fix this
inline asm, I think it is better if we just get rid of it
altogether and go with straight C. IE:
static __inline__ int MulShift30(int x, int y) {
return ((INT64)a*(INT64)b)>>30;
}
Jon ran a test on gcc 3.2 and saw that it output the same
code, I ran a test on gcc 4.0 and found the same thing. In
addition, I found that not using inline assembly allowed the
compiler to optimize more. For example, when passing
constants to the function, instead of code like:
imull %ecx
shrdl $30, %edx, %aex
you just get:
movl $123456, -16(%ebp)
the inline assembly version can not do this. I am sure there
are other instances that the C version can be optimzed where
the assembler version can not. In addition, it is just easier
to maintain and port. The MAC_UNIX code has been using code
very similar to this for some time.
Files Modified
==============
audio/fixptutil/pub/math64.h
Branch(s)
=========
HEAD only.
Index: pub/math64.h
===================================================================
RCS file: /cvsroot/audio/fixptutil/pub/math64.h,v
retrieving revision 1.30
diff -u -w -r1.30 math64.h
--- pub/math64.h 7 Feb 2006 20:58:58 -0000 1.30
+++ pub/math64.h 6 Jun 2006 21:10:11 -0000
@@ -123,63 +123,37 @@
// GCC / i386
//////////////////////////////////////////////////////////////
/////////////////////////
-#elif !defined(_MAC_UNIX) && defined(__GNUC__) &&
(defined(__i386__) || defined(__amd64__)) && !defined(_NO_GNU_AS)
+#elif !defined(_MAC_UNIX) && defined(__GNUC__) &&
(defined(__i386__) ||
+defined(__amd64__))
#define HAVE_PLATFORM_MACROS
/* Compute a * b / c, using 64-bit intermediate result */
static __inline__ int MulDiv64(register int x, register int
y, register int z)
{
- /* we specify four alternatives here, one for each
permutation of memory or
- register operand in the multiplier and the divisor.
All are commutative in
- the multiplication arguments, one of which needs to
be in eax when we
- start. */
-
- __asm__ volatile ("imull %2\n\t"
- "idivl %3\n"
- : "+a,a,a,a" (x)
- : "%0,%0,%0,%0" (x), "m,r,m,r" (y),
"m,m,r,r" (z)
- : "edx") ;
- return x ;
+ return (int)(((INT64)x*(INT64)y)/(INT64)z);
}
/* Compute (a * b) >> 32, using 64-bit intermediate result */
static __inline__ int MulShift32(int x, int y)
{
- int z ;
- /* we specify two alternatives here. The first one can
read the multiplier from
- memory, the second from from a register. Both return
the result in eax,edx
- and are commutative in the arguments, one of which
needs to be in eax when we
- start. */
- __asm__ volatile ("imull %3" : "=d,d" (z), "+a,a" (x):
"%1,1" (x), "m,r" (y)) ;
- return z ;
+ return (int)(((INT64)x*(INT64)y)>>32);
}
/* Compute (a * b) >> 31, using 64-bit intermediate result */
static __inline__ int MulShift31(int x, int y)
{
- int zhi ;
- __asm__ volatile ("imull %3\n\t"
- "shrdl $31,%1,%0": "+a,a" (x), "=d,d"
(zhi) : "%0,%0" (x), "m,r" (y)) ;
- return x ;
+ return (int)(((INT64)x*(INT64)y)>>31);
}
-/* Compute (a * b) >> 30, using 64-bit intermediate result */
static __inline__ int MulShift30(int x, int y)
{
- int zhi ;
- __asm__ volatile ("imull %3\n\t"
- "shrdl $30,%1,%0" : "+a,a" (x), "=d,d"
(zhi) : "%0,%0" (x), "m,r" (y)) ;
- return x ;
+ return (int)(((INT64)x*(INT64)y)>>30);
}
/* Compute (a * b) >> n, using 64-bit intermediate result */
static __inline__ int MulShiftN(register int x, register
int y, register int n)
{
- int zhi ;
- __asm__ volatile ("imull %3\n\t"
- "shrdl %%cl,%1,%0" : "+a,a" (x),
"=d,d" (zhi) : "%0,%0" (x), "m,r" (y), "c,c" (n)) ;
- return x ;
+ return (int)(((INT64)x*(INT64)y)>>n);
}
#ifdef TIMING
@@ -196,6 +170,9 @@
#endif
#ifdef DEBUG
+# ifdef ASSERT
+# undef ASSERT
+# endif
#define ASSERT(x) if (!(x)) __asm__ __volatile ("int $3" :: )
#endif
_______________________________________________
Audio-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/audio-dev