Tue Mar 21 00:14:27 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
[platform/upstream/glibc.git] / stdlib / longlong.h
1 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
2
3 Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
9
10 This file is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13 License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this file; see the file COPYING.LIB.  If not, write to
17 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 /* You have to define the following before including this file:
20
21    UWtype -- An unsigned type, default type for operations (typically a "word")
22    UHWtype -- An unsigned type, at least half the size of UWtype.
23    UDWtype -- An unsigned type, at least twice as large a UWtype
24    W_TYPE_SIZE -- size in bits of UWtype
25
26    SItype, USItype -- Signed and unsigned 32 bit types.
27    DItype, UDItype -- Signed and unsigned 64 bit types.
28
29    On a 32 bit machine UWtype should typically be USItype;
30    on a 64 bit machine, UWtype should typically be UDItype.
31 */
32
33 #define __BITS4 (W_TYPE_SIZE / 4)
34 #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
35 #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
36 #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
37
38 /* Define auxiliary asm macros.
39
40    1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
41    UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
42    word product in HIGH_PROD and LOW_PROD.
43
44    2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
45    UDWtype product.  This is just a variant of umul_ppmm.
46
47    3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
48    denominator) divides a UDWtype, composed by the UWtype integers
49    HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
50    in QUOTIENT and the remainder in REMAINDER.  HIGH_NUMERATOR must be less
51    than DENOMINATOR for correct operation.  If, in addition, the most
52    significant bit of DENOMINATOR must be 1, then the pre-processor symbol
53    UDIV_NEEDS_NORMALIZATION is defined to 1.
54
55    4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
56    denominator).  Like udiv_qrnnd but the numbers are signed.  The quotient
57    is rounded towards 0.
58
59    5) count_leading_zeros(count, x) counts the number of zero-bits from the
60    msb to the first non-zero bit in the UWtype X.  This is the number of
61    steps X needs to be shifted left to set the msb.  Undefined for X == 0,
62    unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
63
64    6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
65    from the least significant end.
66
67    7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
68    high_addend_2, low_addend_2) adds two UWtype integers, composed by
69    HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
70    respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
71    (i.e. carry out) is not stored anywhere, and is lost.
72
73    8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
74    high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
75    composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
76    LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
77    and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
78    and is lost.
79
80    If any of these macros are left undefined for a particular CPU,
81    C macros are used.  */
82
83 /* The CPUs come in alphabetical order below.
84
85    Please add support for more CPUs here, or improve the current support
86    for the CPUs below!  */
87
88 #if defined (__GNUC__) && !defined (NO_ASM)
89
90 /* We sometimes need to clobber "cc" with gcc2, but that would not be
91    understood by gcc1.  Use cpp to avoid major code duplication.  */
92 #if __GNUC__ < 2
93 #define __CLOBBER_CC
94 #define __AND_CLOBBER_CC
95 #else /* __GNUC__ >= 2 */
96 #define __CLOBBER_CC : "cc"
97 #define __AND_CLOBBER_CC , "cc"
98 #endif /* __GNUC__ < 2 */
99
100 #if (defined (__a29k__) || defined (___AM29K__)) && W_TYPE_SIZE == 32
101 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
102   __asm__ ("add %1,%4,%5
103         addc %0,%2,%3"                                                  \
104            : "=r" ((USItype)(sh)),                                      \
105             "=&r" ((USItype)(sl))                                       \
106            : "%r" ((USItype)(ah)),                                      \
107              "rI" ((USItype)(bh)),                                      \
108              "%r" ((USItype)(al)),                                      \
109              "rI" ((USItype)(bl)))
110 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
111   __asm__ ("sub %1,%4,%5
112         subc %0,%2,%3"                                                  \
113            : "=r" ((USItype)(sh)),                                      \
114              "=&r" ((USItype)(sl))                                      \
115            : "r" ((USItype)(ah)),                                       \
116              "rI" ((USItype)(bh)),                                      \
117              "r" ((USItype)(al)),                                       \
118              "rI" ((USItype)(bl)))
119 #define umul_ppmm(xh, xl, m0, m1) \
120   do {                                                                  \
121     USItype __m0 = (m0), __m1 = (m1);                                   \
122     __asm__ ("multiplu %0,%1,%2"                                        \
123              : "=r" ((USItype)(xl))                                     \
124              : "r" (__m0),                                              \
125                "r" (__m1));                                             \
126     __asm__ ("multmu %0,%1,%2"                                          \
127              : "=r" ((USItype)(xh))                                     \
128              : "r" (__m0),                                              \
129                "r" (__m1));                                             \
130   } while (0)
131 #define udiv_qrnnd(q, r, n1, n0, d) \
132   __asm__ ("dividu %0,%3,%4"                                            \
133            : "=r" ((USItype)(q)),                                       \
134              "=q" ((USItype)(r))                                        \
135            : "1" ((USItype)(n1)),                                       \
136              "r" ((USItype)(n0)),                                       \
137              "r" ((USItype)(d)))
138 #define count_leading_zeros(count, x) \
139     __asm__ ("clz %0,%1"                                                \
140              : "=r" ((USItype)(count))                                  \
141              : "r" ((USItype)(x)))
142 #endif /* __a29k__ */
143
144 #if defined (__alpha__) && W_TYPE_SIZE == 64
145 #define umul_ppmm(ph, pl, m0, m1) \
146   do {                                                                  \
147     UDItype __m0 = (m0), __m1 = (m1);                                   \
148     __asm__ ("umulh %r1,%2,%0"                                          \
149              : "=r" ((UDItype) ph)                                      \
150              : "%rJ" (__m0),                                            \
151                "rI" (__m1));                                            \
152     (pl) = __m0 * __m1;                                                 \
153   } while (0)
154 #define UMUL_TIME 46
155 #define udiv_qrnnd(q, r, n1, n0, d) \
156   do { UDItype __r;                                                     \
157     (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                         \
158     (r) = __r;                                                          \
159   } while (0)
160 extern UDItype __udiv_qrnnd ();
161 #define UDIV_TIME 220
162 #endif
163
164 #if defined (__arm__) && W_TYPE_SIZE == 32
165 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
166   __asm__ ("adds %1,%4,%5
167         adc %0,%2,%3"                                                   \
168            : "=r" ((USItype)(sh)),                                      \
169              "=&r" ((USItype)(sl))                                      \
170            : "%r" ((USItype)(ah)),                                      \
171              "rI" ((USItype)(bh)),                                      \
172              "%r" ((USItype)(al)),                                      \
173              "rI" ((USItype)(bl)))
174 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
175   __asm__ ("subs %1,%4,%5
176         sbc %0,%2,%3"                                                   \
177            : "=r" ((USItype)(sh)),                                      \
178              "=&r" ((USItype)(sl))                                      \
179            : "r" ((USItype)(ah)),                                       \
180              "rI" ((USItype)(bh)),                                      \
181              "r" ((USItype)(al)),                                       \
182              "rI" ((USItype)(bl)))
183 #define umul_ppmm(xh, xl, a, b) \
184   __asm__ ("; Inlined umul_ppmm
185         mov     r0,%2 lsr 16
186         mov     r2,%3 lsr 16
187         bic     r1,%2,r0 lsl 16
188         bic     r2,%3,r2 lsl 16
189         mul     %1,r1,r2
190         mul     r2,r0,r2
191         mul     r1,%0,r1
192         mul     %0,r0,%0
193         adds    r1,r2,r1
194         addcs   %0,%0,0x10000
195         adds    %1,%1,r1 lsl 16
196         adc     %0,%0,r1 lsr 16"                                        \
197            : "=&r" ((USItype)(xh)),                                     \
198              "=r" ((USItype)(xl))                                       \
199            : "r" ((USItype)(a)),                                        \
200              "r" ((USItype)(b))                                         \
201            : "r0", "r1", "r2")
202 #define UMUL_TIME 20
203 #define UDIV_TIME 100
204 #endif /* __arm__ */
205
206 #if defined (__clipper__) && W_TYPE_SIZE == 32
207 #define umul_ppmm(w1, w0, u, v) \
208   ({union {UDItype __ll;                                                \
209            struct {USItype __l, __h;} __i;                              \
210           } __xx;                                                       \
211   __asm__ ("mulwux %2,%0"                                               \
212            : "=r" (__xx.__ll)                                           \
213            : "%0" ((USItype)(u)),                                       \
214              "r" ((USItype)(v)));                                       \
215   (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
216 #define smul_ppmm(w1, w0, u, v) \
217   ({union {DItype __ll;                                                 \
218            struct {SItype __l, __h;} __i;                               \
219           } __xx;                                                       \
220   __asm__ ("mulwx %2,%0"                                                \
221            : "=r" (__xx.__ll)                                           \
222            : "%0" ((SItype)(u)),                                        \
223              "r" ((SItype)(v)));                                        \
224   (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
225 #define __umulsidi3(u, v) \
226   ({UDItype __w;                                                        \
227     __asm__ ("mulwux %2,%0"                                             \
228              : "=r" (__w)                                               \
229              : "%0" ((USItype)(u)),                                     \
230                "r" ((USItype)(v)));                                     \
231     __w; })
232 #endif /* __clipper__ */
233
234 #if defined (__gmicro__) && W_TYPE_SIZE == 32
235 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
236   __asm__ ("add.w %5,%1
237         addx %3,%0"                                                     \
238            : "=g" ((USItype)(sh)),                                      \
239              "=&g" ((USItype)(sl))                                      \
240            : "%0" ((USItype)(ah)),                                      \
241              "g" ((USItype)(bh)),                                       \
242              "%1" ((USItype)(al)),                                      \
243              "g" ((USItype)(bl)))
244 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
245   __asm__ ("sub.w %5,%1
246         subx %3,%0"                                                     \
247            : "=g" ((USItype)(sh)),                                      \
248              "=&g" ((USItype)(sl))                                      \
249            : "0" ((USItype)(ah)),                                       \
250              "g" ((USItype)(bh)),                                       \
251              "1" ((USItype)(al)),                                       \
252              "g" ((USItype)(bl)))
253 #define umul_ppmm(ph, pl, m0, m1) \
254   __asm__ ("mulx %3,%0,%1"                                              \
255            : "=g" ((USItype)(ph)),                                      \
256              "=r" ((USItype)(pl))                                       \
257            : "%0" ((USItype)(m0)),                                      \
258              "g" ((USItype)(m1)))
259 #define udiv_qrnnd(q, r, nh, nl, d) \
260   __asm__ ("divx %4,%0,%1"                                              \
261            : "=g" ((USItype)(q)),                                       \
262              "=r" ((USItype)(r))                                        \
263            : "1" ((USItype)(nh)),                                       \
264              "0" ((USItype)(nl)),                                       \
265              "g" ((USItype)(d)))
266 #define count_leading_zeros(count, x) \
267   __asm__ ("bsch/1 %1,%0"                                               \
268            : "=g" (count)                                               \
269            : "g" ((USItype)(x)),                                        \
270              "0" ((USItype)0))
271 #endif
272
273 #if defined (__hppa) && W_TYPE_SIZE == 32
274 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
275   __asm__ ("add %4,%5,%1
276         addc %2,%3,%0"                                                  \
277            : "=r" ((USItype)(sh)),                                      \
278              "=&r" ((USItype)(sl))                                      \
279            : "%rM" ((USItype)(ah)),                                     \
280              "rM" ((USItype)(bh)),                                      \
281              "%rM" ((USItype)(al)),                                     \
282              "rM" ((USItype)(bl)))
283 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
284   __asm__ ("sub %4,%5,%1
285         subb %2,%3,%0"                                                  \
286            : "=r" ((USItype)(sh)),                                      \
287              "=&r" ((USItype)(sl))                                      \
288            : "rM" ((USItype)(ah)),                                      \
289              "rM" ((USItype)(bh)),                                      \
290              "rM" ((USItype)(al)),                                      \
291              "rM" ((USItype)(bl)))
292 #if defined (_PA_RISC1_1)
293 #define umul_ppmm(wh, wl, u, v) \
294   do {                                                                  \
295     union {UDItype __ll;                                                \
296            struct {USItype __h, __l;} __i;                              \
297           } __xx;                                                       \
298     __asm__ ("xmpyu %1,%2,%0"                                           \
299              : "=x" (__xx.__ll)                                         \
300              : "x" ((USItype)(u)),                                      \
301                "x" ((USItype)(v)));                                     \
302     (wh) = __xx.__i.__h;                                                \
303     (wl) = __xx.__i.__l;                                                \
304   } while (0)
305 #define UMUL_TIME 8
306 #define UDIV_TIME 60
307 #else
308 #define UMUL_TIME 40
309 #define UDIV_TIME 80
310 #endif
311 #define udiv_qrnnd(q, r, n1, n0, d) \
312   do { USItype __r;                                                     \
313     (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                         \
314     (r) = __r;                                                          \
315   } while (0)
316 extern USItype __udiv_qrnnd ();
317 #define count_leading_zeros(count, x) \
318   do {                                                                  \
319     USItype __tmp;                                                      \
320     __asm__ (                                                           \
321        "ldi             1,%0
322         extru,=         %1,15,16,%%r0           ; Bits 31..16 zero?
323         extru,tr        %1,15,16,%1             ; No.  Shift down, skip add.
324         ldo             16(%0),%0               ; Yes.  Perform add.
325         extru,=         %1,23,8,%%r0            ; Bits 15..8 zero?
326         extru,tr        %1,23,8,%1              ; No.  Shift down, skip add.
327         ldo             8(%0),%0                ; Yes.  Perform add.
328         extru,=         %1,27,4,%%r0            ; Bits 7..4 zero?
329         extru,tr        %1,27,4,%1              ; No.  Shift down, skip add.
330         ldo             4(%0),%0                ; Yes.  Perform add.
331         extru,=         %1,29,2,%%r0            ; Bits 3..2 zero?
332         extru,tr        %1,29,2,%1              ; No.  Shift down, skip add.
333         ldo             2(%0),%0                ; Yes.  Perform add.
334         extru           %1,30,1,%1              ; Extract bit 1.
335         sub             %0,%1,%0                ; Subtract it.
336         " : "=r" (count), "=r" (__tmp) : "1" (x));                      \
337   } while (0)
338 #endif
339
340 #if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
341 #define umul_ppmm(xh, xl, m0, m1) \
342   do {                                                                  \
343     union {UDItype __ll;                                                \
344            struct {USItype __h, __l;} __i;                              \
345           } __xx;                                                       \
346     USItype __m0 = (m0), __m1 = (m1);                                   \
347     __asm__ ("mr %0,%3"                                                 \
348              : "=r" (__xx.__i.__h),                                     \
349                "=r" (__xx.__i.__l)                                      \
350              : "%1" (__m0),                                             \
351                "r" (__m1));                                             \
352     (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;                           \
353     (xh) += ((((SItype) __m0 >> 31) & __m1)                             \
354              + (((SItype) __m1 >> 31) & __m0));                         \
355   } while (0)
356 #define smul_ppmm(xh, xl, m0, m1) \
357   do {                                                                  \
358     union {DItype __ll;                                                 \
359            struct {USItype __h, __l;} __i;                              \
360           } __xx;                                                       \
361     __asm__ ("mr %0,%3"                                                 \
362              : "=r" (__xx.__i.__h),                                     \
363                "=r" (__xx.__i.__l)                                      \
364              : "%1" (m0),                                               \
365                "r" (m1));                                               \
366     (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;                           \
367   } while (0)
368 #define sdiv_qrnnd(q, r, n1, n0, d) \
369   do {                                                                  \
370     union {DItype __ll;                                                 \
371            struct {USItype __h, __l;} __i;                              \
372           } __xx;                                                       \
373     __xx.__i.__h = n1; __xx.__i.__l = n0;                               \
374     __asm__ ("dr %0,%2"                                                 \
375              : "=r" (__xx.__ll)                                         \
376              : "0" (__xx.__ll), "r" (d));                               \
377     (q) = __xx.__i.__l; (r) = __xx.__i.__h;                             \
378   } while (0)
379 #endif
380
381 #if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
382 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
383   __asm__ ("addl %5,%1
384         adcl %3,%0"                                                     \
385            : "=r" ((USItype)(sh)),                                      \
386              "=&r" ((USItype)(sl))                                      \
387            : "%0" ((USItype)(ah)),                                      \
388              "g" ((USItype)(bh)),                                       \
389              "%1" ((USItype)(al)),                                      \
390              "g" ((USItype)(bl)))
391 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
392   __asm__ ("subl %5,%1
393         sbbl %3,%0"                                                     \
394            : "=r" ((USItype)(sh)),                                      \
395              "=&r" ((USItype)(sl))                                      \
396            : "0" ((USItype)(ah)),                                       \
397              "g" ((USItype)(bh)),                                       \
398              "1" ((USItype)(al)),                                       \
399              "g" ((USItype)(bl)))
400 #define umul_ppmm(w1, w0, u, v) \
401   __asm__ ("mull %3"                                                    \
402            : "=a" ((USItype)(w0)),                                      \
403              "=d" ((USItype)(w1))                                       \
404            : "%0" ((USItype)(u)),                                       \
405              "rm" ((USItype)(v)))
406 #define udiv_qrnnd(q, r, n1, n0, d) \
407   __asm__ ("divl %4"                                                    \
408            : "=a" ((USItype)(q)),                                       \
409              "=d" ((USItype)(r))                                        \
410            : "0" ((USItype)(n0)),                                       \
411              "1" ((USItype)(n1)),                                       \
412              "rm" ((USItype)(d)))
413 #define count_leading_zeros(count, x) \
414   do {                                                                  \
415     USItype __cbtmp;                                                    \
416     __asm__ ("bsrl %1,%0"                                               \
417              : "=r" (__cbtmp) : "rm" ((USItype)(x)));                   \
418     (count) = __cbtmp ^ 31;                                             \
419   } while (0)
420 #define count_trailing_zeros(count, x) \
421   __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
422 #define UMUL_TIME 40
423 #define UDIV_TIME 40
424 #endif /* 80x86 */
425
426 #if defined (__i960__) && W_TYPE_SIZE == 32
427 #define umul_ppmm(w1, w0, u, v) \
428   ({union {UDItype __ll;                                                \
429            struct {USItype __l, __h;} __i;                              \
430           } __xx;                                                       \
431   __asm__ ("emul        %2,%1,%0"                                       \
432            : "=d" (__xx.__ll)                                           \
433            : "%dI" ((USItype)(u)),                                      \
434              "dI" ((USItype)(v)));                                      \
435   (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
436 #define __umulsidi3(u, v) \
437   ({UDItype __w;                                                        \
438     __asm__ ("emul      %2,%1,%0"                                       \
439              : "=d" (__w)                                               \
440              : "%dI" ((USItype)(u)),                                    \
441                "dI" ((USItype)(v)));                                    \
442     __w; })  
443 #endif /* __i960__ */
444
445 #if defined (__mc68000__) && W_TYPE_SIZE == 32
446 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
447   __asm__ ("add%.l %5,%1
448         addx%.l %3,%0"                                                  \
449            : "=d" ((USItype)(sh)),                                      \
450              "=&d" ((USItype)(sl))                                      \
451            : "%0" ((USItype)(ah)),                                      \
452              "d" ((USItype)(bh)),                                       \
453              "%1" ((USItype)(al)),                                      \
454              "g" ((USItype)(bl)))
455 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
456   __asm__ ("sub%.l %5,%1
457         subx%.l %3,%0"                                                  \
458            : "=d" ((USItype)(sh)),                                      \
459              "=&d" ((USItype)(sl))                                      \
460            : "0" ((USItype)(ah)),                                       \
461              "d" ((USItype)(bh)),                                       \
462              "1" ((USItype)(al)),                                       \
463              "g" ((USItype)(bl)))
464 #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
465 #define umul_ppmm(w1, w0, u, v) \
466   __asm__ ("mulu%.l %3,%1:%0"                                           \
467            : "=d" ((USItype)(w0)),                                      \
468              "=d" ((USItype)(w1))                                       \
469            : "%0" ((USItype)(u)),                                       \
470              "dmi" ((USItype)(v)))
471 #define UMUL_TIME 45
472 #define udiv_qrnnd(q, r, n1, n0, d) \
473   __asm__ ("divu%.l %4,%1:%0"                                           \
474            : "=d" ((USItype)(q)),                                       \
475              "=d" ((USItype)(r))                                        \
476            : "0" ((USItype)(n0)),                                       \
477              "1" ((USItype)(n1)),                                       \
478              "dmi" ((USItype)(d)))
479 #define UDIV_TIME 90
480 #define sdiv_qrnnd(q, r, n1, n0, d) \
481   __asm__ ("divs%.l %4,%1:%0"                                           \
482            : "=d" ((USItype)(q)),                                       \
483              "=d" ((USItype)(r))                                        \
484            : "0" ((USItype)(n0)),                                       \
485              "1" ((USItype)(n1)),                                       \
486              "dmi" ((USItype)(d)))
487 #define count_leading_zeros(count, x) \
488   __asm__ ("bfffo %1{%b2:%b2},%0"                                       \
489            : "=d" ((USItype)(count))                                    \
490            : "od" ((USItype)(x)), "n" (0))
491 #else /* not mc68020 */
492 #define umul_ppmm(xh, xl, a, b) \
493   __asm__ ("| Inlined umul_ppmm
494         move%.l %2,%/d0
495         move%.l %3,%/d1
496         move%.l %/d0,%/d2
497         swap    %/d0
498         move%.l %/d1,%/d3
499         swap    %/d1
500         move%.w %/d2,%/d4
501         mulu    %/d3,%/d4
502         mulu    %/d1,%/d2
503         mulu    %/d0,%/d3
504         mulu    %/d0,%/d1
505         move%.l %/d4,%/d0
506         eor%.w  %/d0,%/d0
507         swap    %/d0
508         add%.l  %/d0,%/d2
509         add%.l  %/d3,%/d2
510         jcc     1f
511         add%.l  #65536,%/d1
512 1:      swap    %/d2
513         moveq   #0,%/d0
514         move%.w %/d2,%/d0
515         move%.w %/d4,%/d2
516         move%.l %/d2,%1
517         add%.l  %/d1,%/d0
518         move%.l %/d0,%0"                                                \
519            : "=g" ((USItype)(xh)),                                      \
520              "=g" ((USItype)(xl))                                       \
521            : "g" ((USItype)(a)),                                        \
522              "g" ((USItype)(b))                                         \
523            : "d0", "d1", "d2", "d3", "d4")
524 #define UMUL_TIME 100
525 #define UDIV_TIME 400
526 #endif /* not mc68020 */
527 #endif /* mc68000 */
528
529 #if defined (__m88000__) && W_TYPE_SIZE == 32
530 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
531   __asm__ ("addu.co %1,%r4,%r5
532         addu.ci %0,%r2,%r3"                                             \
533            : "=r" ((USItype)(sh)),                                      \
534              "=&r" ((USItype)(sl))                                      \
535            : "%rJ" ((USItype)(ah)),                                     \
536              "rJ" ((USItype)(bh)),                                      \
537              "%rJ" ((USItype)(al)),                                     \
538              "rJ" ((USItype)(bl)))
539 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
540   __asm__ ("subu.co %1,%r4,%r5
541         subu.ci %0,%r2,%r3"                                             \
542            : "=r" ((USItype)(sh)),                                      \
543              "=&r" ((USItype)(sl))                                      \
544            : "rJ" ((USItype)(ah)),                                      \
545              "rJ" ((USItype)(bh)),                                      \
546              "rJ" ((USItype)(al)),                                      \
547              "rJ" ((USItype)(bl)))
548 #define count_leading_zeros(count, x) \
549   do {                                                                  \
550     USItype __cbtmp;                                                    \
551     __asm__ ("ff1 %0,%1"                                                \
552              : "=r" (__cbtmp)                                           \
553              : "r" ((USItype)(x)));                                     \
554     (count) = __cbtmp ^ 31;                                             \
555   } while (0)
556 #if defined (__mc88110__)
557 #define umul_ppmm(wh, wl, u, v) \
558   do {                                                                  \
559     union {UDItype __ll;                                                \
560            struct {USItype __h, __l;} __i;                              \
561           } __xx;                                                       \
562     __asm__ ("mulu.d    %0,%1,%2"                                       \
563              : "=r" (__xx.__ll)                                         \
564              : "r" ((USItype)(u)),                                      \
565                "r" ((USItype)(v)));                                     \
566     (wh) = __xx.__i.__h;                                                \
567     (wl) = __xx.__i.__l;                                                \
568   } while (0)
569 #define udiv_qrnnd(q, r, n1, n0, d) \
570   ({union {UDItype __ll;                                                \
571            struct {USItype __h, __l;} __i;                              \
572           } __xx;                                                       \
573   USItype __q;                                                          \
574   __xx.__i.__h = (n1); __xx.__i.__l = (n0);                             \
575   __asm__ ("divu.d %0,%1,%2"                                            \
576            : "=r" (__q)                                                 \
577            : "r" (__xx.__ll),                                           \
578              "r" ((USItype)(d)));                                       \
579   (r) = (n0) - __q * (d); (q) = __q; })
580 #define UMUL_TIME 5
581 #define UDIV_TIME 25
582 #else
583 #define UMUL_TIME 17
584 #define UDIV_TIME 150
585 #endif /* __mc88110__ */
586 #endif /* __m88000__ */
587
588 #if defined (__mips__) && W_TYPE_SIZE == 32
589 #define umul_ppmm(w1, w0, u, v) \
590   __asm__ ("multu %2,%3
591         mflo %0
592         mfhi %1"                                                        \
593            : "=d" ((USItype)(w0)),                                      \
594              "=d" ((USItype)(w1))                                       \
595            : "d" ((USItype)(u)),                                        \
596              "d" ((USItype)(v)))
597 #define UMUL_TIME 10
598 #define UDIV_TIME 100
599 #endif /* __mips__ */
600
601 #if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
602 #define umul_ppmm(w1, w0, u, v) \
603   __asm__ ("dmultu %2,%3
604         mflo %0
605         mfhi %1"                                                        \
606            : "=d" ((UDItype)(w0)),                                      \
607              "=d" ((UDItype)(w1))                                       \
608            : "d" ((UDItype)(u)),                                        \
609              "d" ((UDItype)(v)))
610 #define UMUL_TIME 10
611 #define UDIV_TIME 100
612 #endif /* __mips__ */
613
614 #if defined (__ns32000__) && W_TYPE_SIZE == 32
615 #define umul_ppmm(w1, w0, u, v) \
616   ({union {UDItype __ll;                                                \
617            struct {USItype __l, __h;} __i;                              \
618           } __xx;                                                       \
619   __asm__ ("meid %2,%0"                                                 \
620            : "=g" (__xx.__ll)                                           \
621            : "%0" ((USItype)(u)),                                       \
622              "g" ((USItype)(v)));                                       \
623   (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
624 #define __umulsidi3(u, v) \
625   ({UDItype __w;                                                        \
626     __asm__ ("meid %2,%0"                                               \
627              : "=g" (__w)                                               \
628              : "%0" ((USItype)(u)),                                     \
629                "g" ((USItype)(v)));                                     \
630     __w; })
631 #define udiv_qrnnd(q, r, n1, n0, d) \
632   ({union {UDItype __ll;                                                \
633            struct {USItype __l, __h;} __i;                              \
634           } __xx;                                                       \
635   __xx.__i.__h = (n1); __xx.__i.__l = (n0);                             \
636   __asm__ ("deid %2,%0"                                                 \
637            : "=g" (__xx.__ll)                                           \
638            : "0" (__xx.__ll),                                           \
639              "g" ((USItype)(d)));                                       \
640   (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
641 #define count_trailing_zeros(count,x) \
642   do {
643     __asm__ ("ffsd      %2,%0"                                          \
644              : "=r" ((USItype) (count))                                 \
645              : "0" ((USItype) 0),                                       \
646                "r" ((USItype) (x)));                                    \
647   } while (0)
648 #endif /* __ns32000__ */
649
650 #if (defined (__powerpc__) || defined (___IBMR2__)) && W_TYPE_SIZE == 32
651 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
652   do {                                                                  \
653     if (__builtin_constant_p (bh) && (bh) == 0)                         \
654       __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2"           \
655              : "=r" ((USItype)(sh)),                                    \
656                "=&r" ((USItype)(sl))                                    \
657              : "%r" ((USItype)(ah)),                                    \
658                "%r" ((USItype)(al)),                                    \
659                "rI" ((USItype)(bl)));                                   \
660     else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0)          \
661       __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2"           \
662              : "=r" ((USItype)(sh)),                                    \
663                "=&r" ((USItype)(sl))                                    \
664              : "%r" ((USItype)(ah)),                                    \
665                "%r" ((USItype)(al)),                                    \
666                "rI" ((USItype)(bl)));                                   \
667     else                                                                \
668       __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3"          \
669              : "=r" ((USItype)(sh)),                                    \
670                "=&r" ((USItype)(sl))                                    \
671              : "%r" ((USItype)(ah)),                                    \
672                "r" ((USItype)(bh)),                                     \
673                "%r" ((USItype)(al)),                                    \
674                "rI" ((USItype)(bl)));                                   \
675   } while (0)
676 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
677   do {                                                                  \
678     if (__builtin_constant_p (ah) && (ah) == 0)                         \
679       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"               \
680                : "=r" ((USItype)(sh)),                                  \
681                  "=&r" ((USItype)(sl))                                  \
682                : "r" ((USItype)(bh)),                                   \
683                  "rI" ((USItype)(al)),                                  \
684                  "r" ((USItype)(bl)));                                  \
685     else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0)          \
686       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"               \
687                : "=r" ((USItype)(sh)),                                  \
688                  "=&r" ((USItype)(sl))                                  \
689                : "r" ((USItype)(bh)),                                   \
690                  "rI" ((USItype)(al)),                                  \
691                  "r" ((USItype)(bl)));                                  \
692     else if (__builtin_constant_p (bh) && (bh) == 0)                    \
693       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2"         \
694                : "=r" ((USItype)(sh)),                                  \
695                  "=&r" ((USItype)(sl))                                  \
696                : "r" ((USItype)(ah)),                                   \
697                  "rI" ((USItype)(al)),                                  \
698                  "r" ((USItype)(bl)));                                  \
699     else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0)          \
700       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2"         \
701                : "=r" ((USItype)(sh)),                                  \
702                  "=&r" ((USItype)(sl))                                  \
703                : "r" ((USItype)(ah)),                                   \
704                  "rI" ((USItype)(al)),                                  \
705                  "r" ((USItype)(bl)));                                  \
706     else                                                                \
707       __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"      \
708                : "=r" ((USItype)(sh)),                                  \
709                  "=&r" ((USItype)(sl))                                  \
710                : "r" ((USItype)(ah)),                                   \
711                  "r" ((USItype)(bh)),                                   \
712                  "rI" ((USItype)(al)),                                  \
713                  "r" ((USItype)(bl)));                                  \
714   } while (0)
715 #define count_leading_zeros(count, x) \
716   __asm__ ("{cntlz|cntlzw} %0,%1"                                       \
717            : "=r" ((USItype)(count))                                    \
718            : "r" ((USItype)(x)))
719 #if defined (__powerpc__)
720 #define umul_ppmm(ph, pl, m0, m1) \
721   do {                                                                  \
722     USItype __m0 = (m0), __m1 = (m1);                                   \
723     __asm__ ("mulhwu %0,%1,%2"                                          \
724              : "=r" ((USItype) ph)                                      \
725              : "%r" (__m0),                                             \
726                "r" (__m1));                                             \
727     (pl) = __m0 * __m1;                                                 \
728   } while (0)
729 #define UMUL_TIME 15
730 #define smul_ppmm(ph, pl, m0, m1) \
731   do {                                                                  \
732     SItype __m0 = (m0), __m1 = (m1);                                    \
733     __asm__ ("mulhw %0,%1,%2"                                           \
734              : "=r" ((SItype) ph)                                       \
735              : "%r" (__m0),                                             \
736                "r" (__m1));                                             \
737     (pl) = __m0 * __m1;                                                 \
738   } while (0)
739 #define SMUL_TIME 14
740 #define UDIV_TIME 120
741 #else
742 #define umul_ppmm(xh, xl, m0, m1) \
743   do {                                                                  \
744     USItype __m0 = (m0), __m1 = (m1);                                   \
745     __asm__ ("mul %0,%2,%3"                                             \
746              : "=r" ((USItype)(xh)),                                    \
747                "=q" ((USItype)(xl))                                     \
748              : "r" (__m0),                                              \
749                "r" (__m1));                                             \
750     (xh) += ((((SItype) __m0 >> 31) & __m1)                             \
751              + (((SItype) __m1 >> 31) & __m0));                         \
752   } while (0)
753 #define UMUL_TIME 8
754 #define smul_ppmm(xh, xl, m0, m1) \
755   __asm__ ("mul %0,%2,%3"                                               \
756            : "=r" ((SItype)(xh)),                                       \
757              "=q" ((SItype)(xl))                                        \
758            : "r" (m0),                                                  \
759              "r" (m1))
760 #define SMUL_TIME 4
761 #define sdiv_qrnnd(q, r, nh, nl, d) \
762   __asm__ ("div %0,%2,%4"                                               \
763            : "=r" ((SItype)(q)), "=q" ((SItype)(r))                     \
764            : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
765 #define UDIV_TIME 100
766 #endif
767 #endif /* Power architecture variants.  */
768
769 #if defined (__pyr__) && W_TYPE_SIZE == 32
770 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
771   __asm__ ("addw        %5,%1
772         addwc   %3,%0"                                                  \
773            : "=r" ((USItype)(sh)),                                      \
774              "=&r" ((USItype)(sl))                                      \
775            : "%0" ((USItype)(ah)),                                      \
776              "g" ((USItype)(bh)),                                       \
777              "%1" ((USItype)(al)),                                      \
778              "g" ((USItype)(bl)))
779 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
780   __asm__ ("subw        %5,%1
781         subwb   %3,%0"                                                  \
782            : "=r" ((USItype)(sh)),                                      \
783              "=&r" ((USItype)(sl))                                      \
784            : "0" ((USItype)(ah)),                                       \
785              "g" ((USItype)(bh)),                                       \
786              "1" ((USItype)(al)),                                       \
787              "g" ((USItype)(bl)))
788 /* This insn doesn't work on ancient pyramids.  */
789 #define umul_ppmm(w1, w0, u, v) \
790   ({union {UDItype __ll;                                                \
791            struct {USItype __h, __l;} __i;                              \
792           } __xx;                                                       \
793   __xx.__i.__l = u;                                                     \
794   __asm__ ("uemul %3,%0"                                                \
795            : "=r" (__xx.__i.__h),                                       \
796              "=r" (__xx.__i.__l)                                        \
797            : "1" (__xx.__i.__l),                                        \
798              "g" ((USItype)(v)));                                       \
799   (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
800 #endif /* __pyr__ */
801
802 #if defined (__ibm032__) /* RT/ROMP */  && W_TYPE_SIZE == 32
803 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
804   __asm__ ("a %1,%5
805         ae %0,%3"                                                       \
806            : "=r" ((USItype)(sh)),                                      \
807              "=&r" ((USItype)(sl))                                      \
808            : "%0" ((USItype)(ah)),                                      \
809              "r" ((USItype)(bh)),                                       \
810              "%1" ((USItype)(al)),                                      \
811              "r" ((USItype)(bl)))
812 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
813   __asm__ ("s %1,%5
814         se %0,%3"                                                       \
815            : "=r" ((USItype)(sh)),                                      \
816              "=&r" ((USItype)(sl))                                      \
817            : "0" ((USItype)(ah)),                                       \
818              "r" ((USItype)(bh)),                                       \
819              "1" ((USItype)(al)),                                       \
820              "r" ((USItype)(bl)))
821 #define umul_ppmm(ph, pl, m0, m1) \
822   do {                                                                  \
823     USItype __m0 = (m0), __m1 = (m1);                                   \
824     __asm__ (                                                           \
825        "s       r2,r2
826         mts     r10,%2
827         m       r2,%3
828         m       r2,%3
829         m       r2,%3
830         m       r2,%3
831         m       r2,%3
832         m       r2,%3
833         m       r2,%3
834         m       r2,%3
835         m       r2,%3
836         m       r2,%3
837         m       r2,%3
838         m       r2,%3
839         m       r2,%3
840         m       r2,%3
841         m       r2,%3
842         m       r2,%3
843         cas     %0,r2,r0
844         mfs     r10,%1"                                                 \
845              : "=r" ((USItype)(ph)),                                    \
846                "=r" ((USItype)(pl))                                     \
847              : "%r" (__m0),                                             \
848                 "r" (__m1)                                              \
849              : "r2");                                                   \
850     (ph) += ((((SItype) __m0 >> 31) & __m1)                             \
851              + (((SItype) __m1 >> 31) & __m0));                         \
852   } while (0)
853 #define UMUL_TIME 20
854 #define UDIV_TIME 200
855 #define count_leading_zeros(count, x) \
856   do {                                                                  \
857     if ((x) >= 0x10000)                                                 \
858       __asm__ ("clz     %0,%1"                                          \
859                : "=r" ((USItype)(count))                                \
860                : "r" ((USItype)(x) >> 16));                             \
861     else                                                                \
862       {                                                                 \
863         __asm__ ("clz   %0,%1"                                          \
864                  : "=r" ((USItype)(count))                              \
865                  : "r" ((USItype)(x)));                                 \
866         (count) += 16;                                                  \
867       }                                                                 \
868   } while (0)
869 #endif
870
871 #if defined (__sparc__) && W_TYPE_SIZE == 32
872 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
873   __asm__ ("addcc %r4,%5,%1
874         addx %r2,%3,%0"                                                 \
875            : "=r" ((USItype)(sh)),                                      \
876              "=&r" ((USItype)(sl))                                      \
877            : "%rJ" ((USItype)(ah)),                                     \
878              "rI" ((USItype)(bh)),                                      \
879              "%rJ" ((USItype)(al)),                                     \
880              "rI" ((USItype)(bl))                                       \
881            __CLOBBER_CC)
882 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
883   __asm__ ("subcc %r4,%5,%1
884         subx %r2,%3,%0"                                                 \
885            : "=r" ((USItype)(sh)),                                      \
886              "=&r" ((USItype)(sl))                                      \
887            : "rJ" ((USItype)(ah)),                                      \
888              "rI" ((USItype)(bh)),                                      \
889              "rJ" ((USItype)(al)),                                      \
890              "rI" ((USItype)(bl))                                       \
891            __CLOBBER_CC)
892 #if defined (__sparc_v8__)
893 /* Don't match immediate range because, 1) it is not often useful,
894    2) the 'I' flag thinks of the range as a 13 bit signed interval,
895    while we want to match a 13 bit interval, sign extended to 32 bits,
896    but INTERPRETED AS UNSIGNED.  */
897 #define umul_ppmm(w1, w0, u, v) \
898   __asm__ ("umul %2,%3,%1;rd %%y,%0"                                    \
899            : "=r" ((USItype)(w1)),                                      \
900              "=r" ((USItype)(w0))                                       \
901            : "r" ((USItype)(u)),                                        \
902              "r" ((USItype)(v)))
903 #define UMUL_TIME 5
904 /* We might want to leave this undefined for `SuperSPARC (tm)' since
905    its implementation is crippled and often traps.  */
906 #define udiv_qrnnd(q, r, n1, n0, d) \
907   __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
908            : "=&r" ((USItype)(q)),                                      \
909              "=&r" ((USItype)(r))                                       \
910            : "r" ((USItype)(n1)),                                       \
911              "r" ((USItype)(n0)),                                       \
912              "r" ((USItype)(d)))
913 #define UDIV_TIME 25
914 #else
915 #if defined (__sparclite__)
916 /* This has hardware multiply but not divide.  It also has two additional
917    instructions scan (ffs from high bit) and divscc.  */
918 #define umul_ppmm(w1, w0, u, v) \
919   __asm__ ("umul %2,%3,%1;rd %%y,%0"                                    \
920            : "=r" ((USItype)(w1)),                                      \
921              "=r" ((USItype)(w0))                                       \
922            : "r" ((USItype)(u)),                                        \
923              "r" ((USItype)(v)))
924 #define UMUL_TIME 5
925 #define udiv_qrnnd(q, r, n1, n0, d) \
926   __asm__ ("! Inlined udiv_qrnnd
927         wr      %%g0,%2,%%y     ! Not a delayed write for sparclite
928         tst     %%g0
929         divscc  %3,%4,%%g1
930         divscc  %%g1,%4,%%g1
931         divscc  %%g1,%4,%%g1
932         divscc  %%g1,%4,%%g1
933         divscc  %%g1,%4,%%g1
934         divscc  %%g1,%4,%%g1
935         divscc  %%g1,%4,%%g1
936         divscc  %%g1,%4,%%g1
937         divscc  %%g1,%4,%%g1
938         divscc  %%g1,%4,%%g1
939         divscc  %%g1,%4,%%g1
940         divscc  %%g1,%4,%%g1
941         divscc  %%g1,%4,%%g1
942         divscc  %%g1,%4,%%g1
943         divscc  %%g1,%4,%%g1
944         divscc  %%g1,%4,%%g1
945         divscc  %%g1,%4,%%g1
946         divscc  %%g1,%4,%%g1
947         divscc  %%g1,%4,%%g1
948         divscc  %%g1,%4,%%g1
949         divscc  %%g1,%4,%%g1
950         divscc  %%g1,%4,%%g1
951         divscc  %%g1,%4,%%g1
952         divscc  %%g1,%4,%%g1
953         divscc  %%g1,%4,%%g1
954         divscc  %%g1,%4,%%g1
955         divscc  %%g1,%4,%%g1
956         divscc  %%g1,%4,%%g1
957         divscc  %%g1,%4,%%g1
958         divscc  %%g1,%4,%%g1
959         divscc  %%g1,%4,%%g1
960         divscc  %%g1,%4,%0
961         rd      %%y,%1
962         bl,a 1f
963         add     %1,%4,%1
964 1:      ! End of inline udiv_qrnnd"                                     \
965            : "=r" ((USItype)(q)),                                       \
966              "=r" ((USItype)(r))                                        \
967            : "r" ((USItype)(n1)),                                       \
968              "r" ((USItype)(n0)),                                       \
969              "rI" ((USItype)(d))                                        \
970            : "%g1" __AND_CLOBBER_CC)
971 #define UDIV_TIME 37
972 #define count_leading_zeros(count, x) \
973   __asm__ ("scan %1,0,%0"                                               \
974            : "=r" ((USItype)(x))                                        \
975            : "r" ((USItype)(count)))
976 #else
977 /* SPARC without integer multiplication and divide instructions.
978    (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
979 #define umul_ppmm(w1, w0, u, v) \
980   __asm__ ("! Inlined umul_ppmm
981         wr      %%g0,%2,%%y     ! SPARC has 0-3 delay insn after a wr
982         sra     %3,31,%%g2      ! Don't move this insn
983         and     %2,%%g2,%%g2    ! Don't move this insn
984         andcc   %%g0,0,%%g1     ! Don't move this insn
985         mulscc  %%g1,%3,%%g1
986         mulscc  %%g1,%3,%%g1
987         mulscc  %%g1,%3,%%g1
988         mulscc  %%g1,%3,%%g1
989         mulscc  %%g1,%3,%%g1
990         mulscc  %%g1,%3,%%g1
991         mulscc  %%g1,%3,%%g1
992         mulscc  %%g1,%3,%%g1
993         mulscc  %%g1,%3,%%g1
994         mulscc  %%g1,%3,%%g1
995         mulscc  %%g1,%3,%%g1
996         mulscc  %%g1,%3,%%g1
997         mulscc  %%g1,%3,%%g1
998         mulscc  %%g1,%3,%%g1
999         mulscc  %%g1,%3,%%g1
1000         mulscc  %%g1,%3,%%g1
1001         mulscc  %%g1,%3,%%g1
1002         mulscc  %%g1,%3,%%g1
1003         mulscc  %%g1,%3,%%g1
1004         mulscc  %%g1,%3,%%g1
1005         mulscc  %%g1,%3,%%g1
1006         mulscc  %%g1,%3,%%g1
1007         mulscc  %%g1,%3,%%g1
1008         mulscc  %%g1,%3,%%g1
1009         mulscc  %%g1,%3,%%g1
1010         mulscc  %%g1,%3,%%g1
1011         mulscc  %%g1,%3,%%g1
1012         mulscc  %%g1,%3,%%g1
1013         mulscc  %%g1,%3,%%g1
1014         mulscc  %%g1,%3,%%g1
1015         mulscc  %%g1,%3,%%g1
1016         mulscc  %%g1,%3,%%g1
1017         mulscc  %%g1,0,%%g1
1018         add     %%g1,%%g2,%0
1019         rd      %%y,%1"                                                 \
1020            : "=r" ((USItype)(w1)),                                      \
1021              "=r" ((USItype)(w0))                                       \
1022            : "%rI" ((USItype)(u)),                                      \
1023              "r" ((USItype)(v))                                         \
1024            : "%g1", "%g2" __AND_CLOBBER_CC)
1025 #define UMUL_TIME 39            /* 39 instructions */
1026 #define udiv_qrnnd(q, r, n1, n0, d) \
1027   do { USItype __r;                                                     \
1028     (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                         \
1029     (r) = __r;                                                          \
1030   } while (0)
1031 extern USItype __udiv_qrnnd ();
1032 #define UDIV_TIME 140
1033 #endif /* __sparclite__ */
1034 #endif /* __sparc_v8__ */
1035 #endif /* __sparc__ */
1036
1037 #if defined (__vax__) && W_TYPE_SIZE == 32
1038 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1039   __asm__ ("addl2 %5,%1
1040         adwc %3,%0"                                                     \
1041            : "=g" ((USItype)(sh)),                                      \
1042              "=&g" ((USItype)(sl))                                      \
1043            : "%0" ((USItype)(ah)),                                      \
1044              "g" ((USItype)(bh)),                                       \
1045              "%1" ((USItype)(al)),                                      \
1046              "g" ((USItype)(bl)))
1047 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1048   __asm__ ("subl2 %5,%1
1049         sbwc %3,%0"                                                     \
1050            : "=g" ((USItype)(sh)),                                      \
1051              "=&g" ((USItype)(sl))                                      \
1052            : "0" ((USItype)(ah)),                                       \
1053              "g" ((USItype)(bh)),                                       \
1054              "1" ((USItype)(al)),                                       \
1055              "g" ((USItype)(bl)))
1056 #define umul_ppmm(xh, xl, m0, m1) \
1057   do {                                                                  \
1058     union {UDItype __ll;                                                \
1059            struct {USItype __l, __h;} __i;                              \
1060           } __xx;                                                       \
1061     USItype __m0 = (m0), __m1 = (m1);                                   \
1062     __asm__ ("emul %1,%2,$0,%0"                                         \
1063              : "=g" (__xx.__ll)                                         \
1064              : "g" (__m0),                                              \
1065                "g" (__m1));                                             \
1066     (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;                           \
1067     (xh) += ((((SItype) __m0 >> 31) & __m1)                             \
1068              + (((SItype) __m1 >> 31) & __m0));                         \
1069   } while (0)
1070 #define sdiv_qrnnd(q, r, n1, n0, d) \
1071   do {                                                                  \
1072     union {DItype __ll;                                                 \
1073            struct {SItype __l, __h;} __i;                               \
1074           } __xx;                                                       \
1075     __xx.__i.__h = n1; __xx.__i.__l = n0;                               \
1076     __asm__ ("ediv %3,%2,%0,%1"                                         \
1077              : "=g" (q), "=g" (r)                                       \
1078              : "g" (__n1n0.ll), "g" (d));                               \
1079   } while (0)
1080 #endif /* __vax__ */
1081
1082 #if defined (__z8000__) && W_TYPE_SIZE == 16
1083 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1084   __asm__ ("add %H1,%H5\n\tadc  %H0,%H3"                                \
1085            : "=r" ((unsigned int)(sh)),                                 \
1086              "=&r" ((unsigned int)(sl))                                 \
1087            : "%0" ((unsigned int)(ah)),                                 \
1088              "r" ((unsigned int)(bh)),                                  \
1089              "%1" ((unsigned int)(al)),                                 \
1090              "rQR" ((unsigned int)(bl)))
1091 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1092   __asm__ ("sub %H1,%H5\n\tsbc  %H0,%H3"                                \
1093            : "=r" ((unsigned int)(sh)),                                 \
1094              "=&r" ((unsigned int)(sl))                                 \
1095            : "0" ((unsigned int)(ah)),                                  \
1096              "r" ((unsigned int)(bh)),                                  \
1097              "1" ((unsigned int)(al)),                                  \
1098              "rQR" ((unsigned int)(bl)))
1099 #define umul_ppmm(xh, xl, m0, m1) \
1100   do {                                                                  \
1101     union {long int __ll;                                               \
1102            struct {unsigned int __h, __l;} __i;                         \
1103           } __xx;                                                       \
1104     unsigned int __m0 = (m0), __m1 = (m1);                              \
1105     __asm__ ("mult      %S0,%H3"                                        \
1106              : "=r" (__xx.__i.__h),                                     \
1107                "=r" (__xx.__i.__l)                                      \
1108              : "%1" (__m0),                                             \
1109                "rQR" (__m1));                                           \
1110     (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;                           \
1111     (xh) += ((((signed int) __m0 >> 15) & __m1)                         \
1112              + (((signed int) __m1 >> 15) & __m0));                     \
1113   } while (0)
1114 #define umul_ppmm_off(xh, xl, m0, m1) \
1115   do {                                                                  \
1116     union {long int __ll;                                               \
1117            struct {unsigned int __h, __l;} __i;                         \
1118           } __xx;                                                       \
1119     __asm__ ("mult      %S0,%H3"                                        \
1120              : "=r" (__xx.__i.__h),                                     \
1121                "=r" (__xx.__i.__l)                                      \
1122              : "%1" (m0),                                               \
1123                "rQR" (m1));                                             \
1124     (xh) = __xx.__i.__h + ((((signed int) m0 >> 15) & m1)               \
1125                            + (((signed int) m1 >> 15) & m0));           \
1126     (xl) = __xx.__i.__l;                                                \
1127   } while (0)
1128 #endif /* __z8000__ */
1129
1130 #endif /* __GNUC__ */
1131
1132
1133 #if !defined (umul_ppmm) && defined (__umulsidi3)
1134 #define umul_ppmm(ph, pl, m0, m1) \
1135   {                                                                     \
1136     UDWtype __ll = __umulsidi3 (m0, m1);                                \
1137     ph = (UWtype) (__ll >> W_TYPE_SIZE);                                \
1138     pl = (UWtype) __ll;                                                 \
1139   }
1140 #endif
1141
1142 #if !defined (__umulsidi3)
1143 #define __umulsidi3(u, v) \
1144   ({UWtype __hi, __lo;                                                  \
1145     umul_ppmm (__hi, __lo, u, v);                                       \
1146     ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
1147 #endif
1148
1149 /* If this machine has no inline assembler, use C macros.  */
1150
1151 #if !defined (add_ssaaaa)
1152 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1153   do {                                                                  \
1154     UWtype __x;                                                         \
1155     __x = (al) + (bl);                                                  \
1156     (sh) = (ah) + (bh) + (__x < (al));                                  \
1157     (sl) = __x;                                                         \
1158   } while (0)
1159 #endif
1160
1161 #if !defined (sub_ddmmss)
1162 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1163   do {                                                                  \
1164     UWtype __x;                                                         \
1165     __x = (al) - (bl);                                                  \
1166     (sh) = (ah) - (bh) - (__x > (al));                                  \
1167     (sl) = __x;                                                         \
1168   } while (0)
1169 #endif
1170
1171 #if !defined (umul_ppmm)
1172 #define umul_ppmm(w1, w0, u, v)                                         \
1173   do {                                                                  \
1174     UWtype __x0, __x1, __x2, __x3;                                      \
1175     UHWtype __ul, __vl, __uh, __vh;                                     \
1176                                                                         \
1177     __ul = __ll_lowpart (u);                                            \
1178     __uh = __ll_highpart (u);                                           \
1179     __vl = __ll_lowpart (v);                                            \
1180     __vh = __ll_highpart (v);                                           \
1181                                                                         \
1182     __x0 = (UWtype) __ul * __vl;                                        \
1183     __x1 = (UWtype) __ul * __vh;                                        \
1184     __x2 = (UWtype) __uh * __vl;                                        \
1185     __x3 = (UWtype) __uh * __vh;                                        \
1186                                                                         \
1187     __x1 += __ll_highpart (__x0);/* this can't give carry */            \
1188     __x1 += __x2;               /* but this indeed can */               \
1189     if (__x1 < __x2)            /* did we get it? */                    \
1190       __x3 += __ll_B;           /* yes, add it in the proper pos. */    \
1191                                                                         \
1192     (w1) = __x3 + __ll_highpart (__x1);                                 \
1193     (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
1194   } while (0)
1195 #endif
1196
1197 /* Define this unconditionally, so it can be used for debugging.  */
1198 #define __udiv_qrnnd_c(q, r, n1, n0, d) \
1199   do {                                                                  \
1200     UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m;                     \
1201     __d1 = __ll_highpart (d);                                           \
1202     __d0 = __ll_lowpart (d);                                            \
1203                                                                         \
1204     __r1 = (n1) % __d1;                                                 \
1205     __q1 = (n1) / __d1;                                                 \
1206     __m = (UWtype) __q1 * __d0;                                         \
1207     __r1 = __r1 * __ll_B | __ll_highpart (n0);                          \
1208     if (__r1 < __m)                                                     \
1209       {                                                                 \
1210         __q1--, __r1 += (d);                                            \
1211         if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
1212           if (__r1 < __m)                                               \
1213             __q1--, __r1 += (d);                                        \
1214       }                                                                 \
1215     __r1 -= __m;                                                        \
1216                                                                         \
1217     __r0 = __r1 % __d1;                                                 \
1218     __q0 = __r1 / __d1;                                                 \
1219     __m = (UWtype) __q0 * __d0;                                         \
1220     __r0 = __r0 * __ll_B | __ll_lowpart (n0);                           \
1221     if (__r0 < __m)                                                     \
1222       {                                                                 \
1223         __q0--, __r0 += (d);                                            \
1224         if (__r0 >= (d))                                                \
1225           if (__r0 < __m)                                               \
1226             __q0--, __r0 += (d);                                        \
1227       }                                                                 \
1228     __r0 -= __m;                                                        \
1229                                                                         \
1230     (q) = (UWtype) __q1 * __ll_B | __q0;                                \
1231     (r) = __r0;                                                         \
1232   } while (0)
1233
1234 /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
1235    __udiv_w_sdiv (defined in libgcc or elsewhere).  */
1236 #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
1237 #define udiv_qrnnd(q, r, nh, nl, d) \
1238   do {                                                                  \
1239     UWtype __r;                                                         \
1240     (q) = __udiv_w_sdiv (&__r, nh, nl, d);                              \
1241     (r) = __r;                                                          \
1242   } while (0)
1243 #endif
1244
1245 /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
1246 #if !defined (udiv_qrnnd)
1247 #define UDIV_NEEDS_NORMALIZATION 1
1248 #define udiv_qrnnd __udiv_qrnnd_c
1249 #endif
1250
1251 #if !defined (count_leading_zeros)
1252 extern
1253 #ifdef __STDC__
1254 const
1255 #endif
1256 unsigned char __clz_tab[];
1257 #define count_leading_zeros(count, x) \
1258   do {                                                                  \
1259     UWtype __xr = (x);                                                  \
1260     UWtype __a;                                                         \
1261                                                                         \
1262     if (W_TYPE_SIZE <= 32)                                              \
1263       {                                                                 \
1264         __a = __xr < ((UWtype) 1 << 2*__BITS4)                          \
1265           ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4)              \
1266           : (__xr < ((UWtype) 1 << 3*__BITS4) ?  2*__BITS4 : 3*__BITS4);\
1267       }                                                                 \
1268     else                                                                \
1269       {                                                                 \
1270         for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8)                  \
1271           if (((__xr >> __a) & 0xff) != 0)                              \
1272             break;                                                      \
1273       }                                                                 \
1274                                                                         \
1275     (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);             \
1276   } while (0)
1277 /* This version gives a well-defined value for zero. */
1278 #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
1279 #endif
1280
1281 #if !defined (count_trailing_zeros)
1282 /* Define count_trailing_zeros using count_leading_zeros.  The latter might be
1283    defined in asm, but if it is not, the C version above is good enough.  */
1284 #define count_trailing_zeros(count, x) \
1285   do {                                                                  \
1286     UWtype __ctz_x = (x);                                               \
1287     UWtype __ctz_c;                                                     \
1288     count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x);                  \
1289     (count) = W_TYPE_SIZE - 1 - __ctz_c;                                \
1290   } while (0)
1291 #endif
1292
1293 #ifndef UDIV_NEEDS_NORMALIZATION
1294 #define UDIV_NEEDS_NORMALIZATION 0
1295 #endif