Now checked into HEAD.
--greg.


Henry Ping wrote:
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