118334Speter/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
2169689Skan   Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
3169689Skan   2005  Free Software Foundation, Inc.
418334Speter
518334Speter   This definition file is free software; you can redistribute it
618334Speter   and/or modify it under the terms of the GNU General Public
718334Speter   License as published by the Free Software Foundation; either
818334Speter   version 2, or (at your option) any later version.
918334Speter
1018334Speter   This definition file is distributed in the hope that it will be
1118334Speter   useful, but WITHOUT ANY WARRANTY; without even the implied
1218334Speter   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1318334Speter   See the GNU General Public License for more details.
1418334Speter
1518334Speter   You should have received a copy of the GNU General Public License
1618334Speter   along with this program; if not, write to the Free Software
17169689Skan   Foundation, Inc., 51 Franklin Street, Fifth Floor,
18169689Skan   Boston, MA 02110-1301, USA.  */
1918334Speter
2090075Sobrien/* You have to define the following before including this file:
2190075Sobrien
2290075Sobrien   UWtype -- An unsigned type, default type for operations (typically a "word")
2390075Sobrien   UHWtype -- An unsigned type, at least half the size of UWtype.
2490075Sobrien   UDWtype -- An unsigned type, at least twice as large a UWtype
2590075Sobrien   W_TYPE_SIZE -- size in bits of UWtype
2690075Sobrien
2790075Sobrien   UQItype -- Unsigned 8 bit type.
2890075Sobrien   SItype, USItype -- Signed and unsigned 32 bit types.
2990075Sobrien   DItype, UDItype -- Signed and unsigned 64 bit types.
3090075Sobrien
3190075Sobrien   On a 32 bit machine UWtype should typically be USItype;
32169689Skan   on a 64 bit machine, UWtype should typically be UDItype.  */
3390075Sobrien
3490075Sobrien#define __BITS4 (W_TYPE_SIZE / 4)
3590075Sobrien#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
3690075Sobrien#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
3790075Sobrien#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
3890075Sobrien
3990075Sobrien#ifndef W_TYPE_SIZE
4090075Sobrien#define W_TYPE_SIZE	32
4190075Sobrien#define UWtype		USItype
4290075Sobrien#define UHWtype		USItype
4390075Sobrien#define UDWtype		UDItype
4418334Speter#endif
4518334Speter
46169689Skanextern const UQItype __clz_tab[256];
47169689Skan
4818334Speter/* Define auxiliary asm macros.
4918334Speter
50169689Skan   1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
51169689Skan   UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
5290075Sobrien   word product in HIGH_PROD and LOW_PROD.
5318334Speter
5490075Sobrien   2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
5590075Sobrien   UDWtype product.  This is just a variant of umul_ppmm.
5618334Speter
5718334Speter   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
5890075Sobrien   denominator) divides a UDWtype, composed by the UWtype integers
5990075Sobrien   HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
6090075Sobrien   in QUOTIENT and the remainder in REMAINDER.  HIGH_NUMERATOR must be less
6190075Sobrien   than DENOMINATOR for correct operation.  If, in addition, the most
6290075Sobrien   significant bit of DENOMINATOR must be 1, then the pre-processor symbol
6390075Sobrien   UDIV_NEEDS_NORMALIZATION is defined to 1.
6418334Speter
6518334Speter   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
6690075Sobrien   denominator).  Like udiv_qrnnd but the numbers are signed.  The quotient
6790075Sobrien   is rounded towards 0.
6818334Speter
6990075Sobrien   5) count_leading_zeros(count, x) counts the number of zero-bits from the
70117395Skan   msb to the first nonzero bit in the UWtype X.  This is the number of
7190075Sobrien   steps X needs to be shifted left to set the msb.  Undefined for X == 0,
7290075Sobrien   unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
7318334Speter
7490075Sobrien   6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
7590075Sobrien   from the least significant end.
7618334Speter
7790075Sobrien   7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
7890075Sobrien   high_addend_2, low_addend_2) adds two UWtype integers, composed by
7990075Sobrien   HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
8090075Sobrien   respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
8190075Sobrien   (i.e. carry out) is not stored anywhere, and is lost.
8290075Sobrien
8390075Sobrien   8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
8490075Sobrien   high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
8590075Sobrien   composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
8690075Sobrien   LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
8790075Sobrien   and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
8818334Speter   and is lost.
8918334Speter
9018334Speter   If any of these macros are left undefined for a particular CPU,
9118334Speter   C macros are used.  */
9218334Speter
9318334Speter/* The CPUs come in alphabetical order below.
9418334Speter
9518334Speter   Please add support for more CPUs here, or improve the current support
9618334Speter   for the CPUs below!
9718334Speter   (E.g. WE32100, IBM360.)  */
9818334Speter
9918334Speter#if defined (__GNUC__) && !defined (NO_ASM)
10018334Speter
10118334Speter/* We sometimes need to clobber "cc" with gcc2, but that would not be
10218334Speter   understood by gcc1.  Use cpp to avoid major code duplication.  */
10318334Speter#if __GNUC__ < 2
10418334Speter#define __CLOBBER_CC
10518334Speter#define __AND_CLOBBER_CC
10618334Speter#else /* __GNUC__ >= 2 */
10718334Speter#define __CLOBBER_CC : "cc"
10818334Speter#define __AND_CLOBBER_CC , "cc"
10918334Speter#endif /* __GNUC__ < 2 */
11018334Speter
11190075Sobrien#if defined (__alpha) && W_TYPE_SIZE == 64
11290075Sobrien#define umul_ppmm(ph, pl, m0, m1) \
11390075Sobrien  do {									\
11490075Sobrien    UDItype __m0 = (m0), __m1 = (m1);					\
115132718Skan    (ph) = __builtin_alpha_umulh (__m0, __m1);				\
11690075Sobrien    (pl) = __m0 * __m1;							\
11790075Sobrien  } while (0)
11890075Sobrien#define UMUL_TIME 46
11990075Sobrien#ifndef LONGLONG_STANDALONE
12090075Sobrien#define udiv_qrnnd(q, r, n1, n0, d) \
12190075Sobrien  do { UDItype __r;							\
12290075Sobrien    (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));				\
12390075Sobrien    (r) = __r;								\
12490075Sobrien  } while (0)
125117395Skanextern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
12690075Sobrien#define UDIV_TIME 220
12790075Sobrien#endif /* LONGLONG_STANDALONE */
12890075Sobrien#ifdef __alpha_cix__
129132718Skan#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clzl (X))
130132718Skan#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctzl (X))
13190075Sobrien#define COUNT_LEADING_ZEROS_0 64
13290075Sobrien#else
13390075Sobrien#define count_leading_zeros(COUNT,X) \
13490075Sobrien  do {									\
13590075Sobrien    UDItype __xr = (X), __t, __a;					\
136132718Skan    __t = __builtin_alpha_cmpbge (0, __xr);				\
13790075Sobrien    __a = __clz_tab[__t ^ 0xff] - 1;					\
138132718Skan    __t = __builtin_alpha_extbl (__xr, __a);				\
13990075Sobrien    (COUNT) = 64 - (__clz_tab[__t] + __a*8);				\
14090075Sobrien  } while (0)
14190075Sobrien#define count_trailing_zeros(COUNT,X) \
14290075Sobrien  do {									\
14390075Sobrien    UDItype __xr = (X), __t, __a;					\
144132718Skan    __t = __builtin_alpha_cmpbge (0, __xr);				\
14590075Sobrien    __t = ~__t & -~__t;							\
14690075Sobrien    __a = ((__t & 0xCC) != 0) * 2;					\
14790075Sobrien    __a += ((__t & 0xF0) != 0) * 4;					\
14890075Sobrien    __a += ((__t & 0xAA) != 0);						\
149132718Skan    __t = __builtin_alpha_extbl (__xr, __a);				\
15090075Sobrien    __a <<= 3;								\
15190075Sobrien    __t &= -__t;							\
15290075Sobrien    __a += ((__t & 0xCC) != 0) * 2;					\
15390075Sobrien    __a += ((__t & 0xF0) != 0) * 4;					\
15490075Sobrien    __a += ((__t & 0xAA) != 0);						\
15590075Sobrien    (COUNT) = __a;							\
15690075Sobrien  } while (0)
15790075Sobrien#endif /* __alpha_cix__ */
15890075Sobrien#endif /* __alpha */
15990075Sobrien
16090075Sobrien#if defined (__arc__) && W_TYPE_SIZE == 32
16150397Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
16290075Sobrien  __asm__ ("add.f	%1, %4, %5\n\tadc	%0, %2, %3"		\
16350397Sobrien	   : "=r" ((USItype) (sh)),					\
16450397Sobrien	     "=&r" ((USItype) (sl))					\
16550397Sobrien	   : "%r" ((USItype) (ah)),					\
16650397Sobrien	     "rIJ" ((USItype) (bh)),					\
16750397Sobrien	     "%r" ((USItype) (al)),					\
16850397Sobrien	     "rIJ" ((USItype) (bl)))
16950397Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
17090075Sobrien  __asm__ ("sub.f	%1, %4, %5\n\tsbc	%0, %2, %3"		\
17150397Sobrien	   : "=r" ((USItype) (sh)),					\
17250397Sobrien	     "=&r" ((USItype) (sl))					\
17350397Sobrien	   : "r" ((USItype) (ah)),					\
17450397Sobrien	     "rIJ" ((USItype) (bh)),					\
17550397Sobrien	     "r" ((USItype) (al)),					\
17650397Sobrien	     "rIJ" ((USItype) (bl)))
17790075Sobrien/* Call libgcc routine.  */
17850397Sobrien#define umul_ppmm(w1, w0, u, v) \
17950397Sobriendo {									\
18090075Sobrien  DWunion __w;								\
18150397Sobrien  __w.ll = __umulsidi3 (u, v);						\
18250397Sobrien  w1 = __w.s.high;							\
18350397Sobrien  w0 = __w.s.low;							\
18450397Sobrien} while (0)
18550397Sobrien#define __umulsidi3 __umulsidi3
18650397SobrienUDItype __umulsidi3 (USItype, USItype);
18750397Sobrien#endif
18850397Sobrien
189169689Skan#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
19018334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
19190075Sobrien  __asm__ ("adds	%1, %4, %5\n\tadc	%0, %2, %3"		\
19250397Sobrien	   : "=r" ((USItype) (sh)),					\
19350397Sobrien	     "=&r" ((USItype) (sl))					\
19450397Sobrien	   : "%r" ((USItype) (ah)),					\
19550397Sobrien	     "rI" ((USItype) (bh)),					\
19650397Sobrien	     "%r" ((USItype) (al)),					\
197169689Skan	     "rI" ((USItype) (bl)) __CLOBBER_CC)
19818334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
19990075Sobrien  __asm__ ("subs	%1, %4, %5\n\tsbc	%0, %2, %3"		\
20050397Sobrien	   : "=r" ((USItype) (sh)),					\
20150397Sobrien	     "=&r" ((USItype) (sl))					\
20250397Sobrien	   : "r" ((USItype) (ah)),					\
20350397Sobrien	     "rI" ((USItype) (bh)),					\
20450397Sobrien	     "r" ((USItype) (al)),					\
205169689Skan	     "rI" ((USItype) (bl)) __CLOBBER_CC)
20618334Speter#define umul_ppmm(xh, xl, a, b) \
20718334Speter{register USItype __t0, __t1, __t2;					\
208244273Sandrew  __asm__ ("/* Inlined umul_ppmm */\n"					\
20990075Sobrien	   "	mov	%2, %5, lsr #16\n"				\
21090075Sobrien	   "	mov	%0, %6, lsr #16\n"				\
21190075Sobrien	   "	bic	%3, %5, %2, lsl #16\n"				\
21290075Sobrien	   "	bic	%4, %6, %0, lsl #16\n"				\
21390075Sobrien	   "	mul	%1, %3, %4\n"					\
21490075Sobrien	   "	mul	%4, %2, %4\n"					\
21590075Sobrien	   "	mul	%3, %0, %3\n"					\
21690075Sobrien	   "	mul	%0, %2, %0\n"					\
21790075Sobrien	   "	adds	%3, %4, %3\n"					\
21890075Sobrien	   "	addcs	%0, %0, #65536\n"				\
21990075Sobrien	   "	adds	%1, %1, %3, lsl #16\n"				\
22090075Sobrien	   "	adc	%0, %0, %3, lsr #16"				\
22150397Sobrien	   : "=&r" ((USItype) (xh)),					\
22250397Sobrien	     "=r" ((USItype) (xl)),					\
22318334Speter	     "=&r" (__t0), "=&r" (__t1), "=r" (__t2)			\
22450397Sobrien	   : "r" ((USItype) (a)),					\
225169689Skan	     "r" ((USItype) (b)) __CLOBBER_CC );}
22618334Speter#define UMUL_TIME 20
22718334Speter#define UDIV_TIME 100
22818334Speter#endif /* __arm__ */
22918334Speter
23090075Sobrien#if defined (__hppa) && W_TYPE_SIZE == 32
23118334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
23290075Sobrien  __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0"				\
23350397Sobrien	   : "=r" ((USItype) (sh)),					\
23450397Sobrien	     "=&r" ((USItype) (sl))					\
23550397Sobrien	   : "%rM" ((USItype) (ah)),					\
23650397Sobrien	     "rM" ((USItype) (bh)),					\
23750397Sobrien	     "%rM" ((USItype) (al)),					\
23850397Sobrien	     "rM" ((USItype) (bl)))
23918334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
24090075Sobrien  __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0"				\
24150397Sobrien	   : "=r" ((USItype) (sh)),					\
24250397Sobrien	     "=&r" ((USItype) (sl))					\
24350397Sobrien	   : "rM" ((USItype) (ah)),					\
24450397Sobrien	     "rM" ((USItype) (bh)),					\
24550397Sobrien	     "rM" ((USItype) (al)),					\
24650397Sobrien	     "rM" ((USItype) (bl)))
24718334Speter#if defined (_PA_RISC1_1)
24818334Speter#define umul_ppmm(w1, w0, u, v) \
24918334Speter  do {									\
25018334Speter    union								\
25118334Speter      {									\
25218334Speter	UDItype __f;							\
25318334Speter	struct {USItype __w1, __w0;} __w1w0;				\
25418334Speter      } __t;								\
25518334Speter    __asm__ ("xmpyu %1,%2,%0"						\
25618334Speter	     : "=x" (__t.__f)						\
25750397Sobrien	     : "x" ((USItype) (u)),					\
25850397Sobrien	       "x" ((USItype) (v)));					\
25918334Speter    (w1) = __t.__w1w0.__w1;						\
26018334Speter    (w0) = __t.__w1w0.__w0;						\
26118334Speter     } while (0)
26218334Speter#define UMUL_TIME 8
26318334Speter#else
26418334Speter#define UMUL_TIME 30
26518334Speter#endif
26618334Speter#define UDIV_TIME 40
26718334Speter#define count_leading_zeros(count, x) \
26818334Speter  do {									\
26918334Speter    USItype __tmp;							\
27018334Speter    __asm__ (								\
27190075Sobrien       "ldi		1,%0\n"						\
27290075Sobrien"	extru,=		%1,15,16,%%r0		; Bits 31..16 zero?\n"	\
27390075Sobrien"	extru,tr	%1,15,16,%1		; No.  Shift down, skip add.\n"\
27490075Sobrien"	ldo		16(%0),%0		; Yes.  Perform add.\n"	\
27590075Sobrien"	extru,=		%1,23,8,%%r0		; Bits 15..8 zero?\n"	\
27690075Sobrien"	extru,tr	%1,23,8,%1		; No.  Shift down, skip add.\n"\
27790075Sobrien"	ldo		8(%0),%0		; Yes.  Perform add.\n"	\
27890075Sobrien"	extru,=		%1,27,4,%%r0		; Bits 7..4 zero?\n"	\
27990075Sobrien"	extru,tr	%1,27,4,%1		; No.  Shift down, skip add.\n"\
28090075Sobrien"	ldo		4(%0),%0		; Yes.  Perform add.\n"	\
28190075Sobrien"	extru,=		%1,29,2,%%r0		; Bits 3..2 zero?\n"	\
28290075Sobrien"	extru,tr	%1,29,2,%1		; No.  Shift down, skip add.\n"\
28390075Sobrien"	ldo		2(%0),%0		; Yes.  Perform add.\n"	\
28490075Sobrien"	extru		%1,30,1,%1		; Extract bit 1.\n"	\
28590075Sobrien"	sub		%0,%1,%0		; Subtract it.\n"	\
28690075Sobrien	: "=r" (count), "=r" (__tmp) : "1" (x));			\
28718334Speter  } while (0)
28818334Speter#endif
28918334Speter
290117395Skan#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
29190075Sobrien#define smul_ppmm(xh, xl, m0, m1) \
29290075Sobrien  do {									\
29390075Sobrien    union {DItype __ll;							\
29490075Sobrien	   struct {USItype __h, __l;} __i;				\
295117395Skan	  } __x;							\
296117395Skan    __asm__ ("lr %N0,%1\n\tmr %0,%2"					\
297117395Skan	     : "=&r" (__x.__ll)						\
298117395Skan	     : "r" (m0), "r" (m1));					\
299117395Skan    (xh) = __x.__i.__h; (xl) = __x.__i.__l;				\
30090075Sobrien  } while (0)
30190075Sobrien#define sdiv_qrnnd(q, r, n1, n0, d) \
30290075Sobrien  do {									\
30390075Sobrien    union {DItype __ll;							\
30490075Sobrien	   struct {USItype __h, __l;} __i;				\
305117395Skan	  } __x;							\
306117395Skan    __x.__i.__h = n1; __x.__i.__l = n0;					\
30790075Sobrien    __asm__ ("dr %0,%2"							\
308117395Skan	     : "=r" (__x.__ll)						\
309117395Skan	     : "0" (__x.__ll), "r" (d));				\
310117395Skan    (q) = __x.__i.__l; (r) = __x.__i.__h;				\
31190075Sobrien  } while (0)
31290075Sobrien#endif
31390075Sobrien
31490075Sobrien#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
31518334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
31690075Sobrien  __asm__ ("addl %5,%1\n\tadcl %3,%0"					\
317211537Srpaulo	   : "=r" ((USItype) (sh)),					\
318211537Srpaulo	     "=&r" ((USItype) (sl))					\
319211537Srpaulo	   : "%0" ((USItype) (ah)),					\
320211537Srpaulo	     "g" ((USItype) (bh)),					\
321211537Srpaulo	     "%1" ((USItype) (al)),					\
322211537Srpaulo	     "g" ((USItype) (bl)))
32318334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
32490075Sobrien  __asm__ ("subl %5,%1\n\tsbbl %3,%0"					\
325211505Srpaulo	   : "=r" (sh),							\
326211505Srpaulo	     "=&r" (sl)							\
327211537Srpaulo	   : "0" ((USItype) (ah)),					\
328211537Srpaulo	     "g" ((USItype) (bh)),					\
329211537Srpaulo	     "1" ((USItype) (al)),					\
330211537Srpaulo	     "g" ((USItype) (bl)))
33118334Speter#define umul_ppmm(w1, w0, u, v) \
33218334Speter  __asm__ ("mull %3"							\
333211505Srpaulo	   : "=a" (w0),							\
334211505Srpaulo	     "=d" (w1)							\
335211537Srpaulo	   : "%0" ((USItype) (u)),					\
336211537Srpaulo	     "rm" ((USItype) (v)))
33790075Sobrien#define udiv_qrnnd(q, r, n1, n0, dv) \
33818334Speter  __asm__ ("divl %4"							\
339211505Srpaulo	   : "=a" (q),							\
340211505Srpaulo	     "=d" (r)							\
341211537Srpaulo	   : "0" ((USItype) (n0)),					\
342211537Srpaulo	     "1" ((USItype) (n1)),					\
343211537Srpaulo	     "rm" ((USItype) (dv)))
34418334Speter#define count_leading_zeros(count, x) \
34518334Speter  do {									\
34618334Speter    USItype __cbtmp;							\
34718334Speter    __asm__ ("bsrl %1,%0"						\
348211537Srpaulo	     : "=r" (__cbtmp) : "rm" ((USItype) (x)));			\
34918334Speter    (count) = __cbtmp ^ 31;						\
35018334Speter  } while (0)
35190075Sobrien#define count_trailing_zeros(count, x) \
35290075Sobrien  __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
35318334Speter#define UMUL_TIME 40
35418334Speter#define UDIV_TIME 40
35518334Speter#endif /* 80x86 */
35618334Speter
35790075Sobrien#if defined (__i960__) && W_TYPE_SIZE == 32
35818334Speter#define umul_ppmm(w1, w0, u, v) \
35918334Speter  ({union {UDItype __ll;						\
36018334Speter	   struct {USItype __l, __h;} __i;				\
36118334Speter	  } __xx;							\
36218334Speter  __asm__ ("emul	%2,%1,%0"					\
36318334Speter	   : "=d" (__xx.__ll)						\
36450397Sobrien	   : "%dI" ((USItype) (u)),					\
36550397Sobrien	     "dI" ((USItype) (v)));					\
36618334Speter  (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
36718334Speter#define __umulsidi3(u, v) \
36818334Speter  ({UDItype __w;							\
36918334Speter    __asm__ ("emul	%2,%1,%0"					\
37018334Speter	     : "=d" (__w)						\
37150397Sobrien	     : "%dI" ((USItype) (u)),					\
37250397Sobrien	       "dI" ((USItype) (v)));					\
37390075Sobrien    __w; })
37418334Speter#endif /* __i960__ */
37518334Speter
37690075Sobrien#if defined (__M32R__) && W_TYPE_SIZE == 32
37750397Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
37850397Sobrien  /* The cmp clears the condition bit.  */ \
379132718Skan  __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3"			\
38050397Sobrien	   : "=r" ((USItype) (sh)),					\
38150397Sobrien	     "=&r" ((USItype) (sl))					\
382132718Skan	   : "0" ((USItype) (ah)),					\
38350397Sobrien	     "r" ((USItype) (bh)),					\
384132718Skan	     "1" ((USItype) (al)),					\
38550397Sobrien	     "r" ((USItype) (bl))					\
38650397Sobrien	   : "cbit")
38750397Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
38850397Sobrien  /* The cmp clears the condition bit.  */ \
389132718Skan  __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3"			\
39050397Sobrien	   : "=r" ((USItype) (sh)),					\
39150397Sobrien	     "=&r" ((USItype) (sl))					\
39250397Sobrien	   : "0" ((USItype) (ah)),					\
39350397Sobrien	     "r" ((USItype) (bh)),					\
39450397Sobrien	     "1" ((USItype) (al)),					\
39550397Sobrien	     "r" ((USItype) (bl))					\
39650397Sobrien	   : "cbit")
39750397Sobrien#endif /* __M32R__ */
39850397Sobrien
39990075Sobrien#if defined (__mc68000__) && W_TYPE_SIZE == 32
40018334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
40190075Sobrien  __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
40250397Sobrien	   : "=d" ((USItype) (sh)),					\
40350397Sobrien	     "=&d" ((USItype) (sl))					\
40450397Sobrien	   : "%0" ((USItype) (ah)),					\
40550397Sobrien	     "d" ((USItype) (bh)),					\
40650397Sobrien	     "%1" ((USItype) (al)),					\
40750397Sobrien	     "g" ((USItype) (bl)))
40818334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
40990075Sobrien  __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0"				\
41050397Sobrien	   : "=d" ((USItype) (sh)),					\
41150397Sobrien	     "=&d" ((USItype) (sl))					\
41250397Sobrien	   : "0" ((USItype) (ah)),					\
41350397Sobrien	     "d" ((USItype) (bh)),					\
41450397Sobrien	     "1" ((USItype) (al)),					\
41550397Sobrien	     "g" ((USItype) (bl)))
41650397Sobrien
417169689Skan/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r.  */
418169689Skan#if (defined (__mc68020__) && !defined (__mc68060__))
41918334Speter#define umul_ppmm(w1, w0, u, v) \
42018334Speter  __asm__ ("mulu%.l %3,%1:%0"						\
42150397Sobrien	   : "=d" ((USItype) (w0)),					\
42250397Sobrien	     "=d" ((USItype) (w1))					\
42350397Sobrien	   : "%0" ((USItype) (u)),					\
42450397Sobrien	     "dmi" ((USItype) (v)))
42518334Speter#define UMUL_TIME 45
42618334Speter#define udiv_qrnnd(q, r, n1, n0, d) \
42718334Speter  __asm__ ("divu%.l %4,%1:%0"						\
42850397Sobrien	   : "=d" ((USItype) (q)),					\
42950397Sobrien	     "=d" ((USItype) (r))					\
43050397Sobrien	   : "0" ((USItype) (n0)),					\
43150397Sobrien	     "1" ((USItype) (n1)),					\
43250397Sobrien	     "dmi" ((USItype) (d)))
43318334Speter#define UDIV_TIME 90
43418334Speter#define sdiv_qrnnd(q, r, n1, n0, d) \
43518334Speter  __asm__ ("divs%.l %4,%1:%0"						\
43650397Sobrien	   : "=d" ((USItype) (q)),					\
43750397Sobrien	     "=d" ((USItype) (r))					\
43850397Sobrien	   : "0" ((USItype) (n0)),					\
43950397Sobrien	     "1" ((USItype) (n1)),					\
44050397Sobrien	     "dmi" ((USItype) (d)))
44150397Sobrien
442169689Skan#elif defined (__mcoldfire__) /* not mc68020 */
443169689Skan
444132718Skan#define umul_ppmm(xh, xl, a, b) \
445132718Skan  __asm__ ("| Inlined umul_ppmm\n"					\
446132718Skan	   "	move%.l	%2,%/d0\n"					\
447132718Skan	   "	move%.l	%3,%/d1\n"					\
448132718Skan	   "	move%.l	%/d0,%/d2\n"					\
449132718Skan	   "	swap	%/d0\n"						\
450132718Skan	   "	move%.l	%/d1,%/d3\n"					\
451132718Skan	   "	swap	%/d1\n"						\
452132718Skan	   "	move%.w	%/d2,%/d4\n"					\
453132718Skan	   "	mulu	%/d3,%/d4\n"					\
454132718Skan	   "	mulu	%/d1,%/d2\n"					\
455132718Skan	   "	mulu	%/d0,%/d3\n"					\
456132718Skan	   "	mulu	%/d0,%/d1\n"					\
457132718Skan	   "	move%.l	%/d4,%/d0\n"					\
458132718Skan	   "	clr%.w	%/d0\n"						\
459132718Skan	   "	swap	%/d0\n"						\
460132718Skan	   "	add%.l	%/d0,%/d2\n"					\
461132718Skan	   "	add%.l	%/d3,%/d2\n"					\
462132718Skan	   "	jcc	1f\n"						\
463132718Skan	   "	add%.l	%#65536,%/d1\n"					\
464132718Skan	   "1:	swap	%/d2\n"						\
465132718Skan	   "	moveq	%#0,%/d0\n"					\
466132718Skan	   "	move%.w	%/d2,%/d0\n"					\
467132718Skan	   "	move%.w	%/d4,%/d2\n"					\
468132718Skan	   "	move%.l	%/d2,%1\n"					\
469132718Skan	   "	add%.l	%/d1,%/d0\n"					\
470132718Skan	   "	move%.l	%/d0,%0"					\
471132718Skan	   : "=g" ((USItype) (xh)),					\
472132718Skan	     "=g" ((USItype) (xl))					\
473132718Skan	   : "g" ((USItype) (a)),					\
474132718Skan	     "g" ((USItype) (b))					\
475132718Skan	   : "d0", "d1", "d2", "d3", "d4")
476132718Skan#define UMUL_TIME 100
477132718Skan#define UDIV_TIME 400
478132718Skan#else /* not ColdFire */
47918334Speter/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX.  */
48018334Speter#define umul_ppmm(xh, xl, a, b) \
48190075Sobrien  __asm__ ("| Inlined umul_ppmm\n"					\
48290075Sobrien	   "	move%.l	%2,%/d0\n"					\
48390075Sobrien	   "	move%.l	%3,%/d1\n"					\
48490075Sobrien	   "	move%.l	%/d0,%/d2\n"					\
48590075Sobrien	   "	swap	%/d0\n"						\
48690075Sobrien	   "	move%.l	%/d1,%/d3\n"					\
48790075Sobrien	   "	swap	%/d1\n"						\
48890075Sobrien	   "	move%.w	%/d2,%/d4\n"					\
48990075Sobrien	   "	mulu	%/d3,%/d4\n"					\
49090075Sobrien	   "	mulu	%/d1,%/d2\n"					\
49190075Sobrien	   "	mulu	%/d0,%/d3\n"					\
49290075Sobrien	   "	mulu	%/d0,%/d1\n"					\
49390075Sobrien	   "	move%.l	%/d4,%/d0\n"					\
49490075Sobrien	   "	eor%.w	%/d0,%/d0\n"					\
49590075Sobrien	   "	swap	%/d0\n"						\
49690075Sobrien	   "	add%.l	%/d0,%/d2\n"					\
49790075Sobrien	   "	add%.l	%/d3,%/d2\n"					\
49890075Sobrien	   "	jcc	1f\n"						\
49990075Sobrien	   "	add%.l	%#65536,%/d1\n"					\
50090075Sobrien	   "1:	swap	%/d2\n"						\
50190075Sobrien	   "	moveq	%#0,%/d0\n"					\
50290075Sobrien	   "	move%.w	%/d2,%/d0\n"					\
50390075Sobrien	   "	move%.w	%/d4,%/d2\n"					\
50490075Sobrien	   "	move%.l	%/d2,%1\n"					\
50590075Sobrien	   "	add%.l	%/d1,%/d0\n"					\
50690075Sobrien	   "	move%.l	%/d0,%0"					\
50750397Sobrien	   : "=g" ((USItype) (xh)),					\
50850397Sobrien	     "=g" ((USItype) (xl))					\
50950397Sobrien	   : "g" ((USItype) (a)),					\
51050397Sobrien	     "g" ((USItype) (b))					\
51118334Speter	   : "d0", "d1", "d2", "d3", "d4")
51218334Speter#define UMUL_TIME 100
51318334Speter#define UDIV_TIME 400
514169689Skan
51518334Speter#endif /* not mc68020 */
51650397Sobrien
517132718Skan/* The '020, '030, '040 and '060 have bitfield insns.
518132718Skan   cpu32 disguises as a 68020, but lacks them.  */
519169689Skan#if defined (__mc68020__) && !defined (__mcpu32__)
52050397Sobrien#define count_leading_zeros(count, x) \
52150397Sobrien  __asm__ ("bfffo %1{%b2:%b2},%0"					\
52250397Sobrien	   : "=d" ((USItype) (count))					\
52350397Sobrien	   : "od" ((USItype) (x)), "n" (0))
52450397Sobrien#endif
52518334Speter#endif /* mc68000 */
52618334Speter
52790075Sobrien#if defined (__m88000__) && W_TYPE_SIZE == 32
52818334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
52990075Sobrien  __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3"			\
53050397Sobrien	   : "=r" ((USItype) (sh)),					\
53150397Sobrien	     "=&r" ((USItype) (sl))					\
53250397Sobrien	   : "%rJ" ((USItype) (ah)),					\
53350397Sobrien	     "rJ" ((USItype) (bh)),					\
53450397Sobrien	     "%rJ" ((USItype) (al)),					\
53550397Sobrien	     "rJ" ((USItype) (bl)))
53618334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
53790075Sobrien  __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3"			\
53850397Sobrien	   : "=r" ((USItype) (sh)),					\
53950397Sobrien	     "=&r" ((USItype) (sl))					\
54050397Sobrien	   : "rJ" ((USItype) (ah)),					\
54150397Sobrien	     "rJ" ((USItype) (bh)),					\
54250397Sobrien	     "rJ" ((USItype) (al)),					\
54350397Sobrien	     "rJ" ((USItype) (bl)))
54418334Speter#define count_leading_zeros(count, x) \
54518334Speter  do {									\
54618334Speter    USItype __cbtmp;							\
54718334Speter    __asm__ ("ff1 %0,%1"						\
54818334Speter	     : "=r" (__cbtmp)						\
54950397Sobrien	     : "r" ((USItype) (x)));					\
55018334Speter    (count) = __cbtmp ^ 31;						\
55118334Speter  } while (0)
55290075Sobrien#define COUNT_LEADING_ZEROS_0 63 /* sic */
55318334Speter#if defined (__mc88110__)
55418334Speter#define umul_ppmm(wh, wl, u, v) \
55518334Speter  do {									\
55618334Speter    union {UDItype __ll;						\
55718334Speter	   struct {USItype __h, __l;} __i;				\
55818334Speter	  } __xx;							\
55918334Speter    __asm__ ("mulu.d	%0,%1,%2"					\
56018334Speter	     : "=r" (__xx.__ll)						\
56150397Sobrien	     : "r" ((USItype) (u)),					\
56250397Sobrien	       "r" ((USItype) (v)));					\
56318334Speter    (wh) = __xx.__i.__h;						\
56418334Speter    (wl) = __xx.__i.__l;						\
56518334Speter  } while (0)
56618334Speter#define udiv_qrnnd(q, r, n1, n0, d) \
56718334Speter  ({union {UDItype __ll;						\
56818334Speter	   struct {USItype __h, __l;} __i;				\
56918334Speter	  } __xx;							\
57018334Speter  USItype __q;								\
57118334Speter  __xx.__i.__h = (n1); __xx.__i.__l = (n0);				\
57218334Speter  __asm__ ("divu.d %0,%1,%2"						\
57318334Speter	   : "=r" (__q)							\
57418334Speter	   : "r" (__xx.__ll),						\
57550397Sobrien	     "r" ((USItype) (d)));					\
57618334Speter  (r) = (n0) - __q * (d); (q) = __q; })
57718334Speter#define UMUL_TIME 5
57818334Speter#define UDIV_TIME 25
57918334Speter#else
58018334Speter#define UMUL_TIME 17
58118334Speter#define UDIV_TIME 150
58218334Speter#endif /* __mc88110__ */
58318334Speter#endif /* __m88000__ */
58418334Speter
58590075Sobrien#if defined (__mips__) && W_TYPE_SIZE == 32
58618334Speter#define umul_ppmm(w1, w0, u, v) \
58718334Speter  __asm__ ("multu %2,%3"						\
58850397Sobrien	   : "=l" ((USItype) (w0)),					\
58950397Sobrien	     "=h" ((USItype) (w1))					\
59050397Sobrien	   : "d" ((USItype) (u)),					\
59150397Sobrien	     "d" ((USItype) (v)))
59218334Speter#define UMUL_TIME 10
59318334Speter#define UDIV_TIME 100
59418334Speter#endif /* __mips__ */
59518334Speter
59690075Sobrien#if defined (__ns32000__) && W_TYPE_SIZE == 32
59718334Speter#define umul_ppmm(w1, w0, u, v) \
59818334Speter  ({union {UDItype __ll;						\
59918334Speter	   struct {USItype __l, __h;} __i;				\
60018334Speter	  } __xx;							\
60118334Speter  __asm__ ("meid %2,%0"							\
60218334Speter	   : "=g" (__xx.__ll)						\
60350397Sobrien	   : "%0" ((USItype) (u)),					\
60450397Sobrien	     "g" ((USItype) (v)));					\
60518334Speter  (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
60618334Speter#define __umulsidi3(u, v) \
60718334Speter  ({UDItype __w;							\
60818334Speter    __asm__ ("meid %2,%0"						\
60918334Speter	     : "=g" (__w)						\
61050397Sobrien	     : "%0" ((USItype) (u)),					\
61150397Sobrien	       "g" ((USItype) (v)));					\
61218334Speter    __w; })
61318334Speter#define udiv_qrnnd(q, r, n1, n0, d) \
61418334Speter  ({union {UDItype __ll;						\
61518334Speter	   struct {USItype __l, __h;} __i;				\
61618334Speter	  } __xx;							\
61718334Speter  __xx.__i.__h = (n1); __xx.__i.__l = (n0);				\
61818334Speter  __asm__ ("deid %2,%0"							\
61918334Speter	   : "=g" (__xx.__ll)						\
62018334Speter	   : "0" (__xx.__ll),						\
62150397Sobrien	     "g" ((USItype) (d)));					\
62218334Speter  (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
62390075Sobrien#define count_trailing_zeros(count,x) \
624117395Skan  do {									\
625117395Skan    __asm__ ("ffsd     %2,%0"						\
626117395Skan            : "=r" ((USItype) (count))					\
627117395Skan            : "0" ((USItype) 0),					\
628117395Skan              "r" ((USItype) (x)));					\
62990075Sobrien  } while (0)
63018334Speter#endif /* __ns32000__ */
63118334Speter
632117395Skan/* FIXME: We should test _IBMR2 here when we add assembly support for the
633117395Skan   system vendor compilers.
634117395Skan   FIXME: What's needed for gcc PowerPC VxWorks?  __vxworks__ is not good
635117395Skan   enough, since that hits ARM and m68k too.  */
636117395Skan#if (defined (_ARCH_PPC)	/* AIX */				\
637117395Skan     || defined (_ARCH_PWR)	/* AIX */				\
638117395Skan     || defined (_ARCH_COM)	/* AIX */				\
639117395Skan     || defined (__powerpc__)	/* gcc */				\
640117395Skan     || defined (__POWERPC__)	/* BEOS */				\
641117395Skan     || defined (__ppc__)	/* Darwin */				\
642161651Skan     || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */    \
643161651Skan     || (defined (PPC) && defined (CPU_FAMILY)    /* VxWorks */               \
644161651Skan         && CPU_FAMILY == PPC)                                                \
645117395Skan     ) && W_TYPE_SIZE == 32
64618334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
64718334Speter  do {									\
64818334Speter    if (__builtin_constant_p (bh) && (bh) == 0)				\
64918334Speter      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2"		\
650117395Skan	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
651117395Skan    else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
65218334Speter      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2"		\
653117395Skan	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
65418334Speter    else								\
65518334Speter      __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3"		\
656117395Skan	     : "=r" (sh), "=&r" (sl)					\
657117395Skan	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
65818334Speter  } while (0)
65918334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
66018334Speter  do {									\
66118334Speter    if (__builtin_constant_p (ah) && (ah) == 0)				\
66218334Speter      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"	\
663117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
664117395Skan    else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0)		\
66518334Speter      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"	\
666117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
66718334Speter    else if (__builtin_constant_p (bh) && (bh) == 0)			\
66818334Speter      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2"		\
669117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
670117395Skan    else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
67118334Speter      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2"		\
672117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
67318334Speter    else								\
67418334Speter      __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"	\
675117395Skan	       : "=r" (sh), "=&r" (sl)					\
676117395Skan	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
67718334Speter  } while (0)
67818334Speter#define count_leading_zeros(count, x) \
679117395Skan  __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
68090075Sobrien#define COUNT_LEADING_ZEROS_0 32
681117395Skan#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \
682161651Skan  || defined (__ppc__)                                                    \
683161651Skan  || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */       \
684161651Skan  || (defined (PPC) && defined (CPU_FAMILY)    /* VxWorks */                  \
685161651Skan         && CPU_FAMILY == PPC)
68618334Speter#define umul_ppmm(ph, pl, m0, m1) \
68718334Speter  do {									\
68818334Speter    USItype __m0 = (m0), __m1 = (m1);					\
689117395Skan    __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
69018334Speter    (pl) = __m0 * __m1;							\
69118334Speter  } while (0)
69218334Speter#define UMUL_TIME 15
69318334Speter#define smul_ppmm(ph, pl, m0, m1) \
69418334Speter  do {									\
69518334Speter    SItype __m0 = (m0), __m1 = (m1);					\
696117395Skan    __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
69718334Speter    (pl) = __m0 * __m1;							\
69818334Speter  } while (0)
69918334Speter#define SMUL_TIME 14
70018334Speter#define UDIV_TIME 120
70190075Sobrien#elif defined (_ARCH_PWR)
70218334Speter#define UMUL_TIME 8
70318334Speter#define smul_ppmm(xh, xl, m0, m1) \
704117395Skan  __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1))
70518334Speter#define SMUL_TIME 4
70618334Speter#define sdiv_qrnnd(q, r, nh, nl, d) \
707117395Skan  __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d))
70818334Speter#define UDIV_TIME 100
70918334Speter#endif
710117395Skan#endif /* 32-bit POWER architecture variants.  */
71118334Speter
712117395Skan/* We should test _IBMR2 here when we add assembly support for the system
713117395Skan   vendor compilers.  */
714117395Skan#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64
71518334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
716117395Skan  do {									\
717117395Skan    if (__builtin_constant_p (bh) && (bh) == 0)				\
718117395Skan      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2"		\
719117395Skan	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
720117395Skan    else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0)		\
721117395Skan      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2"		\
722117395Skan	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
723117395Skan    else								\
724117395Skan      __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3"		\
725117395Skan	     : "=r" (sh), "=&r" (sl)					\
726117395Skan	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
727117395Skan  } while (0)
72818334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
729117395Skan  do {									\
730117395Skan    if (__builtin_constant_p (ah) && (ah) == 0)				\
731117395Skan      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"	\
732117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
733117395Skan    else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0)		\
734117395Skan      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"	\
735117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
736117395Skan    else if (__builtin_constant_p (bh) && (bh) == 0)			\
737117395Skan      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2"		\
738117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
739117395Skan    else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0)		\
740117395Skan      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2"		\
741117395Skan	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
742117395Skan    else								\
743117395Skan      __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"	\
744117395Skan	       : "=r" (sh), "=&r" (sl)					\
745117395Skan	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
746117395Skan  } while (0)
747117395Skan#define count_leading_zeros(count, x) \
748117395Skan  __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
749117395Skan#define COUNT_LEADING_ZEROS_0 64
750117395Skan#define umul_ppmm(ph, pl, m0, m1) \
751117395Skan  do {									\
752117395Skan    UDItype __m0 = (m0), __m1 = (m1);					\
753117395Skan    __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
754117395Skan    (pl) = __m0 * __m1;							\
755117395Skan  } while (0)
756117395Skan#define UMUL_TIME 15
757117395Skan#define smul_ppmm(ph, pl, m0, m1) \
758117395Skan  do {									\
759117395Skan    DItype __m0 = (m0), __m1 = (m1);					\
760117395Skan    __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
761117395Skan    (pl) = __m0 * __m1;							\
762117395Skan  } while (0)
763117395Skan#define SMUL_TIME 14  /* ??? */
764117395Skan#define UDIV_TIME 120 /* ??? */
765117395Skan#endif /* 64-bit PowerPC.  */
76618334Speter
76790075Sobrien#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
76818334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
76990075Sobrien  __asm__ ("a %1,%5\n\tae %0,%3"					\
77050397Sobrien	   : "=r" ((USItype) (sh)),					\
77150397Sobrien	     "=&r" ((USItype) (sl))					\
77250397Sobrien	   : "%0" ((USItype) (ah)),					\
77350397Sobrien	     "r" ((USItype) (bh)),					\
77450397Sobrien	     "%1" ((USItype) (al)),					\
77550397Sobrien	     "r" ((USItype) (bl)))
77618334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
77790075Sobrien  __asm__ ("s %1,%5\n\tse %0,%3"					\
77850397Sobrien	   : "=r" ((USItype) (sh)),					\
77950397Sobrien	     "=&r" ((USItype) (sl))					\
78050397Sobrien	   : "0" ((USItype) (ah)),					\
78150397Sobrien	     "r" ((USItype) (bh)),					\
78250397Sobrien	     "1" ((USItype) (al)),					\
78350397Sobrien	     "r" ((USItype) (bl)))
78418334Speter#define umul_ppmm(ph, pl, m0, m1) \
78518334Speter  do {									\
78618334Speter    USItype __m0 = (m0), __m1 = (m1);					\
78718334Speter    __asm__ (								\
78890075Sobrien       "s	r2,r2\n"						\
78990075Sobrien"	mts	r10,%2\n"						\
79090075Sobrien"	m	r2,%3\n"						\
79190075Sobrien"	m	r2,%3\n"						\
79290075Sobrien"	m	r2,%3\n"						\
79390075Sobrien"	m	r2,%3\n"						\
79490075Sobrien"	m	r2,%3\n"						\
79590075Sobrien"	m	r2,%3\n"						\
79690075Sobrien"	m	r2,%3\n"						\
79790075Sobrien"	m	r2,%3\n"						\
79890075Sobrien"	m	r2,%3\n"						\
79990075Sobrien"	m	r2,%3\n"						\
80090075Sobrien"	m	r2,%3\n"						\
80190075Sobrien"	m	r2,%3\n"						\
80290075Sobrien"	m	r2,%3\n"						\
80390075Sobrien"	m	r2,%3\n"						\
80490075Sobrien"	m	r2,%3\n"						\
80590075Sobrien"	m	r2,%3\n"						\
80690075Sobrien"	cas	%0,r2,r0\n"						\
80790075Sobrien"	mfs	r10,%1"							\
80850397Sobrien	     : "=r" ((USItype) (ph)),					\
80950397Sobrien	       "=r" ((USItype) (pl))					\
81018334Speter	     : "%r" (__m0),						\
81118334Speter		"r" (__m1)						\
81218334Speter	     : "r2");							\
81318334Speter    (ph) += ((((SItype) __m0 >> 31) & __m1)				\
81418334Speter	     + (((SItype) __m1 >> 31) & __m0));				\
81518334Speter  } while (0)
81618334Speter#define UMUL_TIME 20
81718334Speter#define UDIV_TIME 200
81818334Speter#define count_leading_zeros(count, x) \
81918334Speter  do {									\
82018334Speter    if ((x) >= 0x10000)							\
82118334Speter      __asm__ ("clz	%0,%1"						\
82250397Sobrien	       : "=r" ((USItype) (count))				\
82350397Sobrien	       : "r" ((USItype) (x) >> 16));				\
82418334Speter    else								\
82518334Speter      {									\
82618334Speter	__asm__ ("clz	%0,%1"						\
82750397Sobrien		 : "=r" ((USItype) (count))				\
82850397Sobrien		 : "r" ((USItype) (x)));					\
82918334Speter	(count) += 16;							\
83018334Speter      }									\
83118334Speter  } while (0)
83218334Speter#endif
83318334Speter
834169689Skan#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32
835169689Skan#ifndef __sh1__
83690075Sobrien#define umul_ppmm(w1, w0, u, v) \
83790075Sobrien  __asm__ (								\
838169689Skan       "dmulu.l	%2,%3\n\tsts%M1	macl,%1\n\tsts%M0	mach,%0"	\
839169689Skan	   : "=r<" ((USItype)(w1)),					\
840169689Skan	     "=r<" ((USItype)(w0))					\
84190075Sobrien	   : "r" ((USItype)(u)),					\
84290075Sobrien	     "r" ((USItype)(v))						\
84390075Sobrien	   : "macl", "mach")
84490075Sobrien#define UMUL_TIME 5
84590075Sobrien#endif
84690075Sobrien
847169689Skan/* This is the same algorithm as __udiv_qrnnd_c.  */
848169689Skan#define UDIV_NEEDS_NORMALIZATION 1
849169689Skan
850169689Skan#define udiv_qrnnd(q, r, n1, n0, d) \
851169689Skan  do {									\
852169689Skan    extern UWtype __udiv_qrnnd_16 (UWtype, UWtype)			\
853169689Skan                        __attribute__ ((visibility ("hidden")));	\
854169689Skan    /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */	\
855169689Skan    __asm__ (								\
856169689Skan	"mov%M4 %4,r5\n"						\
857169689Skan"	swap.w %3,r4\n"							\
858169689Skan"	swap.w r5,r6\n"							\
859169689Skan"	jsr @%5\n"							\
860169689Skan"	shll16 r6\n"							\
861169689Skan"	swap.w r4,r4\n"							\
862169689Skan"	jsr @%5\n"							\
863169689Skan"	swap.w r1,%0\n"							\
864169689Skan"	or r1,%0"							\
865169689Skan	: "=r" (q), "=&z" (r)						\
866169689Skan	: "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16)		\
867169689Skan	: "r1", "r2", "r4", "r5", "r6", "pr");				\
868169689Skan  } while (0)
869169689Skan
870169689Skan#define UDIV_TIME 80
871169689Skan
872169689Skan#define sub_ddmmss(sh, sl, ah, al, bh, bl)				\
873169689Skan  __asm__ ("clrt;subc %5,%1; subc %4,%0"				\
874169689Skan	   : "=r" (sh), "=r" (sl)					\
875169689Skan	   : "0" (ah), "1" (al), "r" (bh), "r" (bl))
876169689Skan
877169689Skan#endif /* __sh__ */
878169689Skan
87996263Sobrien#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32
88096263Sobrien#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
88196263Sobrien#define count_leading_zeros(count, x) \
88296263Sobrien  do									\
88396263Sobrien    {									\
88496263Sobrien      UDItype x_ = (USItype)(x);					\
88596263Sobrien      SItype c_;							\
88696263Sobrien									\
88796263Sobrien      __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_));			\
88896263Sobrien      (count) = c_ - 31;						\
88996263Sobrien    }									\
89096263Sobrien  while (0)
89196263Sobrien#define COUNT_LEADING_ZEROS_0 32
89296263Sobrien#endif
89396263Sobrien
89490075Sobrien#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \
89590075Sobrien    && W_TYPE_SIZE == 32
89618334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
89790075Sobrien  __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0"				\
89850397Sobrien	   : "=r" ((USItype) (sh)),					\
89950397Sobrien	     "=&r" ((USItype) (sl))					\
90050397Sobrien	   : "%rJ" ((USItype) (ah)),					\
90150397Sobrien	     "rI" ((USItype) (bh)),					\
90250397Sobrien	     "%rJ" ((USItype) (al)),					\
90350397Sobrien	     "rI" ((USItype) (bl))					\
90418334Speter	   __CLOBBER_CC)
90518334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
90690075Sobrien  __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0"				\
90750397Sobrien	   : "=r" ((USItype) (sh)),					\
90850397Sobrien	     "=&r" ((USItype) (sl))					\
90950397Sobrien	   : "rJ" ((USItype) (ah)),					\
91050397Sobrien	     "rI" ((USItype) (bh)),					\
91150397Sobrien	     "rJ" ((USItype) (al)),					\
91250397Sobrien	     "rI" ((USItype) (bl))					\
91318334Speter	   __CLOBBER_CC)
91418334Speter#if defined (__sparc_v8__)
91518334Speter#define umul_ppmm(w1, w0, u, v) \
91618334Speter  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
91750397Sobrien	   : "=r" ((USItype) (w1)),					\
91850397Sobrien	     "=r" ((USItype) (w0))					\
91950397Sobrien	   : "r" ((USItype) (u)),					\
92050397Sobrien	     "r" ((USItype) (v)))
92190075Sobrien#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
92218334Speter  __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
92390075Sobrien	   : "=&r" ((USItype) (__q)),					\
92490075Sobrien	     "=&r" ((USItype) (__r))					\
92590075Sobrien	   : "r" ((USItype) (__n1)),					\
92690075Sobrien	     "r" ((USItype) (__n0)),					\
92790075Sobrien	     "r" ((USItype) (__d)))
92818334Speter#else
92918334Speter#if defined (__sparclite__)
93018334Speter/* This has hardware multiply but not divide.  It also has two additional
93118334Speter   instructions scan (ffs from high bit) and divscc.  */
93218334Speter#define umul_ppmm(w1, w0, u, v) \
93318334Speter  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
93450397Sobrien	   : "=r" ((USItype) (w1)),					\
93550397Sobrien	     "=r" ((USItype) (w0))					\
93650397Sobrien	   : "r" ((USItype) (u)),					\
93750397Sobrien	     "r" ((USItype) (v)))
93818334Speter#define udiv_qrnnd(q, r, n1, n0, d) \
93990075Sobrien  __asm__ ("! Inlined udiv_qrnnd\n"					\
94090075Sobrien"	wr	%%g0,%2,%%y	! Not a delayed write for sparclite\n"	\
94190075Sobrien"	tst	%%g0\n"							\
94290075Sobrien"	divscc	%3,%4,%%g1\n"						\
94390075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
94490075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
94590075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
94690075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
94790075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
94890075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
94990075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95090075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95190075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95290075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95390075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95490075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95590075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95690075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95790075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95890075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
95990075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96090075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96190075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96290075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96390075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96490075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96590075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96690075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96790075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96890075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
96990075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
97090075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
97190075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
97290075Sobrien"	divscc	%%g1,%4,%%g1\n"						\
97390075Sobrien"	divscc	%%g1,%4,%0\n"						\
97490075Sobrien"	rd	%%y,%1\n"						\
97590075Sobrien"	bl,a 1f\n"							\
97690075Sobrien"	add	%1,%4,%1\n"						\
97790075Sobrien"1:	! End of inline udiv_qrnnd"					\
97850397Sobrien	   : "=r" ((USItype) (q)),					\
97950397Sobrien	     "=r" ((USItype) (r))					\
98050397Sobrien	   : "r" ((USItype) (n1)),					\
98150397Sobrien	     "r" ((USItype) (n0)),					\
98250397Sobrien	     "rI" ((USItype) (d))					\
98390075Sobrien	   : "g1" __AND_CLOBBER_CC)
98418334Speter#define UDIV_TIME 37
98518334Speter#define count_leading_zeros(count, x) \
98652284Sobrien  do {                                                                  \
98752284Sobrien  __asm__ ("scan %1,1,%0"                                               \
98852284Sobrien           : "=r" ((USItype) (count))                                   \
98952284Sobrien           : "r" ((USItype) (x)));					\
99090075Sobrien  } while (0)
99190075Sobrien/* Early sparclites return 63 for an argument of 0, but they warn that future
99290075Sobrien   implementations might change this.  Therefore, leave COUNT_LEADING_ZEROS_0
99390075Sobrien   undefined.  */
99418334Speter#else
99518334Speter/* SPARC without integer multiplication and divide instructions.
99618334Speter   (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
99718334Speter#define umul_ppmm(w1, w0, u, v) \
99890075Sobrien  __asm__ ("! Inlined umul_ppmm\n"					\
99990075Sobrien"	wr	%%g0,%2,%%y	! SPARC has 0-3 delay insn after a wr\n"\
100090075Sobrien"	sra	%3,31,%%o5	! Don't move this insn\n"		\
100190075Sobrien"	and	%2,%%o5,%%o5	! Don't move this insn\n"		\
100290075Sobrien"	andcc	%%g0,0,%%g1	! Don't move this insn\n"		\
100390075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
100490075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
100590075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
100690075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
100790075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
100890075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
100990075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101090075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101190075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101290075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101390075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101490075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101590075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101690075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101790075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101890075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
101990075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102090075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102190075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102290075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102390075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102490075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102590075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102690075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102790075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102890075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
102990075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
103090075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
103190075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
103290075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
103390075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
103490075Sobrien"	mulscc	%%g1,%3,%%g1\n"						\
103590075Sobrien"	mulscc	%%g1,0,%%g1\n"						\
103690075Sobrien"	add	%%g1,%%o5,%0\n"						\
103790075Sobrien"	rd	%%y,%1"							\
103850397Sobrien	   : "=r" ((USItype) (w1)),					\
103950397Sobrien	     "=r" ((USItype) (w0))					\
104050397Sobrien	   : "%rI" ((USItype) (u)),					\
104150397Sobrien	     "r" ((USItype) (v))						\
104290075Sobrien	   : "g1", "o5" __AND_CLOBBER_CC)
104318334Speter#define UMUL_TIME 39		/* 39 instructions */
104418334Speter/* It's quite necessary to add this much assembler for the sparc.
104518334Speter   The default udiv_qrnnd (in C) is more than 10 times slower!  */
104690075Sobrien#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
104790075Sobrien  __asm__ ("! Inlined udiv_qrnnd\n"					\
104890075Sobrien"	mov	32,%%g1\n"						\
104990075Sobrien"	subcc	%1,%2,%%g0\n"						\
105090075Sobrien"1:	bcs	5f\n"							\
105190075Sobrien"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
105290075Sobrien"	sub	%1,%2,%1	! this kills msb of n\n"		\
105390075Sobrien"	addx	%1,%1,%1	! so this can't give carry\n"		\
105490075Sobrien"	subcc	%%g1,1,%%g1\n"						\
105590075Sobrien"2:	bne	1b\n"							\
105690075Sobrien"	 subcc	%1,%2,%%g0\n"						\
105790075Sobrien"	bcs	3f\n"							\
105890075Sobrien"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
105990075Sobrien"	b	3f\n"							\
106090075Sobrien"	 sub	%1,%2,%1	! this kills msb of n\n"		\
106190075Sobrien"4:	sub	%1,%2,%1\n"						\
106290075Sobrien"5:	addxcc	%1,%1,%1\n"						\
106390075Sobrien"	bcc	2b\n"							\
106490075Sobrien"	 subcc	%%g1,1,%%g1\n"						\
106590075Sobrien"! Got carry from n.  Subtract next step to cancel this carry.\n"	\
106690075Sobrien"	bne	4b\n"							\
106790075Sobrien"	 addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb\n"	\
106890075Sobrien"	sub	%1,%2,%1\n"						\
106990075Sobrien"3:	xnor	%0,0,%0\n"						\
107090075Sobrien"	! End of inline udiv_qrnnd"					\
107190075Sobrien	   : "=&r" ((USItype) (__q)),					\
107290075Sobrien	     "=&r" ((USItype) (__r))					\
107390075Sobrien	   : "r" ((USItype) (__d)),					\
107490075Sobrien	     "1" ((USItype) (__n1)),					\
107590075Sobrien	     "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC)
107690075Sobrien#define UDIV_TIME (3+7*32)	/* 7 instructions/iteration. 32 iterations.  */
107718334Speter#endif /* __sparclite__ */
107818334Speter#endif /* __sparc_v8__ */
107990075Sobrien#endif /* sparc32 */
108018334Speter
108190075Sobrien#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \
108290075Sobrien    && W_TYPE_SIZE == 64
108390075Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl)				\
108490075Sobrien  __asm__ ("addcc %r4,%5,%1\n\t"					\
108590075Sobrien   	   "add %r2,%3,%0\n\t"						\
108690075Sobrien   	   "bcs,a,pn %%xcc, 1f\n\t"					\
108790075Sobrien   	   "add %0, 1, %0\n"						\
108890075Sobrien	   "1:"								\
1089263763Sdim	   : "=r" (sh),						      	\
1090263763Sdim	     "=&r" (sl)						      	\
109190075Sobrien	   : "%rJ" ((UDItype)(ah)),				     	\
109290075Sobrien	     "rI" ((UDItype)(bh)),				      	\
109390075Sobrien	     "%rJ" ((UDItype)(al)),				     	\
109490075Sobrien	     "rI" ((UDItype)(bl))				       	\
109590075Sobrien	   __CLOBBER_CC)
109690075Sobrien
109790075Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) 				\
109890075Sobrien  __asm__ ("subcc %r4,%5,%1\n\t"					\
109990075Sobrien   	   "sub %r2,%3,%0\n\t"						\
110090075Sobrien   	   "bcs,a,pn %%xcc, 1f\n\t"					\
110190075Sobrien   	   "sub %0, 1, %0\n\t"						\
110290075Sobrien	   "1:"								\
1103263763Sdim	   : "=r" (sh),						      	\
1104263763Sdim	     "=&r" (sl)						      	\
110590075Sobrien	   : "rJ" ((UDItype)(ah)),				     	\
110690075Sobrien	     "rI" ((UDItype)(bh)),				      	\
110790075Sobrien	     "rJ" ((UDItype)(al)),				     	\
110890075Sobrien	     "rI" ((UDItype)(bl))				       	\
110990075Sobrien	   __CLOBBER_CC)
111090075Sobrien
111190075Sobrien#define umul_ppmm(wh, wl, u, v)						\
111290075Sobrien  do {									\
111390075Sobrien	  UDItype tmp1, tmp2, tmp3, tmp4;				\
111490075Sobrien	  __asm__ __volatile__ (					\
111590075Sobrien		   "srl %7,0,%3\n\t"					\
111690075Sobrien		   "mulx %3,%6,%1\n\t"					\
111790075Sobrien		   "srlx %6,32,%2\n\t"					\
111890075Sobrien		   "mulx %2,%3,%4\n\t"					\
111990075Sobrien		   "sllx %4,32,%5\n\t"					\
112090075Sobrien		   "srl %6,0,%3\n\t"					\
112190075Sobrien		   "sub %1,%5,%5\n\t"					\
112290075Sobrien		   "srlx %5,32,%5\n\t"					\
112390075Sobrien		   "addcc %4,%5,%4\n\t"					\
112490075Sobrien		   "srlx %7,32,%5\n\t"					\
112590075Sobrien		   "mulx %3,%5,%3\n\t"					\
112690075Sobrien		   "mulx %2,%5,%5\n\t"					\
112790075Sobrien		   "sethi %%hi(0x80000000),%2\n\t"			\
112890075Sobrien		   "addcc %4,%3,%4\n\t"					\
112990075Sobrien		   "srlx %4,32,%4\n\t"					\
113090075Sobrien		   "add %2,%2,%2\n\t"					\
113190075Sobrien		   "movcc %%xcc,%%g0,%2\n\t"				\
113290075Sobrien		   "addcc %5,%4,%5\n\t"					\
113390075Sobrien		   "sllx %3,32,%3\n\t"					\
113490075Sobrien		   "add %1,%3,%1\n\t"					\
113590075Sobrien		   "add %5,%2,%0"					\
1136263763Sdim	   : "=r" (wh),							\
1137263763Sdim	     "=&r" (wl),						\
113890075Sobrien	     "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4)	\
113990075Sobrien	   : "r" ((UDItype)(u)),					\
114090075Sobrien	     "r" ((UDItype)(v))						\
114190075Sobrien	   __CLOBBER_CC);						\
114290075Sobrien  } while (0)
114390075Sobrien#define UMUL_TIME 96
114490075Sobrien#define UDIV_TIME 230
114590075Sobrien#endif /* sparc64 */
114690075Sobrien
114790075Sobrien#if defined (__vax__) && W_TYPE_SIZE == 32
114818334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
114990075Sobrien  __asm__ ("addl2 %5,%1\n\tadwc %3,%0"					\
115050397Sobrien	   : "=g" ((USItype) (sh)),					\
115150397Sobrien	     "=&g" ((USItype) (sl))					\
115250397Sobrien	   : "%0" ((USItype) (ah)),					\
115350397Sobrien	     "g" ((USItype) (bh)),					\
115450397Sobrien	     "%1" ((USItype) (al)),					\
115550397Sobrien	     "g" ((USItype) (bl)))
115618334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
115790075Sobrien  __asm__ ("subl2 %5,%1\n\tsbwc %3,%0"					\
115850397Sobrien	   : "=g" ((USItype) (sh)),					\
115950397Sobrien	     "=&g" ((USItype) (sl))					\
116050397Sobrien	   : "0" ((USItype) (ah)),					\
116150397Sobrien	     "g" ((USItype) (bh)),					\
116250397Sobrien	     "1" ((USItype) (al)),					\
116350397Sobrien	     "g" ((USItype) (bl)))
116418334Speter#define umul_ppmm(xh, xl, m0, m1) \
116518334Speter  do {									\
116618334Speter    union {								\
116718334Speter	UDItype __ll;							\
116818334Speter	struct {USItype __l, __h;} __i;					\
116918334Speter      } __xx;								\
117018334Speter    USItype __m0 = (m0), __m1 = (m1);					\
117118334Speter    __asm__ ("emul %1,%2,$0,%0"						\
117218334Speter	     : "=r" (__xx.__ll)						\
117318334Speter	     : "g" (__m0),						\
117418334Speter	       "g" (__m1));						\
117518334Speter    (xh) = __xx.__i.__h;						\
117618334Speter    (xl) = __xx.__i.__l;						\
117718334Speter    (xh) += ((((SItype) __m0 >> 31) & __m1)				\
117818334Speter	     + (((SItype) __m1 >> 31) & __m0));				\
117918334Speter  } while (0)
118018334Speter#define sdiv_qrnnd(q, r, n1, n0, d) \
118118334Speter  do {									\
118218334Speter    union {DItype __ll;							\
118318334Speter	   struct {SItype __l, __h;} __i;				\
118418334Speter	  } __xx;							\
118518334Speter    __xx.__i.__h = n1; __xx.__i.__l = n0;				\
118618334Speter    __asm__ ("ediv %3,%2,%0,%1"						\
118718334Speter	     : "=g" (q), "=g" (r)					\
118818334Speter	     : "g" (__xx.__ll), "g" (d));				\
118918334Speter  } while (0)
119018334Speter#endif /* __vax__ */
119118334Speter
119290075Sobrien#if defined (__z8000__) && W_TYPE_SIZE == 16
119390075Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
119490075Sobrien  __asm__ ("add	%H1,%H5\n\tadc	%H0,%H3"				\
119590075Sobrien	   : "=r" ((unsigned int)(sh)),					\
119690075Sobrien	     "=&r" ((unsigned int)(sl))					\
119790075Sobrien	   : "%0" ((unsigned int)(ah)),					\
119890075Sobrien	     "r" ((unsigned int)(bh)),					\
119990075Sobrien	     "%1" ((unsigned int)(al)),					\
120090075Sobrien	     "rQR" ((unsigned int)(bl)))
120190075Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
120290075Sobrien  __asm__ ("sub	%H1,%H5\n\tsbc	%H0,%H3"				\
120390075Sobrien	   : "=r" ((unsigned int)(sh)),					\
120490075Sobrien	     "=&r" ((unsigned int)(sl))					\
120590075Sobrien	   : "0" ((unsigned int)(ah)),					\
120690075Sobrien	     "r" ((unsigned int)(bh)),					\
120790075Sobrien	     "1" ((unsigned int)(al)),					\
120890075Sobrien	     "rQR" ((unsigned int)(bl)))
120990075Sobrien#define umul_ppmm(xh, xl, m0, m1) \
121090075Sobrien  do {									\
121190075Sobrien    union {long int __ll;						\
121290075Sobrien	   struct {unsigned int __h, __l;} __i;				\
121390075Sobrien	  } __xx;							\
121490075Sobrien    unsigned int __m0 = (m0), __m1 = (m1);				\
121590075Sobrien    __asm__ ("mult	%S0,%H3"					\
121690075Sobrien	     : "=r" (__xx.__i.__h),					\
121790075Sobrien	       "=r" (__xx.__i.__l)					\
121890075Sobrien	     : "%1" (__m0),						\
121990075Sobrien	       "rQR" (__m1));						\
122090075Sobrien    (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;				\
122190075Sobrien    (xh) += ((((signed int) __m0 >> 15) & __m1)				\
122290075Sobrien	     + (((signed int) __m1 >> 15) & __m0));			\
122390075Sobrien  } while (0)
122490075Sobrien#endif /* __z8000__ */
122590075Sobrien
122618334Speter#endif /* __GNUC__ */
122718334Speter
122818334Speter/* If this machine has no inline assembler, use C macros.  */
122918334Speter
123018334Speter#if !defined (add_ssaaaa)
123118334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
123218334Speter  do {									\
123390075Sobrien    UWtype __x;								\
123418334Speter    __x = (al) + (bl);							\
123518334Speter    (sh) = (ah) + (bh) + (__x < (al));					\
123618334Speter    (sl) = __x;								\
123718334Speter  } while (0)
123818334Speter#endif
123918334Speter
124018334Speter#if !defined (sub_ddmmss)
124118334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
124218334Speter  do {									\
124390075Sobrien    UWtype __x;								\
124418334Speter    __x = (al) - (bl);							\
124518334Speter    (sh) = (ah) - (bh) - (__x > (al));					\
124618334Speter    (sl) = __x;								\
124718334Speter  } while (0)
124818334Speter#endif
124918334Speter
1250117395Skan/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
1251117395Skan   smul_ppmm.  */
1252117395Skan#if !defined (umul_ppmm) && defined (smul_ppmm)
1253117395Skan#define umul_ppmm(w1, w0, u, v)						\
1254117395Skan  do {									\
1255117395Skan    UWtype __w1;							\
1256117395Skan    UWtype __xm0 = (u), __xm1 = (v);					\
1257117395Skan    smul_ppmm (__w1, w0, __xm0, __xm1);					\
1258117395Skan    (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1)		\
1259117395Skan		+ (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0);		\
1260117395Skan  } while (0)
1261117395Skan#endif
1262117395Skan
1263117395Skan/* If we still don't have umul_ppmm, define it using plain C.  */
126418334Speter#if !defined (umul_ppmm)
126518334Speter#define umul_ppmm(w1, w0, u, v)						\
126618334Speter  do {									\
126790075Sobrien    UWtype __x0, __x1, __x2, __x3;					\
126890075Sobrien    UHWtype __ul, __vl, __uh, __vh;					\
126918334Speter									\
127018334Speter    __ul = __ll_lowpart (u);						\
127118334Speter    __uh = __ll_highpart (u);						\
127218334Speter    __vl = __ll_lowpart (v);						\
127318334Speter    __vh = __ll_highpart (v);						\
127418334Speter									\
127590075Sobrien    __x0 = (UWtype) __ul * __vl;					\
127690075Sobrien    __x1 = (UWtype) __ul * __vh;					\
127790075Sobrien    __x2 = (UWtype) __uh * __vl;					\
127890075Sobrien    __x3 = (UWtype) __uh * __vh;					\
127918334Speter									\
128018334Speter    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
128118334Speter    __x1 += __x2;		/* but this indeed can */		\
128218334Speter    if (__x1 < __x2)		/* did we get it? */			\
128390075Sobrien      __x3 += __ll_B;		/* yes, add it in the proper pos.  */	\
128418334Speter									\
128518334Speter    (w1) = __x3 + __ll_highpart (__x1);					\
128618334Speter    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
128718334Speter  } while (0)
128818334Speter#endif
128918334Speter
129018334Speter#if !defined (__umulsidi3)
129118334Speter#define __umulsidi3(u, v) \
129290075Sobrien  ({DWunion __w;							\
129318334Speter    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
129418334Speter    __w.ll; })
129518334Speter#endif
129618334Speter
129718334Speter/* Define this unconditionally, so it can be used for debugging.  */
129818334Speter#define __udiv_qrnnd_c(q, r, n1, n0, d) \
129918334Speter  do {									\
130090075Sobrien    UWtype __d1, __d0, __q1, __q0;					\
130190075Sobrien    UWtype __r1, __r0, __m;						\
130218334Speter    __d1 = __ll_highpart (d);						\
130318334Speter    __d0 = __ll_lowpart (d);						\
130418334Speter									\
130518334Speter    __r1 = (n1) % __d1;							\
130618334Speter    __q1 = (n1) / __d1;							\
130790075Sobrien    __m = (UWtype) __q1 * __d0;						\
130818334Speter    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
130918334Speter    if (__r1 < __m)							\
131018334Speter      {									\
131118334Speter	__q1--, __r1 += (d);						\
131218334Speter	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
131318334Speter	  if (__r1 < __m)						\
131418334Speter	    __q1--, __r1 += (d);					\
131518334Speter      }									\
131618334Speter    __r1 -= __m;							\
131718334Speter									\
131818334Speter    __r0 = __r1 % __d1;							\
131918334Speter    __q0 = __r1 / __d1;							\
132090075Sobrien    __m = (UWtype) __q0 * __d0;						\
132118334Speter    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
132218334Speter    if (__r0 < __m)							\
132318334Speter      {									\
132418334Speter	__q0--, __r0 += (d);						\
132518334Speter	if (__r0 >= (d))						\
132618334Speter	  if (__r0 < __m)						\
132718334Speter	    __q0--, __r0 += (d);					\
132818334Speter      }									\
132918334Speter    __r0 -= __m;							\
133018334Speter									\
133190075Sobrien    (q) = (UWtype) __q1 * __ll_B | __q0;				\
133218334Speter    (r) = __r0;								\
133318334Speter  } while (0)
133418334Speter
133518334Speter/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
133618334Speter   __udiv_w_sdiv (defined in libgcc or elsewhere).  */
133718334Speter#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
133818334Speter#define udiv_qrnnd(q, r, nh, nl, d) \
133918334Speter  do {									\
134018334Speter    USItype __r;							\
134118334Speter    (q) = __udiv_w_sdiv (&__r, nh, nl, d);				\
134218334Speter    (r) = __r;								\
134318334Speter  } while (0)
134418334Speter#endif
134518334Speter
134618334Speter/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
134718334Speter#if !defined (udiv_qrnnd)
134818334Speter#define UDIV_NEEDS_NORMALIZATION 1
134918334Speter#define udiv_qrnnd __udiv_qrnnd_c
135018334Speter#endif
135118334Speter
135218334Speter#if !defined (count_leading_zeros)
135318334Speter#define count_leading_zeros(count, x) \
135418334Speter  do {									\
135590075Sobrien    UWtype __xr = (x);							\
135690075Sobrien    UWtype __a;								\
135718334Speter									\
135890075Sobrien    if (W_TYPE_SIZE <= 32)						\
135918334Speter      {									\
136090075Sobrien	__a = __xr < ((UWtype)1<<2*__BITS4)				\
136190075Sobrien	  ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4)			\
136290075Sobrien	  : (__xr < ((UWtype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
136318334Speter      }									\
136418334Speter    else								\
136518334Speter      {									\
136690075Sobrien	for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
136718334Speter	  if (((__xr >> __a) & 0xff) != 0)				\
136818334Speter	    break;							\
136918334Speter      }									\
137018334Speter									\
137190075Sobrien    (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
137218334Speter  } while (0)
137390075Sobrien#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
137418334Speter#endif
137518334Speter
137690075Sobrien#if !defined (count_trailing_zeros)
137790075Sobrien/* Define count_trailing_zeros using count_leading_zeros.  The latter might be
137890075Sobrien   defined in asm, but if it is not, the C version above is good enough.  */
137990075Sobrien#define count_trailing_zeros(count, x) \
138090075Sobrien  do {									\
138190075Sobrien    UWtype __ctz_x = (x);						\
138290075Sobrien    UWtype __ctz_c;							\
138390075Sobrien    count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x);			\
138490075Sobrien    (count) = W_TYPE_SIZE - 1 - __ctz_c;				\
138590075Sobrien  } while (0)
138690075Sobrien#endif
138790075Sobrien
138818334Speter#ifndef UDIV_NEEDS_NORMALIZATION
138918334Speter#define UDIV_NEEDS_NORMALIZATION 0
139018334Speter#endif
1391