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