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
