159691Selan /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
259691Selan    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
359691Selan 
459691Selan    This definition file is free software; you can redistribute it
559691Selan    and/or modify it under the terms of the GNU General Public
659691Selan    License as published by the Free Software Foundation; either
759691Selan    version 2, or (at your option) any later version.
859691Selan 
959691Selan    This definition file is distributed in the hope that it will be
1059691Selan    useful, but WITHOUT ANY WARRANTY; without even the implied
1159691Selan    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1259691Selan    See the GNU General Public License for more details.
1359691Selan 
1459691Selan    You should have received a copy of the GNU General Public License
1559691Selan    along with this program; if not, write to the Free Software
1659691Selan    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
1759691Selan 
1859691Selan #ifndef SI_TYPE_SIZE
1959691Selan #define SI_TYPE_SIZE 32
2059691Selan #endif
2159691Selan 
2259691Selan #define __BITS4 (SI_TYPE_SIZE / 4)
2359691Selan #define __ll_B (1L << (SI_TYPE_SIZE / 2))
2459691Selan #define __ll_lowpart(t) ((USItype) (t) % __ll_B)
2559691Selan #define __ll_highpart(t) ((USItype) (t) / __ll_B)
2659691Selan 
2759691Selan /* Define auxiliary asm macros.
2859691Selan 
2959691Selan    1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
3059691Selan    multiplies two USItype integers MULTIPLER and MULTIPLICAND,
3159691Selan    and generates a two-part USItype product in HIGH_PROD and
3259691Selan    LOW_PROD.
3359691Selan 
3459691Selan    2) __umulsidi3(a,b) multiplies two USItype integers A and B,
3559691Selan    and returns a UDItype product.  This is just a variant of umul_ppmm.
3659691Selan 
3759691Selan    3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
3859691Selan    denominator) divides a two-word unsigned integer, composed by the
3959691Selan    integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
4059691Selan    places the quotient in QUOTIENT and the remainder in REMAINDER.
4159691Selan    HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
4259691Selan    If, in addition, the most significant bit of DENOMINATOR must be 1,
4359691Selan    then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
4459691Selan 
4559691Selan    4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
4659691Selan    denominator).  Like udiv_qrnnd but the numbers are signed.  The
4759691Selan    quotient is rounded towards 0.
4859691Selan 
4959691Selan    5) count_leading_zeros(count, x) counts the number of zero-bits from
5059691Selan    the msb to the first non-zero bit.  This is the number of steps X
5159691Selan    needs to be shifted left to set the msb.  Undefined for X == 0.
5259691Selan 
5359691Selan    6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
5459691Selan    high_addend_2, low_addend_2) adds two two-word unsigned integers,
5559691Selan    composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
5659691Selan    LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
5759691Selan    LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
5859691Selan    lost.
5959691Selan 
6059691Selan    7) sub_ddmmss(high_difference, low_difference, high_minuend,
6159691Selan    low_minuend, high_subtrahend, low_subtrahend) subtracts two
6259691Selan    two-word unsigned integers, composed by HIGH_MINUEND_1 and
6359691Selan    LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
6459691Selan    respectively.  The result is placed in HIGH_DIFFERENCE and
6559691Selan    LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
6659691Selan    and is lost.
6759691Selan 
6859691Selan    If any of these macros are left undefined for a particular CPU,
6959691Selan    C macros are used.  */
7059691Selan 
7159691Selan /* The CPUs come in alphabetical order below.
7259691Selan 
7359691Selan    Please add support for more CPUs here, or improve the current support
7459691Selan    for the CPUs below!
7559691Selan    (E.g. WE32100, i960, IBM360.)  */
7659691Selan 
7759691Selan #if defined (__GNUC__) && !defined (NO_ASM)
7859691Selan 
7959691Selan /* We sometimes need to clobber "cc" with gcc2, but that would not be
8059691Selan    understood by gcc1.  Use cpp to avoid major code duplication.  */
8159691Selan #if __GNUC__ < 2
8259691Selan #define __CLOBBER_CC
8359691Selan #define __AND_CLOBBER_CC
8459691Selan #else /* __GNUC__ >= 2 */
8559691Selan #define __CLOBBER_CC : "cc"
8659691Selan #define __AND_CLOBBER_CC , "cc"
8759691Selan #endif /* __GNUC__ < 2 */
8859691Selan 
8959691Selan #if defined (__a29k__) || defined (___AM29K__)
9059691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
9159691Selan   __asm__ ("add %1,%4,%5
9259691Selan 	addc %0,%2,%3"							\
9359691Selan 	   : "=r" ((USItype)(sh)),					\
9459691Selan 	    "=&r" ((USItype)(sl))					\
9559691Selan 	   : "%r" ((USItype)(ah)),					\
9659691Selan 	     "rI" ((USItype)(bh)),					\
9759691Selan 	     "%r" ((USItype)(al)),					\
9859691Selan 	     "rI" ((USItype)(bl)))
9959691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
10059691Selan   __asm__ ("sub %1,%4,%5
10159691Selan 	subc %0,%2,%3"							\
10259691Selan 	   : "=r" ((USItype)(sh)),					\
10359691Selan 	     "=&r" ((USItype)(sl))					\
10459691Selan 	   : "r" ((USItype)(ah)),					\
10559691Selan 	     "rI" ((USItype)(bh)),					\
10659691Selan 	     "r" ((USItype)(al)),					\
10759691Selan 	     "rI" ((USItype)(bl)))
10859691Selan #define umul_ppmm(xh, xl, m0, m1) \
10959691Selan   do {									\
11059691Selan     USItype __m0 = (m0), __m1 = (m1);					\
11159691Selan     __asm__ ("multiplu %0,%1,%2"					\
11259691Selan 	     : "=r" ((USItype)(xl))					\
11359691Selan 	     : "r" (__m0),						\
11459691Selan 	       "r" (__m1));						\
11559691Selan     __asm__ ("multmu %0,%1,%2"						\
11659691Selan 	     : "=r" ((USItype)(xh))					\
11759691Selan 	     : "r" (__m0),						\
11859691Selan 	       "r" (__m1));						\
11959691Selan   } while (0)
12059691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
12159691Selan   __asm__ ("dividu %0,%3,%4"						\
12259691Selan 	   : "=r" ((USItype)(q)),					\
12359691Selan 	     "=q" ((USItype)(r))					\
12459691Selan 	   : "1" ((USItype)(n1)),					\
12559691Selan 	     "r" ((USItype)(n0)),					\
12659691Selan 	     "r" ((USItype)(d)))
12759691Selan #define count_leading_zeros(count, x) \
12859691Selan     __asm__ ("clz %0,%1"						\
12959691Selan 	     : "=r" ((USItype)(count))					\
13059691Selan 	     : "r" ((USItype)(x)))
13159691Selan #endif /* __a29k__ */
13259691Selan 
13359691Selan #if defined (__arm__)
13459691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
13559691Selan   __asm__ ("adds %1,%4,%5
13659691Selan 	adc %0,%2,%3"							\
13759691Selan 	   : "=r" ((USItype)(sh)),					\
13859691Selan 	     "=&r" ((USItype)(sl))					\
13959691Selan 	   : "%r" ((USItype)(ah)),					\
14059691Selan 	     "rI" ((USItype)(bh)),					\
14159691Selan 	     "%r" ((USItype)(al)),					\
14259691Selan 	     "rI" ((USItype)(bl)))
14359691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
14459691Selan   __asm__ ("subs %1,%4,%5
14559691Selan 	sbc %0,%2,%3"							\
14659691Selan 	   : "=r" ((USItype)(sh)),					\
14759691Selan 	     "=&r" ((USItype)(sl))					\
14859691Selan 	   : "r" ((USItype)(ah)),					\
14959691Selan 	     "rI" ((USItype)(bh)),					\
15059691Selan 	     "r" ((USItype)(al)),					\
15159691Selan 	     "rI" ((USItype)(bl)))
15259691Selan #endif /* __arm__ */
15359691Selan 
15459691Selan #if defined (__gmicro__)
15559691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
15659691Selan   __asm__ ("add.w %5,%1
15759691Selan 	addx %3,%0"							\
15859691Selan 	   : "=g" ((USItype)(sh)),					\
15959691Selan 	     "=&g" ((USItype)(sl))					\
16059691Selan 	   : "%0" ((USItype)(ah)),					\
16159691Selan 	     "g" ((USItype)(bh)),					\
16259691Selan 	     "%1" ((USItype)(al)),					\
16359691Selan 	     "g" ((USItype)(bl)))
16459691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
16559691Selan   __asm__ ("sub.w %5,%1
16659691Selan 	subx %3,%0"							\
16759691Selan 	   : "=g" ((USItype)(sh)),					\
16859691Selan 	     "=&g" ((USItype)(sl))					\
16959691Selan 	   : "0" ((USItype)(ah)),					\
17059691Selan 	     "g" ((USItype)(bh)),					\
17159691Selan 	     "1" ((USItype)(al)),					\
17259691Selan 	     "g" ((USItype)(bl)))
17359691Selan #define umul_ppmm(ph, pl, m0, m1) \
17459691Selan   __asm__ ("mulx %3,%0,%1"						\
17559691Selan 	   : "=g" ((USItype)(ph)),					\
17659691Selan 	     "=r" ((USItype)(pl))					\
17759691Selan 	   : "%0" ((USItype)(m0)),					\
17859691Selan 	     "g" ((USItype)(m1)))
17959691Selan #define udiv_qrnnd(q, r, nh, nl, d) \
18059691Selan   __asm__ ("divx %4,%0,%1"						\
18159691Selan 	   : "=g" ((USItype)(q)),					\
18259691Selan 	     "=r" ((USItype)(r))					\
18359691Selan 	   : "1" ((USItype)(nh)),					\
18459691Selan 	     "0" ((USItype)(nl)),					\
18559691Selan 	     "g" ((USItype)(d)))
18659691Selan #define count_leading_zeros(count, x) \
18759691Selan   __asm__ ("bsch/1 %1,%0"						\
18859691Selan 	   : "=g" (count)						\
18959691Selan 	   : "g" ((USItype)(x)),					\
19059691Selan 	     "0" ((USItype)0))
19159691Selan #endif
19259691Selan 
19359691Selan #if defined (__hppa)
19459691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
19559691Selan   __asm__ ("add %4,%5,%1
19659691Selan 	addc %2,%3,%0"							\
19759691Selan 	   : "=r" ((USItype)(sh)),					\
19859691Selan 	     "=&r" ((USItype)(sl))					\
19959691Selan 	   : "%rM" ((USItype)(ah)),					\
20059691Selan 	     "rM" ((USItype)(bh)),					\
20159691Selan 	     "%rM" ((USItype)(al)),					\
20259691Selan 	     "rM" ((USItype)(bl)))
20359691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
20459691Selan   __asm__ ("sub %4,%5,%1
20559691Selan 	subb %2,%3,%0"							\
20659691Selan 	   : "=r" ((USItype)(sh)),					\
20759691Selan 	     "=&r" ((USItype)(sl))					\
20859691Selan 	   : "rM" ((USItype)(ah)),					\
20959691Selan 	     "rM" ((USItype)(bh)),					\
21059691Selan 	     "rM" ((USItype)(al)),					\
21159691Selan 	     "rM" ((USItype)(bl)))
21259691Selan #if defined (_PA_RISC1_1)
21359691Selan #define umul_ppmm(w1, w0, u, v) \
21459691Selan   do {									\
21559691Selan     union								\
21659691Selan       {									\
21759691Selan 	UDItype __f;							\
21859691Selan 	struct {USItype __w1, __w0;} __w1w0;				\
21959691Selan       } __t;								\
22059691Selan     __asm__ ("xmpyu %1,%2,%0"						\
22159691Selan 	     : "=x" (__t.__f)						\
22259691Selan 	     : "x" ((USItype)(u)),					\
22359691Selan 	       "x" ((USItype)(v)));					\
22459691Selan     (w1) = __t.__w1w0.__w1;						\
22559691Selan     (w0) = __t.__w1w0.__w0;						\
22659691Selan      } while (0)
22759691Selan #define UMUL_TIME 8
22859691Selan #else
22959691Selan #define UMUL_TIME 30
23059691Selan #endif
23159691Selan #define UDIV_TIME 40
23259691Selan #endif
23359691Selan 
23459691Selan #if defined (__i386__) || defined (__i486__)
23559691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
23659691Selan   __asm__ ("addl %5,%1
23759691Selan 	adcl %3,%0"							\
23859691Selan 	   : "=r" ((USItype)(sh)),					\
23959691Selan 	     "=&r" ((USItype)(sl))					\
24059691Selan 	   : "%0" ((USItype)(ah)),					\
24159691Selan 	     "g" ((USItype)(bh)),					\
24259691Selan 	     "%1" ((USItype)(al)),					\
24359691Selan 	     "g" ((USItype)(bl)))
24459691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
24559691Selan   __asm__ ("subl %5,%1
24659691Selan 	sbbl %3,%0"							\
24759691Selan 	   : "=r" ((USItype)(sh)),					\
24859691Selan 	     "=&r" ((USItype)(sl))					\
24959691Selan 	   : "0" ((USItype)(ah)),					\
25059691Selan 	     "g" ((USItype)(bh)),					\
25159691Selan 	     "1" ((USItype)(al)),					\
25259691Selan 	     "g" ((USItype)(bl)))
25359691Selan #define umul_ppmm(w1, w0, u, v) \
25459691Selan   __asm__ ("mull %3"							\
25559691Selan 	   : "=a" ((USItype)(w0)),					\
25659691Selan 	     "=d" ((USItype)(w1))					\
25759691Selan 	   : "%0" ((USItype)(u)),					\
25859691Selan 	     "rm" ((USItype)(v)))
25959691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
26059691Selan   __asm__ ("divl %4"							\
26159691Selan 	   : "=a" ((USItype)(q)),					\
26259691Selan 	     "=d" ((USItype)(r))					\
26359691Selan 	   : "0" ((USItype)(n0)),					\
26459691Selan 	     "1" ((USItype)(n1)),					\
26559691Selan 	     "rm" ((USItype)(d)))
26659691Selan #define count_leading_zeros(count, x) \
26759691Selan   do {									\
26859691Selan     USItype __cbtmp;							\
26959691Selan     __asm__ ("bsrl %1,%0"						\
27059691Selan 	     : "=r" (__cbtmp) : "rm" ((USItype)(x)));			\
27159691Selan     (count) = __cbtmp ^ 31;						\
27259691Selan   } while (0)
27359691Selan #define UMUL_TIME 40
27459691Selan #define UDIV_TIME 40
27559691Selan #endif /* 80x86 */
27659691Selan 
27759691Selan #if defined (__i860__)
27859691Selan #if 0
27959691Selan /* Make sure these patterns really improve the code before
28059691Selan    switching them on.  */
28159691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
28259691Selan   do {									\
28359691Selan     union								\
28459691Selan       {									\
28559691Selan 	DItype __ll;							\
28659691Selan 	struct {USItype __l, __h;} __i;					\
28759691Selan       }  __a, __b, __s;							\
28859691Selan     __a.__i.__l = (al);							\
28959691Selan     __a.__i.__h = (ah);							\
29059691Selan     __b.__i.__l = (bl);							\
29159691Selan     __b.__i.__h = (bh);							\
29259691Selan     __asm__ ("fiadd.dd %1,%2,%0"					\
29359691Selan 	     : "=f" (__s.__ll)						\
29459691Selan 	     : "%f" (__a.__ll), "f" (__b.__ll));			\
29559691Selan     (sh) = __s.__i.__h;							\
29659691Selan     (sl) = __s.__i.__l;							\
29759691Selan     } while (0)
29859691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
29959691Selan   do {									\
30059691Selan     union								\
30159691Selan       {									\
30259691Selan 	DItype __ll;							\
30359691Selan 	struct {USItype __l, __h;} __i;					\
30459691Selan       }  __a, __b, __s;							\
30559691Selan     __a.__i.__l = (al);							\
30659691Selan     __a.__i.__h = (ah);							\
30759691Selan     __b.__i.__l = (bl);							\
30859691Selan     __b.__i.__h = (bh);							\
30959691Selan     __asm__ ("fisub.dd %1,%2,%0"					\
31059691Selan 	     : "=f" (__s.__ll)						\
31159691Selan 	     : "%f" (__a.__ll), "f" (__b.__ll));			\
31259691Selan     (sh) = __s.__i.__h;							\
31359691Selan     (sl) = __s.__i.__l;							\
31459691Selan     } while (0)
31559691Selan #endif
31659691Selan #endif /* __i860__ */
31759691Selan 
31859691Selan #if defined (___IBMR2__) /* IBM RS6000 */
31959691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
32059691Selan   __asm__ ("a%I5 %1,%4,%5
32159691Selan 	ae %0,%2,%3"							\
32259691Selan 	   : "=r" ((USItype)(sh)),					\
32359691Selan 	     "=&r" ((USItype)(sl))					\
32459691Selan 	   : "%r" ((USItype)(ah)),					\
32559691Selan 	     "r" ((USItype)(bh)),					\
32659691Selan 	     "%r" ((USItype)(al)),					\
32759691Selan 	     "rI" ((USItype)(bl)))
32859691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
32959691Selan   __asm__ ("sf%I4 %1,%5,%4
33059691Selan 	sfe %0,%3,%2"							\
33159691Selan 	   : "=r" ((USItype)(sh)),					\
33259691Selan 	     "=&r" ((USItype)(sl))					\
33359691Selan 	   : "r" ((USItype)(ah)),					\
33459691Selan 	     "r" ((USItype)(bh)),					\
33559691Selan 	     "rI" ((USItype)(al)),					\
33659691Selan 	     "r" ((USItype)(bl)))
33759691Selan #define umul_ppmm(xh, xl, m0, m1) \
33859691Selan   do {									\
33959691Selan     USItype __m0 = (m0), __m1 = (m1);					\
34059691Selan     __asm__ ("mul %0,%2,%3"						\
34159691Selan 	     : "=r" ((USItype)(xh)),					\
34259691Selan 	       "=q" ((USItype)(xl))					\
34359691Selan 	     : "r" (__m0),						\
34459691Selan 	       "r" (__m1));						\
34559691Selan     (xh) += ((((SItype) __m0 >> 31) & __m1)				\
34659691Selan 	     + (((SItype) __m1 >> 31) & __m0));				\
34759691Selan   } while (0)
34859691Selan #define smul_ppmm(xh, xl, m0, m1) \
34959691Selan   __asm__ ("mul %0,%2,%3"						\
35059691Selan 	   : "=r" ((USItype)(xh)),					\
35159691Selan 	     "=q" ((USItype)(xl))					\
35259691Selan 	   : "r" ((USItype)(m0)),					\
35359691Selan 	     "r" ((USItype)(m1)))
35459691Selan #define UMUL_TIME 8
35559691Selan #define sdiv_qrnnd(q, r, nh, nl, d) \
35659691Selan   __asm__ ("div %0,%2,%4"						\
35759691Selan 	   : "=r" ((USItype)(q)), "=q" ((USItype)(r))			\
35859691Selan 	   : "r" ((USItype)(nh)), "1" ((USItype)(nl)), "r" ((USItype)(d)))
35959691Selan #define UDIV_TIME 40
36059691Selan #define UDIV_NEEDS_NORMALIZATION 1
36159691Selan #define count_leading_zeros(count, x) \
36259691Selan   __asm__ ("cntlz %0,%1"						\
36359691Selan 	   : "=r" ((USItype)(count))					\
36459691Selan 	   : "r" ((USItype)(x)))
36559691Selan #endif /* ___IBMR2__ */
36659691Selan 
36759691Selan #if defined (__mc68000__)
36859691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
36959691Selan   __asm__ ("add%.l %5,%1
37059691Selan 	addx%.l %3,%0"							\
37159691Selan 	   : "=d" ((USItype)(sh)),					\
37259691Selan 	     "=&d" ((USItype)(sl))					\
37359691Selan 	   : "%0" ((USItype)(ah)),					\
37459691Selan 	     "d" ((USItype)(bh)),					\
37559691Selan 	     "%1" ((USItype)(al)),					\
37659691Selan 	     "g" ((USItype)(bl)))
37759691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
37859691Selan   __asm__ ("sub%.l %5,%1
37959691Selan 	subx%.l %3,%0"							\
38059691Selan 	   : "=d" ((USItype)(sh)),					\
38159691Selan 	     "=&d" ((USItype)(sl))					\
38259691Selan 	   : "0" ((USItype)(ah)),					\
38359691Selan 	     "d" ((USItype)(bh)),					\
38459691Selan 	     "1" ((USItype)(al)),					\
38559691Selan 	     "g" ((USItype)(bl)))
38659691Selan #if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)
38759691Selan #define umul_ppmm(w1, w0, u, v) \
38859691Selan   __asm__ ("mulu%.l %3,%1:%0"						\
38959691Selan 	   : "=d" ((USItype)(w0)),					\
39059691Selan 	     "=d" ((USItype)(w1))					\
39159691Selan 	   : "%0" ((USItype)(u)),					\
39259691Selan 	     "dmi" ((USItype)(v)))
39359691Selan #define UMUL_TIME 45
39459691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
39559691Selan   __asm__ ("divu%.l %4,%1:%0"						\
39659691Selan 	   : "=d" ((USItype)(q)),					\
39759691Selan 	     "=d" ((USItype)(r))					\
39859691Selan 	   : "0" ((USItype)(n0)),					\
39959691Selan 	     "1" ((USItype)(n1)),					\
40059691Selan 	     "dmi" ((USItype)(d)))
40159691Selan #define UDIV_TIME 90
40259691Selan #define sdiv_qrnnd(q, r, n1, n0, d) \
40359691Selan   __asm__ ("divs%.l %4,%1:%0"						\
40459691Selan 	   : "=d" ((USItype)(q)),					\
40559691Selan 	     "=d" ((USItype)(r))					\
40659691Selan 	   : "0" ((USItype)(n0)),					\
40759691Selan 	     "1" ((USItype)(n1)),					\
40859691Selan 	     "dmi" ((USItype)(d)))
40959691Selan #define count_leading_zeros(count, x) \
41059691Selan   __asm__ ("bfffo %1{%b2:%b2},%0"					\
41159691Selan 	   : "=d" ((USItype)(count))					\
41259691Selan 	   : "od" ((USItype)(x)), "n" (0))
41359691Selan #else /* not mc68020 */
414*60380Selan /* %/ inserts REGISTER_PREFIX.  */
41559691Selan #define umul_ppmm(xh, xl, a, b) \
41659691Selan   __asm__ ("| Inlined umul_ppmm
417*60380Selan 	movel	%2,%/d0
418*60380Selan 	movel	%3,%/d1
419*60380Selan 	movel	%/d0,%/d2
420*60380Selan 	swap	%/d0
421*60380Selan 	movel	%/d1,%/d3
422*60380Selan 	swap	%/d1
423*60380Selan 	movew	%/d2,%/d4
424*60380Selan 	mulu	%/d3,%/d4
425*60380Selan 	mulu	%/d1,%/d2
426*60380Selan 	mulu	%/d0,%/d3
427*60380Selan 	mulu	%/d0,%/d1
428*60380Selan 	movel	%/d4,%/d0
429*60380Selan 	eorw	%/d0,%/d0
430*60380Selan 	swap	%/d0
431*60380Selan 	addl	%/d0,%/d2
432*60380Selan 	addl	%/d3,%/d2
43359691Selan 	jcc	1f
434*60380Selan 	addl	#65536,%/d1
435*60380Selan 1:	swap	%/d2
436*60380Selan 	moveq	#0,%/d0
437*60380Selan 	movew	%/d2,%/d0
438*60380Selan 	movew	%/d4,%/d2
439*60380Selan 	movel	%/d2,%1
440*60380Selan 	addl	%/d1,%/d0
441*60380Selan 	movel	%/d0,%0"						\
44259691Selan 	   : "=g" ((USItype)(xh)),					\
44359691Selan 	     "=g" ((USItype)(xl))					\
44459691Selan 	   : "g" ((USItype)(a)),					\
44559691Selan 	     "g" ((USItype)(b))						\
44659691Selan 	   : "d0", "d1", "d2", "d3", "d4")
44759691Selan #define UMUL_TIME 100
44859691Selan #define UDIV_TIME 400
44959691Selan #endif /* not mc68020 */
45059691Selan #endif /* mc68000 */
45159691Selan 
45259691Selan #if defined (__m88000__)
45359691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
45459691Selan   __asm__ ("addu.co %1,%r4,%r5
45559691Selan 	addu.ci %0,%r2,%r3"						\
45659691Selan 	   : "=r" ((USItype)(sh)),					\
45759691Selan 	     "=&r" ((USItype)(sl))					\
45859691Selan 	   : "%rJ" ((USItype)(ah)),					\
45959691Selan 	     "rJ" ((USItype)(bh)),					\
46059691Selan 	     "%rJ" ((USItype)(al)),					\
46159691Selan 	     "rJ" ((USItype)(bl)))
46259691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
46359691Selan   __asm__ ("subu.co %1,%r4,%r5
46459691Selan 	subu.ci %0,%r2,%r3"						\
46559691Selan 	   : "=r" ((USItype)(sh)),					\
46659691Selan 	     "=&r" ((USItype)(sl))					\
46759691Selan 	   : "rJ" ((USItype)(ah)),					\
46859691Selan 	     "rJ" ((USItype)(bh)),					\
46959691Selan 	     "rJ" ((USItype)(al)),					\
47059691Selan 	     "rJ" ((USItype)(bl)))
47159691Selan #define UMUL_TIME 17
47259691Selan #define UDIV_TIME 150
47359691Selan #define count_leading_zeros(count, x) \
47459691Selan   do {									\
47559691Selan     USItype __cbtmp;							\
47659691Selan     __asm__ ("ff1 %0,%1"						\
47759691Selan 	     : "=r" (__cbtmp)						\
47859691Selan 	     : "r" ((USItype)(x)));					\
47959691Selan     (count) = __cbtmp ^ 31;						\
48059691Selan   } while (0)
48159691Selan #if defined (__mc88110__)
48259691Selan #define umul_ppmm(w1, w0, u, v) \
48359691Selan   __asm__ ("mulu.d	r10,%2,%3
48459691Selan 	or	%0,r10,0
48559691Selan 	or	%1,r11,0"						\
48659691Selan 	   : "=r" (w1),							\
48759691Selan 	     "=r" (w0)							\
48859691Selan 	   : "r" ((USItype)(u)),					\
48959691Selan 	     "r" ((USItype)(v))						\
49059691Selan 	   : "r10", "r11")
49159691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
49259691Selan   __asm__ ("or	r10,%2,0
49359691Selan 	or	r11,%3,0
49459691Selan 	divu.d	r10,r10,%4
49559691Selan 	mulu	%1,%4,r11
49659691Selan 	subu	%1,%3,%1
49759691Selan 	or	%0,r11,0"						\
49859691Selan 	   : "=r" (q),							\
49959691Selan 	     "=&r" (r)							\
50059691Selan 	   : "r" ((USItype)(n1)),					\
50159691Selan 	     "r" ((USItype)(n0)),					\
50259691Selan 	     "r" ((USItype)(d))						\
50359691Selan 	   : "r10", "r11")
50459691Selan #endif
50559691Selan #endif /* __m88000__ */
50659691Selan 
50759691Selan #if defined (__mips__)
50859691Selan #define umul_ppmm(w1, w0, u, v) \
50959691Selan   __asm__ ("multu %2,%3
51059691Selan 	mflo %0
51159691Selan 	mfhi %1"							\
51259691Selan 	   : "=d" ((USItype)(w0)),					\
51359691Selan 	     "=d" ((USItype)(w1))					\
51459691Selan 	   : "d" ((USItype)(u)),					\
51559691Selan 	     "d" ((USItype)(v)))
51659691Selan #define UMUL_TIME 5
51759691Selan #define UDIV_TIME 100
51859691Selan #endif /* __mips__ */
51959691Selan 
52059691Selan #if defined (__ns32000__)
52159691Selan #define __umulsidi3(u, v) \
52259691Selan   ({UDItype __w;							\
52359691Selan     __asm__ ("meid %2,%0"						\
52459691Selan 	     : "=g" (__w)						\
52559691Selan 	     : "%0" ((USItype)(u)),					\
52659691Selan 	       "g" ((USItype)(v)));					\
52759691Selan     __w; })
52859691Selan #define div_qrnnd(q, r, n1, n0, d) \
52959691Selan   __asm__ ("movd %2,r0
53059691Selan 	movd %3,r1
53159691Selan 	deid %4,r0
53259691Selan 	movd r1,%0
53359691Selan 	movd r0,%1"							\
53459691Selan 	   : "=g" ((USItype)(q)),					\
53559691Selan 	     "=g" ((USItype)(r))					\
53659691Selan 	   : "g" ((USItype)(n0)),					\
53759691Selan 	     "g" ((USItype)(n1)),					\
53859691Selan 	     "g" ((USItype)(d))						\
53959691Selan 	   : "r0", "r1")
54059691Selan #endif /* __ns32000__ */
54159691Selan 
54259691Selan #if defined (__pyr__)
54359691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
54459691Selan   __asm__ ("addw	%5,%1
54559691Selan 	addwc	%3,%0"							\
54659691Selan 	   : "=r" ((USItype)(sh)),					\
54759691Selan 	     "=&r" ((USItype)(sl))					\
54859691Selan 	   : "%0" ((USItype)(ah)),					\
54959691Selan 	     "g" ((USItype)(bh)),					\
55059691Selan 	     "%1" ((USItype)(al)),					\
55159691Selan 	     "g" ((USItype)(bl)))
55259691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
55359691Selan   __asm__ ("subw	%5,%1
55459691Selan 	subwb	%3,%0"							\
55559691Selan 	   : "=r" ((USItype)(sh)),					\
55659691Selan 	     "=&r" ((USItype)(sl))					\
55759691Selan 	   : "0" ((USItype)(ah)),					\
55859691Selan 	     "g" ((USItype)(bh)),					\
55959691Selan 	     "1" ((USItype)(al)),					\
56059691Selan 	     "g" ((USItype)(bl)))
56159691Selan /* This insn doesn't work on ancient pyramids.  */
56259691Selan #define umul_ppmm(w1, w0, u, v) \
56359691Selan   ({union {								\
56459691Selan 	UDItype __ll;							\
56559691Selan 	struct {USItype __h, __l;} __i;					\
56659691Selan      } __xx;								\
56759691Selan   __xx.__i.__l = u;							\
56859691Selan   __asm__ ("uemul %3,%0"						\
56959691Selan 	   : "=r" (__xx.__i.__h),					\
57059691Selan 	     "=r" (__xx.__i.__l)					\
57159691Selan 	   : "1" (__xx.__i.__l),					\
57259691Selan 	     "g" ((UDItype)(v)));					\
57359691Selan   (w1) = __xx.__i.__h;							\
57459691Selan   (w0) = __xx.__i.__l;})
57559691Selan #endif /* __pyr__ */
57659691Selan 
57759691Selan #if defined (__ibm032__) /* RT/ROMP */
57859691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
57959691Selan   __asm__ ("a %1,%5
58059691Selan 	ae %0,%3"							\
58159691Selan 	   : "=r" ((USItype)(sh)),					\
58259691Selan 	     "=&r" ((USItype)(sl))					\
58359691Selan 	   : "%0" ((USItype)(ah)),					\
58459691Selan 	     "r" ((USItype)(bh)),					\
58559691Selan 	     "%1" ((USItype)(al)),					\
58659691Selan 	     "r" ((USItype)(bl)))
58759691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
58859691Selan   __asm__ ("s %1,%5
58959691Selan 	se %0,%3"							\
59059691Selan 	   : "=r" ((USItype)(sh)),					\
59159691Selan 	     "=&r" ((USItype)(sl))					\
59259691Selan 	   : "0" ((USItype)(ah)),					\
59359691Selan 	     "r" ((USItype)(bh)),					\
59459691Selan 	     "1" ((USItype)(al)),					\
59559691Selan 	     "r" ((USItype)(bl)))
59659691Selan #define umul_ppmm(ph, pl, m0, m1) \
59759691Selan   do {									\
59859691Selan     USItype __m0 = (m0), __m1 = (m1);					\
59959691Selan     __asm__ (								\
60059691Selan        "s	r2,r2
60159691Selan 	mts	r10,%2
60259691Selan 	m	r2,%3
60359691Selan 	m	r2,%3
60459691Selan 	m	r2,%3
60559691Selan 	m	r2,%3
60659691Selan 	m	r2,%3
60759691Selan 	m	r2,%3
60859691Selan 	m	r2,%3
60959691Selan 	m	r2,%3
61059691Selan 	m	r2,%3
61159691Selan 	m	r2,%3
61259691Selan 	m	r2,%3
61359691Selan 	m	r2,%3
61459691Selan 	m	r2,%3
61559691Selan 	m	r2,%3
61659691Selan 	m	r2,%3
61759691Selan 	m	r2,%3
61859691Selan 	cas	%0,r2,r0
61959691Selan 	mfs	r10,%1"							\
62059691Selan 	     : "=r" ((USItype)(ph)),					\
62159691Selan 	       "=r" ((USItype)(pl))					\
62259691Selan 	     : "%r" (__m0),						\
62359691Selan 		"r" (__m1)						\
62459691Selan 	     : "r2");							\
62559691Selan     (ph) += ((((SItype) __m0 >> 31) & __m1)				\
62659691Selan 	     + (((SItype) __m1 >> 31) & __m0));				\
62759691Selan   } while (0)
62859691Selan #define UMUL_TIME 20
62959691Selan #define UDIV_TIME 200
63059691Selan #define count_leading_zeros(count, x) \
63159691Selan   do {									\
63259691Selan     if ((x) >= 0x10000)							\
63359691Selan       __asm__ ("clz	%0,%1"						\
63459691Selan 	       : "=r" ((USItype)(count))				\
63559691Selan 	       : "r" ((USItype)(x) >> 16));				\
63659691Selan     else								\
63759691Selan       {									\
63859691Selan 	__asm__ ("clz	%0,%1"						\
63959691Selan 		 : "=r" ((USItype)(count))				\
64059691Selan 		 : "r" ((USItype)(x)));					\
64159691Selan 	(count) += 16;							\
64259691Selan       }									\
64359691Selan   } while (0)
64459691Selan #endif
64559691Selan 
64659691Selan #if defined (__sparc__)
64759691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
64859691Selan   __asm__ ("addcc %4,%5,%1
64959691Selan 	addx %2,%3,%0"							\
65059691Selan 	   : "=r" ((USItype)(sh)),					\
65159691Selan 	     "=&r" ((USItype)(sl))					\
65259691Selan 	   : "%r" ((USItype)(ah)),					\
65359691Selan 	     "rI" ((USItype)(bh)),					\
65459691Selan 	     "%r" ((USItype)(al)),					\
65559691Selan 	     "rI" ((USItype)(bl))					\
65659691Selan 	   __CLOBBER_CC)
65759691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
65859691Selan   __asm__ ("subcc %4,%5,%1
65959691Selan 	subx %2,%3,%0"							\
66059691Selan 	   : "=r" ((USItype)(sh)),					\
66159691Selan 	     "=&r" ((USItype)(sl))					\
66259691Selan 	   : "r" ((USItype)(ah)),					\
66359691Selan 	     "rI" ((USItype)(bh)),					\
66459691Selan 	     "r" ((USItype)(al)),					\
66559691Selan 	     "rI" ((USItype)(bl))					\
66659691Selan 	   __CLOBBER_CC)
66759691Selan #if defined (__sparc_v8__)
66859691Selan #define umul_ppmm(w1, w0, u, v) \
66959691Selan   __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
67059691Selan 	   : "=r" ((USItype)(w1)),					\
67159691Selan 	     "=r" ((USItype)(w0))					\
67259691Selan 	   : "r" ((USItype)(u)),					\
67359691Selan 	     "r" ((USItype)(v)))
67459691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
67559691Selan   __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
67659691Selan 	   : "=&r" ((USItype)(q)),					\
67759691Selan 	     "=&r" ((USItype)(r))					\
67859691Selan 	   : "r" ((USItype)(n1)),					\
67959691Selan 	     "r" ((USItype)(n0)),					\
68059691Selan 	     "r" ((USItype)(d)))
68159691Selan #else
68259691Selan #if defined (__sparclite__)
68359691Selan /* This has hardware multiply but not divide.  It also has two additional
68459691Selan    instructions scan (ffs from high bit) and divscc.  */
68559691Selan #define umul_ppmm(w1, w0, u, v) \
68659691Selan   __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
68759691Selan 	   : "=r" ((USItype)(w1)),					\
68859691Selan 	     "=r" ((USItype)(w0))					\
68959691Selan 	   : "r" ((USItype)(u)),					\
69059691Selan 	     "r" ((USItype)(v)))
69159691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
69259691Selan   __asm__ ("! Inlined udiv_qrnnd
69359691Selan 	wr	%%g0,%2,%%y	! Not a delayed write for sparclite
69459691Selan 	tst	%%g0
69559691Selan 	divscc	%3,%4,%%g1
69659691Selan 	divscc	%%g1,%4,%%g1
69759691Selan 	divscc	%%g1,%4,%%g1
69859691Selan 	divscc	%%g1,%4,%%g1
69959691Selan 	divscc	%%g1,%4,%%g1
70059691Selan 	divscc	%%g1,%4,%%g1
70159691Selan 	divscc	%%g1,%4,%%g1
70259691Selan 	divscc	%%g1,%4,%%g1
70359691Selan 	divscc	%%g1,%4,%%g1
70459691Selan 	divscc	%%g1,%4,%%g1
70559691Selan 	divscc	%%g1,%4,%%g1
70659691Selan 	divscc	%%g1,%4,%%g1
70759691Selan 	divscc	%%g1,%4,%%g1
70859691Selan 	divscc	%%g1,%4,%%g1
70959691Selan 	divscc	%%g1,%4,%%g1
71059691Selan 	divscc	%%g1,%4,%%g1
71159691Selan 	divscc	%%g1,%4,%%g1
71259691Selan 	divscc	%%g1,%4,%%g1
71359691Selan 	divscc	%%g1,%4,%%g1
71459691Selan 	divscc	%%g1,%4,%%g1
71559691Selan 	divscc	%%g1,%4,%%g1
71659691Selan 	divscc	%%g1,%4,%%g1
71759691Selan 	divscc	%%g1,%4,%%g1
71859691Selan 	divscc	%%g1,%4,%%g1
71959691Selan 	divscc	%%g1,%4,%%g1
72059691Selan 	divscc	%%g1,%4,%%g1
72159691Selan 	divscc	%%g1,%4,%%g1
72259691Selan 	divscc	%%g1,%4,%%g1
72359691Selan 	divscc	%%g1,%4,%%g1
72459691Selan 	divscc	%%g1,%4,%%g1
72559691Selan 	divscc	%%g1,%4,%%g1
72659691Selan 	divscc	%%g1,%4,%0
72759691Selan 	rd	%%y,%1
72859691Selan 	bl,a 1f
72959691Selan 	add	%1,%4,%1
73059691Selan 1:	! End of inline udiv_qrnnd"					\
73159691Selan 	   : "=r" ((USItype)(q)),					\
73259691Selan 	     "=r" ((USItype)(r))					\
73359691Selan 	   : "r" ((USItype)(n1)),					\
73459691Selan 	     "r" ((USItype)(n0)),					\
73559691Selan 	     "rI" ((USItype)(d))					\
73659691Selan 	   : "%g1" __AND_CLOBBER_CC)
73759691Selan #define UDIV_TIME 37
73859691Selan #define count_leading_zeros(count, x) \
73959691Selan   __asm__ ("scan %1,0,%0"						\
74059691Selan 	   : "=r" ((USItype)(x))					\
74159691Selan 	   : "r" ((USItype)(count)))
74259691Selan #else
74359691Selan /* SPARC without integer multiplication and divide instructions.
74459691Selan    (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
74559691Selan #define umul_ppmm(w1, w0, u, v) \
74659691Selan   __asm__ ("! Inlined umul_ppmm
74759691Selan 	wr	%%g0,%2,%%y	! SPARC has 0-3 delay insn after a wr
74859691Selan 	sra	%3,31,%%g2	! Don't move this insn
74959691Selan 	and	%2,%%g2,%%g2	! Don't move this insn
75059691Selan 	andcc	%%g0,0,%%g1	! Don't move this insn
75159691Selan 	mulscc	%%g1,%3,%%g1
75259691Selan 	mulscc	%%g1,%3,%%g1
75359691Selan 	mulscc	%%g1,%3,%%g1
75459691Selan 	mulscc	%%g1,%3,%%g1
75559691Selan 	mulscc	%%g1,%3,%%g1
75659691Selan 	mulscc	%%g1,%3,%%g1
75759691Selan 	mulscc	%%g1,%3,%%g1
75859691Selan 	mulscc	%%g1,%3,%%g1
75959691Selan 	mulscc	%%g1,%3,%%g1
76059691Selan 	mulscc	%%g1,%3,%%g1
76159691Selan 	mulscc	%%g1,%3,%%g1
76259691Selan 	mulscc	%%g1,%3,%%g1
76359691Selan 	mulscc	%%g1,%3,%%g1
76459691Selan 	mulscc	%%g1,%3,%%g1
76559691Selan 	mulscc	%%g1,%3,%%g1
76659691Selan 	mulscc	%%g1,%3,%%g1
76759691Selan 	mulscc	%%g1,%3,%%g1
76859691Selan 	mulscc	%%g1,%3,%%g1
76959691Selan 	mulscc	%%g1,%3,%%g1
77059691Selan 	mulscc	%%g1,%3,%%g1
77159691Selan 	mulscc	%%g1,%3,%%g1
77259691Selan 	mulscc	%%g1,%3,%%g1
77359691Selan 	mulscc	%%g1,%3,%%g1
77459691Selan 	mulscc	%%g1,%3,%%g1
77559691Selan 	mulscc	%%g1,%3,%%g1
77659691Selan 	mulscc	%%g1,%3,%%g1
77759691Selan 	mulscc	%%g1,%3,%%g1
77859691Selan 	mulscc	%%g1,%3,%%g1
77959691Selan 	mulscc	%%g1,%3,%%g1
78059691Selan 	mulscc	%%g1,%3,%%g1
78159691Selan 	mulscc	%%g1,%3,%%g1
78259691Selan 	mulscc	%%g1,%3,%%g1
78359691Selan 	mulscc	%%g1,0,%%g1
78459691Selan 	add	%%g1,%%g2,%0
78559691Selan 	rd	%%y,%1"							\
78659691Selan 	   : "=r" ((USItype)(w1)),					\
78759691Selan 	     "=r" ((USItype)(w0))					\
78859691Selan 	   : "%rI" ((USItype)(u)),					\
78959691Selan 	     "r" ((USItype)(v))						\
79059691Selan 	   : "%g1", "%g2" __AND_CLOBBER_CC)
79159691Selan #define UMUL_TIME 39		/* 39 instructions */
79259691Selan /* It's quite necessary to add this much assembler for the sparc.
79359691Selan    The default udiv_qrnnd (in C) is more than 10 times slower!  */
79459691Selan #define udiv_qrnnd(q, r, n1, n0, d) \
79559691Selan   __asm__ ("! Inlined udiv_qrnnd
79659691Selan 	mov	32,%%g1
79759691Selan 	subcc	%1,%2,%%g0
79859691Selan 1:	bcs	5f
79959691Selan 	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb
80059691Selan 	sub	%1,%2,%1	! this kills msb of n
80159691Selan 	addx	%1,%1,%1	! so this can't give carry
80259691Selan 	subcc	%%g1,1,%%g1
80359691Selan 2:	bne	1b
80459691Selan 	 subcc	%1,%2,%%g0
80559691Selan 	bcs	3f
80659691Selan 	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb
80759691Selan 	b	3f
80859691Selan 	 sub	%1,%2,%1	! this kills msb of n
80959691Selan 4:	sub	%1,%2,%1
81059691Selan 5:	addxcc	%1,%1,%1
81159691Selan 	bcc	2b
81259691Selan 	 subcc	%%g1,1,%%g1
81359691Selan ! Got carry from n.  Subtract next step to cancel this carry.
81459691Selan 	bne	4b
81559691Selan 	 addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb
81659691Selan 	sub	%1,%2,%1
81759691Selan 3:	xnor	%0,0,%0
81859691Selan 	! End of inline udiv_qrnnd"					\
81959691Selan 	   : "=&r" ((USItype)(q)),					\
82059691Selan 	     "=&r" ((USItype)(r))					\
82159691Selan 	   : "r" ((USItype)(d)),					\
82259691Selan 	     "1" ((USItype)(n1)),					\
82359691Selan 	     "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC)
82459691Selan #define UDIV_TIME (3+7*32)	/* 7 instructions/iteration. 32 iterations. */
82559691Selan #endif /* __sparclite__ */
82659691Selan #endif /* __sparc_v8__ */
82759691Selan #endif /* __sparc__ */
82859691Selan 
82959691Selan #if defined (__vax__)
83059691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
83159691Selan   __asm__ ("addl2 %5,%1
83259691Selan 	adwc %3,%0"							\
83359691Selan 	   : "=g" ((USItype)(sh)),					\
83459691Selan 	     "=&g" ((USItype)(sl))					\
83559691Selan 	   : "%0" ((USItype)(ah)),					\
83659691Selan 	     "g" ((USItype)(bh)),					\
83759691Selan 	     "%1" ((USItype)(al)),					\
83859691Selan 	     "g" ((USItype)(bl)))
83959691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
84059691Selan   __asm__ ("subl2 %5,%1
84159691Selan 	sbwc %3,%0"							\
84259691Selan 	   : "=g" ((USItype)(sh)),					\
84359691Selan 	     "=&g" ((USItype)(sl))					\
84459691Selan 	   : "0" ((USItype)(ah)),					\
84559691Selan 	     "g" ((USItype)(bh)),					\
84659691Selan 	     "1" ((USItype)(al)),					\
84759691Selan 	     "g" ((USItype)(bl)))
84859691Selan #define umul_ppmm(xh, xl, m0, m1) \
84959691Selan   do {									\
85059691Selan     union {								\
85159691Selan 	UDItype __ll;							\
85259691Selan 	struct {USItype __l, __h;} __i;					\
85359691Selan       } __xx;								\
85459691Selan     USItype __m0 = (m0), __m1 = (m1);					\
85559691Selan     __asm__ ("emul %1,%2,$0,%0"						\
85659691Selan 	     : "=r" (__xx.__ll)						\
85759691Selan 	     : "g" (__m0),						\
85859691Selan 	       "g" (__m1));						\
85959691Selan     (xh) = __xx.__i.__h;						\
86059691Selan     (xl) = __xx.__i.__l;						\
86159691Selan     (xh) += ((((SItype) __m0 >> 31) & __m1)				\
86259691Selan 	     + (((SItype) __m1 >> 31) & __m0));				\
86359691Selan   } while (0)
86459691Selan #endif /* __vax__ */
86559691Selan 
86659691Selan #endif /* __GNUC__ */
86759691Selan 
86859691Selan /* If this machine has no inline assembler, use C macros.  */
86959691Selan 
87059691Selan #if !defined (add_ssaaaa)
87159691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
87259691Selan   do {									\
87359691Selan     USItype __x;							\
87459691Selan     __x = (al) + (bl);							\
87559691Selan     (sh) = (ah) + (bh) + (__x < (al));					\
87659691Selan     (sl) = __x;								\
87759691Selan   } while (0)
87859691Selan #endif
87959691Selan 
88059691Selan #if !defined (sub_ddmmss)
88159691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
88259691Selan   do {									\
88359691Selan     USItype __x;							\
88459691Selan     __x = (al) - (bl);							\
88559691Selan     (sh) = (ah) - (bh) - (__x > (al));					\
88659691Selan     (sl) = __x;								\
88759691Selan   } while (0)
88859691Selan #endif
88959691Selan 
89059691Selan #if !defined (umul_ppmm)
89159691Selan #define umul_ppmm(w1, w0, u, v)						\
89259691Selan   do {									\
89359691Selan     USItype __x0, __x1, __x2, __x3;					\
89459691Selan     USItype __ul, __vl, __uh, __vh;					\
89559691Selan 									\
89659691Selan     __ul = __ll_lowpart (u);						\
89759691Selan     __uh = __ll_highpart (u);						\
89859691Selan     __vl = __ll_lowpart (v);						\
89959691Selan     __vh = __ll_highpart (v);						\
90059691Selan 									\
90159691Selan     __x0 = (USItype) __ul * __vl;					\
90259691Selan     __x1 = (USItype) __ul * __vh;					\
90359691Selan     __x2 = (USItype) __uh * __vl;					\
90459691Selan     __x3 = (USItype) __uh * __vh;					\
90559691Selan 									\
90659691Selan     __x1 += __ll_highpart (__x0);/* this can't give carry */		\
90759691Selan     __x1 += __x2;		/* but this indeed can */		\
90859691Selan     if (__x1 < __x2)		/* did we get it? */			\
90959691Selan       __x3 += __ll_B;		/* yes, add it in the proper pos. */	\
91059691Selan 									\
91159691Selan     (w1) = __x3 + __ll_highpart (__x1);					\
91259691Selan     (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
91359691Selan   } while (0)
91459691Selan #endif
91559691Selan 
91659691Selan #if !defined (__umulsidi3)
91759691Selan #define __umulsidi3(u, v) \
91859691Selan   ({DIunion __w;							\
91959691Selan     umul_ppmm (__w.s.high, __w.s.low, u, v);				\
92059691Selan     __w.ll; })
92159691Selan #endif
92259691Selan 
92359691Selan /* Define this unconditionally, so it can be used for debugging.  */
92459691Selan #define __udiv_qrnnd_c(q, r, n1, n0, d) \
92559691Selan   do {									\
92659691Selan     USItype __d1, __d0, __q1, __q0;					\
92759691Selan     USItype __r1, __r0, __m;						\
92859691Selan     __d1 = __ll_highpart (d);						\
92959691Selan     __d0 = __ll_lowpart (d);						\
93059691Selan 									\
93159691Selan     __r1 = (n1) % __d1;							\
93259691Selan     __q1 = (n1) / __d1;							\
93359691Selan     __m = (USItype) __q1 * __d0;					\
93459691Selan     __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
93559691Selan     if (__r1 < __m)							\
93659691Selan       {									\
93759691Selan 	__q1--, __r1 += (d);						\
93859691Selan 	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
93959691Selan 	  if (__r1 < __m)						\
94059691Selan 	    __q1--, __r1 += (d);					\
94159691Selan       }									\
94259691Selan     __r1 -= __m;							\
94359691Selan 									\
94459691Selan     __r0 = __r1 % __d1;							\
94559691Selan     __q0 = __r1 / __d1;							\
94659691Selan     __m = (USItype) __q0 * __d0;					\
94759691Selan     __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
94859691Selan     if (__r0 < __m)							\
94959691Selan       {									\
95059691Selan 	__q0--, __r0 += (d);						\
95159691Selan 	if (__r0 >= (d))						\
95259691Selan 	  if (__r0 < __m)						\
95359691Selan 	    __q0--, __r0 += (d);					\
95459691Selan       }									\
95559691Selan     __r0 -= __m;							\
95659691Selan 									\
95759691Selan     (q) = (USItype) __q1 * __ll_B | __q0;				\
95859691Selan     (r) = __r0;								\
95959691Selan   } while (0)
96059691Selan 
96159691Selan /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
96259691Selan    __udiv_w_sdiv (defined in libgcc or elsewhere).  */
96359691Selan #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
96459691Selan #define udiv_qrnnd(q, r, nh, nl, d) \
96559691Selan   do {									\
96659691Selan     USItype __r;							\
96759691Selan     (q) = __udiv_w_sdiv (&__r, nh, nl, d);				\
96859691Selan     (r) = __r;								\
96959691Selan   } while (0)
97059691Selan #endif
97159691Selan 
97259691Selan /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
97359691Selan #if !defined (udiv_qrnnd)
97459691Selan #define UDIV_NEEDS_NORMALIZATION 1
97559691Selan #define udiv_qrnnd __udiv_qrnnd_c
97659691Selan #endif
97759691Selan 
97859691Selan #if !defined (count_leading_zeros)
97959691Selan extern const UQItype __clz_tab[];
98059691Selan #define count_leading_zeros(count, x) \
98159691Selan   do {									\
98259691Selan     USItype __xr = (x);							\
98359691Selan     USItype __a;							\
98459691Selan 									\
98559691Selan     if (SI_TYPE_SIZE <= 32)						\
98659691Selan       {									\
98759691Selan 	__a = __xr < (1<<2*__BITS4)					\
98859691Selan 	  ? (__xr < (1<<__BITS4) ? 0 : __BITS4)				\
98959691Selan 	  : (__xr < (1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);		\
99059691Selan       }									\
99159691Selan     else								\
99259691Selan       {									\
99359691Selan 	for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)		\
99459691Selan 	  if (((__xr >> __a) & 0xff) != 0)				\
99559691Selan 	    break;							\
99659691Selan       }									\
99759691Selan 									\
99859691Selan     (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
99959691Selan   } while (0)
100059691Selan #endif
100159691Selan 
100259691Selan #ifndef UDIV_NEEDS_NORMALIZATION
100359691Selan #define UDIV_NEEDS_NORMALIZATION 0
100459691Selan #endif
1005