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