Looks good, C is better than ASM 

-->Henry

> -----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


_______________________________________________
Audio-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/audio-dev

Reply via email to