Provide __P definition if not already defined.
[kopensolaris-gnu/glibc.git] / stdlib / longlong.h
index 40ccc89..397188e 100644 (file)
@@ -1,5 +1,5 @@
 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
-   Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
+   Copyright (C) 1991,92,93,94,96,97,98,99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
 #define __MPN(x) __##x
 #endif
 
+#ifndef __P
+# if defined __GNUC__ || (defined (__STDC__) && __STDC__) \
+     || defined (__cplusplus)
+#  define __P(args)    args
+# else
+#  define __P(args)    ()
+# endif
+#endif
+
 /* Define auxiliary asm macros.
 
    1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
@@ -190,6 +199,7 @@ extern UDItype __udiv_qrnnd __P ((UDItype *, UDItype, UDItype, UDItype));
             "rI" ((USItype)(bh)),                                      \
             "r" ((USItype)(al)),                                       \
             "rI" ((USItype)(bl)))
+#if 0
 #define umul_ppmm(xh, xl, a, b) \
   __asm__ ("%@ Inlined umul_ppmm
        mov     %|r0, %2, lsr #16
@@ -211,6 +221,7 @@ extern UDItype __udiv_qrnnd __P ((UDItype *, UDItype, UDItype, UDItype));
           : "r0", "r1", "r2")
 #define UMUL_TIME 20
 #define UDIV_TIME 100
+#endif
 #endif /* __arm__ */
 
 #if defined (__clipper__) && W_TYPE_SIZE == 32
@@ -1133,18 +1144,111 @@ extern USItype __udiv_qrnnd ();
 #define UMUL_TIME 39           /* 39 instructions */
 #endif
 #ifndef udiv_qrnnd
-#ifndef LONGLONG_STANDALONE
+/* It's quite necessary to add this much assembler for the sparc.
+   The default udiv_qrnnd (in C) is more than 10 times slower!  */
 #define udiv_qrnnd(q, r, n1, n0, d) \
-  do { USItype __r;                                                    \
-    (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                                \
-    (r) = __r;                                                         \
-  } while (0)
+  __asm__ ("! Inlined udiv_qrnnd
+       mov     32,%%g1
+       subcc   %1,%2,%%g0
+1:     bcs     5f
+        addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
+       sub     %1,%2,%1        ! this kills msb of n
+       addx    %1,%1,%1        ! so this can't give carry
+       subcc   %%g1,1,%%g1
+2:     bne     1b
+        subcc  %1,%2,%%g0
+       bcs     3f
+        addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
+       b       3f
+        sub    %1,%2,%1        ! this kills msb of n
+4:     sub     %1,%2,%1
+5:     addxcc  %1,%1,%1
+       bcc     2b
+        subcc  %%g1,1,%%g1
+! Got carry from n.  Subtract next step to cancel this carry.
+       bne     4b
+        addcc  %0,%0,%0        ! shift n1n0 and a 0-bit in lsb
+       sub     %1,%2,%1
+3:     xnor    %0,0,%0
+       ! End of inline udiv_qrnnd"                                     \
+          : "=&r" ((USItype)(q)),                                      \
+            "=&r" ((USItype)(r))                                       \
+          : "r" ((USItype)(d)),                                        \
+            "1" ((USItype)(n1)),                                       \
+            "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME (3+7*32)     /* 7 instructions/iteration. 32 iterations. */
+#else
 extern USItype __udiv_qrnnd __P ((USItype *, USItype, USItype, USItype));
 #define UDIV_TIME 140
-#endif /* LONGLONG_STANDALONE */
 #endif /* udiv_qrnnd */
 #endif /* __sparc__ */
 
+#if (defined (__sparc_v9__) || (defined (__sparc__) && defined (__arch64__)) \
+    || defined (__sparcv9)) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl)                             \
+  __asm__ ("addcc %4,%5,%1
+           add %2,%3,%0
+           bcs,a,pn %%xcc, 1f
+           add %0, 1, %0
+           1:"                                                         \
+          : "=r" ((UDItype)(sh)),                                      \
+            "=&r" ((UDItype)(sl))                                      \
+          : "r" ((UDItype)(ah)),                                       \
+            "r" ((UDItype)(bh)),                                       \
+            "r" ((UDItype)(al)),                                       \
+            "r" ((UDItype)(bl))                                        \
+          : "cc")
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl)                             \
+  __asm__ ("subcc %4,%5,%1
+           sub %2,%3,%0
+           bcs,a,pn %%xcc, 1f
+           sub %0, 1, %0
+           1:"                                                         \
+          : "=r" ((UDItype)(sh)),                                      \
+            "=&r" ((UDItype)(sl))                                      \
+          : "r" ((UDItype)(ah)),                                       \
+            "r" ((UDItype)(bh)),                                       \
+            "r" ((UDItype)(al)),                                       \
+            "r" ((UDItype)(bl))                                        \
+          : "cc")
+
+#define umul_ppmm(wh, wl, u, v)                                                \
+  do {                                                                 \
+         UDItype tmp1, tmp2, tmp3, tmp4;                               \
+         __asm__ __volatile__ (                                        \
+                  "srl %7,0,%3
+                   mulx %3,%6,%1
+                   srlx %6,32,%2
+                   mulx %2,%3,%4
+                   sllx %4,32,%5
+                   srl %6,0,%3
+                   sub %1,%5,%5
+                   srlx %5,32,%5
+                   addcc %4,%5,%4
+                   srlx %7,32,%5
+                   mulx %3,%5,%3
+                   mulx %2,%5,%5
+                   sethi %%hi(0x80000000),%2
+                   addcc %4,%3,%4
+                   srlx %4,32,%4
+                   add %2,%2,%2
+                   movcc %%xcc,%%g0,%2
+                   addcc %5,%4,%5
+                   sllx %3,32,%3
+                   add %1,%3,%1
+                   add %5,%2,%0"                                       \
+          : "=r" ((UDItype)(wh)),                                      \
+            "=&r" ((UDItype)(wl)),                                     \
+            "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4)     \
+          : "r" ((UDItype)(u)),                                        \
+            "r" ((UDItype)(v))                                         \
+          : "cc");                                                     \
+  } while (0)
+#define UMUL_TIME 96
+#define UDIV_TIME 230
+#endif /* __sparc_v9__ */
+
 #if defined (__vax__) && W_TYPE_SIZE == 32
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   __asm__ ("addl2 %5,%1