Looks good, C is better than ASM
-->Henry
> -----Original Message-----
> From: audio-dev-bounces helixcommunity.org
> [mailto:audio-dev-bounces helixcommunity.org] On
Behalf Of Greg Wright
> Sent: Tuesday, June 06, 2006 2:18 PM
> To: audio-dev helixcommunity.org
> 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
> Audio-dev helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|