OSDN Git Service

(sparclite): Use machine independent USItype instead of explicit types.
[pf3gnuchains/gcc-fork.git] / gcc / longlong.h
1 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
2    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
3
4    This definition file is free software; you can redistribute it
5    and/or modify it under the terms of the GNU General Public
6    License as published by the Free Software Foundation; either
7    version 2, or (at your option) any later version.
8
9    This definition file is distributed in the hope that it will be
10    useful, but WITHOUT ANY WARRANTY; without even the implied
11    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12    See the GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 #ifndef SI_TYPE_SIZE
19 #define SI_TYPE_SIZE 32
20 #endif
21
22 #define __BITS4 (SI_TYPE_SIZE / 4)
23 #define __ll_B (1L << (SI_TYPE_SIZE / 2))
24 #define __ll_lowpart(t) ((USItype) (t) % __ll_B)
25 #define __ll_highpart(t) ((USItype) (t) / __ll_B)
26
27 /* Define auxiliary asm macros.
28
29    1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
30    multiplies two USItype integers MULTIPLER and MULTIPLICAND,
31    and generates a two-part USItype product in HIGH_PROD and
32    LOW_PROD.
33
34    2) __umulsidi3(a,b) multiplies two USItype integers A and B,
35    and returns a UDItype product.  This is just a variant of umul_ppmm.
36
37    3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
38    denominator) divides a two-word unsigned integer, composed by the
39    integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
40    places the quotient in QUOTIENT and the remainder in REMAINDER.
41    HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
42    If, in addition, the most significant bit of DENOMINATOR must be 1,
43    then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
44
45    4) count_leading_zeros(count, x) counts the number of zero-bits from
46    the msb to the first non-zero bit.  This is the number of steps X
47    needs to be shifted left to set the msb.  Undefined for X == 0.
48
49    5) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
50    high_addend_2, low_addend_2) adds two two-word unsigned integers,
51    composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
52    LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
53    LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
54    lost.
55
56    6) sub_ddmmss(high_difference, low_difference, high_minuend,
57    low_minuend, high_subtrahend, low_subtrahend) subtracts two
58    two-word unsigned integers, composed by HIGH_MINUEND_1 and
59    LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
60    respectively.  The result is placed in HIGH_DIFFERENCE and
61    LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
62    and is lost.
63
64    If any of these macros are left undefined for a particular CPU,
65    C macros are used.  */
66
67 /* The CPUs come in alphabetical order below.
68
69    Please add support for more CPUs here, or improve the current support
70    for the CPUs below!
71    (E.g. WE32100, i960, IBM360.)  */
72
73 #if defined (__GNUC__) && !defined (NO_ASM)
74
75 /* We sometimes need to clobber "cc" with gcc2, but that would not be
76    understood by gcc1.  Use cpp to avoid major code duplication.  */
77 #if __GNUC__ < 2
78 #define __CLOBBER_CC
79 #define __AND_CLOBBER_CC
80 #else /* __GNUC__ >= 2 */
81 #define __CLOBBER_CC : "cc"
82 #define __AND_CLOBBER_CC , "cc"
83 #endif /* __GNUC__ < 2 */
84
85 #if defined (__a29k__) || defined (___AM29K__)
86 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
87   __asm__ ("add %1,%4,%5
88         addc %0,%2,%3"                                                  \
89            : "=r" ((USItype)(sh)),                                      \
90             "=&r" ((USItype)(sl))                                       \
91            : "%r" ((USItype)(ah)),                                      \
92              "rI" ((USItype)(bh)),                                      \
93              "%r" ((USItype)(al)),                                      \
94              "rI" ((USItype)(bl)))
95 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
96   __asm__ ("sub %1,%4,%5
97         subc %0,%2,%3"                                                  \
98            : "=r" ((USItype)(sh)),                                      \
99              "=&r" ((USItype)(sl))                                      \
100            : "r" ((USItype)(ah)),                                       \
101              "rI" ((USItype)(bh)),                                      \
102              "r" ((USItype)(al)),                                       \
103              "rI" ((USItype)(bl)))
104 #define umul_ppmm(xh, xl, m0, m1) \
105   do {                                                                  \
106     USItype __m0 = (m0), __m1 = (m1);                                   \
107     __asm__ ("multiplu %0,%1,%2"                                        \
108              : "=r" ((USItype)(xl))                                     \
109              : "r" (__m0),                                              \
110                "r" (__m1));                                             \
111     __asm__ ("multmu %0,%1,%2"                                          \
112              : "=r" ((USItype)(xh))                                     \
113              : "r" (__m0),                                              \
114                "r" (__m1));                                             \
115   } while (0)
116 #define udiv_qrnnd(q, r, n1, n0, d) \
117   __asm__ ("dividu %0,%3,%4"                                            \
118            : "=r" ((USItype)(q)),                                       \
119              "=q" ((USItype)(r))                                        \
120            : "1" ((USItype)(n1)),                                       \
121              "r" ((USItype)(n0)),                                       \
122              "r" ((USItype)(d)))
123 #define count_leading_zeros(count, x) \
124     __asm__ ("clz %0,%1"                                                \
125              : "=r" ((USItype)(count))                                  \
126              : "r" ((USItype)(x)))
127 #endif /* __a29k__ */
128
129 #if defined (__arm__)
130 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
131   __asm__ ("adds %1,%4,%5
132         adc %0,%2,%3"                                                   \
133            : "=r" ((USItype)(sh)),                                      \
134              "=&r" ((USItype)(sl))                                      \
135            : "%r" ((USItype)(ah)),                                      \
136              "rI" ((USItype)(bh)),                                      \
137              "%r" ((USItype)(al)),                                      \
138              "rI" ((USItype)(bl)))
139 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
140   __asm__ ("subs %1,%4,%5
141         sbc %0,%2,%3"                                                   \
142            : "=r" ((USItype)(sh)),                                      \
143              "=&r" ((USItype)(sl))                                      \
144            : "r" ((USItype)(ah)),                                       \
145              "rI" ((USItype)(bh)),                                      \
146              "r" ((USItype)(al)),                                       \
147              "rI" ((USItype)(bl)))
148 #endif /* __arm__ */
149
150 #if defined (__gmicro__)
151 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
152   __asm__ ("add.w %5,%1
153         addx %3,%0"                                                     \
154            : "=g" ((USItype)(sh)),                                      \
155              "=&g" ((USItype)(sl))                                      \
156            : "%0" ((USItype)(ah)),                                      \
157              "g" ((USItype)(bh)),                                       \
158              "%1" ((USItype)(al)),                                      \
159              "g" ((USItype)(bl)))
160 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
161   __asm__ ("sub.w %5,%1
162         subx %3,%0"                                                     \
163            : "=g" ((USItype)(sh)),                                      \
164              "=&g" ((USItype)(sl))                                      \
165            : "0" ((USItype)(ah)),                                       \
166              "g" ((USItype)(bh)),                                       \
167              "1" ((USItype)(al)),                                       \
168              "g" ((USItype)(bl)))
169 #define umul_ppmm(ph, pl, m0, m1) \
170   __asm__ ("mulx %3,%0,%1"                                              \
171            : "=g" ((USItype)(ph)),                                      \
172              "=r" ((USItype)(pl))                                       \
173            : "%0" ((USItype)(m0)),                                      \
174              "g" ((USItype)(m1)))
175 #define udiv_qrnnd(q, r, nh, nl, d) \
176   __asm__ ("divx %4,%0,%1"                                              \
177            : "=g" ((USItype)(q)),                                       \
178              "=r" ((USItype)(r))                                        \
179            : "1" ((USItype)(nh)),                                       \
180              "0" ((USItype)(nl)),                                       \
181              "g" ((USItype)(d)))
182 #define count_leading_zeros(count, x) \
183   __asm__ ("bsch/1 %1,%0"                                               \
184            : "=g" (count)                                               \
185            : "g" ((USItype)(x)),                                        \
186              "0" ((USItype)0))
187 #endif
188
189 #if defined (__hppa)
190 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
191   __asm__ ("add %4,%5,%1
192         addc %2,%3,%0"                                                  \
193            : "=r" ((USItype)(sh)),                                      \
194              "=&r" ((USItype)(sl))                                      \
195            : "%rM" ((USItype)(ah)),                                     \
196              "rM" ((USItype)(bh)),                                      \
197              "%rM" ((USItype)(al)),                                     \
198              "rM" ((USItype)(bl)))
199 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
200   __asm__ ("sub %5,%4,%1
201         subb %3,%2,%0"                                                  \
202            : "=r" ((USItype)(sh)),                                      \
203              "=&r" ((USItype)(sl))                                      \
204            : "rM" ((USItype)(ah)),                                      \
205              "rM" ((USItype)(bh)),                                      \
206              "rM" ((USItype)(al)),                                      \
207              "rM" ((USItype)(bl)))
208 #if defined (_PA_RISC1_1)
209 #define umul_ppmm(w1, w0, u, v) \
210   do {                                                                  \
211     union                                                               \
212       {                                                                 \
213         UDItype __f;                                                    \
214         struct {USItype __w1, __w0;} __w1w0;                            \
215       } __t;                                                            \
216     __asm__ ("xmpyu %1,%2,%0"                                           \
217              : "=x" (__t.__f)                                           \
218              : "x" ((USItype)(u)),                                      \
219                "x" ((USItype)(v)));                                     \
220     (w1) = __t.__w1w0.__w1;                                             \
221     (w0) = __t.__w1w0.__w0;                                             \
222      } while (0)
223 #define UMUL_TIME 8
224 #else
225 #define UMUL_TIME 30
226 #endif
227 #define UDIV_TIME 40
228 #endif
229
230 #if defined (__i386__) || defined (__i486__)
231 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
232   __asm__ ("addl %5,%1
233         adcl %3,%0"                                                     \
234            : "=r" ((USItype)(sh)),                                      \
235              "=&r" ((USItype)(sl))                                      \
236            : "%0" ((USItype)(ah)),                                      \
237              "g" ((USItype)(bh)),                                       \
238              "%1" ((USItype)(al)),                                      \
239              "g" ((USItype)(bl)))
240 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
241   __asm__ ("subl %5,%1
242         sbbl %3,%0"                                                     \
243            : "=r" ((USItype)(sh)),                                      \
244              "=&r" ((USItype)(sl))                                      \
245            : "0" ((USItype)(ah)),                                       \
246              "g" ((USItype)(bh)),                                       \
247              "1" ((USItype)(al)),                                       \
248              "g" ((USItype)(bl)))
249 #define umul_ppmm(w1, w0, u, v) \
250   __asm__ ("mull %3"                                                    \
251            : "=a" ((USItype)(w0)),                                      \
252              "=d" ((USItype)(w1))                                       \
253            : "%0" ((USItype)(u)),                                       \
254              "rm" ((USItype)(v)))
255 #define udiv_qrnnd(q, r, n1, n0, d) \
256   __asm__ ("divl %4"                                                    \
257            : "=a" ((USItype)(q)),                                       \
258              "=d" ((USItype)(r))                                        \
259            : "0" ((USItype)(n0)),                                       \
260              "1" ((USItype)(n1)),                                       \
261              "rm" ((USItype)(d)))
262 #define count_leading_zeros(count, x) \
263   do {                                                                  \
264     USItype __cbtmp;                                                    \
265     __asm__ ("bsrl %1,%0"                                               \
266              : "=r" (__cbtmp) : "rm" ((USItype)(x)));                   \
267     (count) = __cbtmp ^ 31;                                             \
268   } while (0)
269 #define UMUL_TIME 40
270 #define UDIV_TIME 40
271 #endif /* 80x86 */
272
273 #if defined (__i860__)
274 #if 0
275 /* Make sure these patterns really improve the code before
276    switching them on.  */
277 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
278   do {                                                                  \
279     union                                                               \
280       {                                                                 \
281         DItype __ll;                                                    \
282         struct {USItype __l, __h;} __i;                                 \
283       }  __a, __b, __s;                                                 \
284     __a.__i.__l = (al);                                                 \
285     __a.__i.__h = (ah);                                                 \
286     __b.__i.__l = (bl);                                                 \
287     __b.__i.__h = (bh);                                                 \
288     __asm__ ("fiadd.dd %1,%2,%0"                                        \
289              : "=f" (__s.__ll)                                          \
290              : "%f" (__a.__ll), "f" (__b.__ll));                        \
291     (sh) = __s.__i.__h;                                                 \
292     (sl) = __s.__i.__l;                                                 \
293     } while (0)
294 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
295   do {                                                                  \
296     union                                                               \
297       {                                                                 \
298         DItype __ll;                                                    \
299         struct {USItype __l, __h;} __i;                                 \
300       }  __a, __b, __s;                                                 \
301     __a.__i.__l = (al);                                                 \
302     __a.__i.__h = (ah);                                                 \
303     __b.__i.__l = (bl);                                                 \
304     __b.__i.__h = (bh);                                                 \
305     __asm__ ("fisub.dd %1,%2,%0"                                        \
306              : "=f" (__s.__ll)                                          \
307              : "%f" (__a.__ll), "f" (__b.__ll));                        \
308     (sh) = __s.__i.__h;                                                 \
309     (sl) = __s.__i.__l;                                                 \
310     } while (0)
311 #endif
312 #endif /* __i860__ */
313
314 #if defined (___IBMR2__) /* IBM RS6000 */
315 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
316   __asm__ ("a%I5 %1,%4,%5
317         ae %0,%2,%3"                                                    \
318            : "=r" ((USItype)(sh)),                                      \
319              "=&r" ((USItype)(sl))                                      \
320            : "%r" ((USItype)(ah)),                                      \
321              "r" ((USItype)(bh)),                                       \
322              "%r" ((USItype)(al)),                                      \
323              "rI" ((USItype)(bl)))
324 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
325   __asm__ ("sf%I4 %1,%5,%4
326         sfe %0,%3,%2"                                                   \
327            : "=r" ((USItype)(sh)),                                      \
328              "=&r" ((USItype)(sl))                                      \
329            : "r" ((USItype)(ah)),                                       \
330              "r" ((USItype)(bh)),                                       \
331              "rI" ((USItype)(al)),                                      \
332              "r" ((USItype)(bl)))
333 #define umul_ppmm(xh, xl, m0, m1) \
334   do {                                                                  \
335     USItype __m0 = (m0), __m1 = (m1);                                   \
336     __asm__ ("mul %0,%2,%3"                                             \
337              : "=r" ((USItype)(xh)),                                    \
338                "=q" ((USItype)(xl))                                     \
339              : "r" (__m0),                                              \
340                "r" (__m1));                                             \
341     (xh) += ((((SItype) __m0 >> 31) & __m1)                             \
342              + (((SItype) __m1 >> 31) & __m0));                         \
343   } while (0)
344 #define smul_ppmm(xh, xl, m0, m1) \
345   __asm__ ("mul %0,%2,%3"                                               \
346            : "=r" ((USItype)(xh)),                                      \
347              "=q" ((USItype)(xl))                                       \
348            : "r" ((USItype)(m0)),                                       \
349              "r" ((USItype)(m1)))
350 #define UMUL_TIME 8
351 #define sdiv_qrnnd(q, r, nh, nl, d) \
352   __asm__ ("div %0,%2,%4"                                               \
353            : "=r" ((USItype)(q)), "=q" ((USItype)(r))                   \
354            : "r" ((USItype)(nh)), "1" ((USItype)(nl)), "r" ((USItype)(d)))
355 #define UDIV_TIME 40
356 #define UDIV_NEEDS_NORMALIZATION 1
357 #define count_leading_zeros(count, x) \
358   __asm__ ("cntlz %0,%1"                                                \
359            : "=r" ((USItype)(count))                                    \
360            : "r" ((USItype)(x)))
361 #endif /* ___IBMR2__ */
362
363 #if defined (__mc68000__)
364 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
365   __asm__ ("add%.l %5,%1
366         addx%.l %3,%0"                                                  \
367            : "=d" ((USItype)(sh)),                                      \
368              "=&d" ((USItype)(sl))                                      \
369            : "%0" ((USItype)(ah)),                                      \
370              "d" ((USItype)(bh)),                                       \
371              "%1" ((USItype)(al)),                                      \
372              "g" ((USItype)(bl)))
373 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
374   __asm__ ("sub%.l %5,%1
375         subx%.l %3,%0"                                                  \
376            : "=d" ((USItype)(sh)),                                      \
377              "=&d" ((USItype)(sl))                                      \
378            : "0" ((USItype)(ah)),                                       \
379              "d" ((USItype)(bh)),                                       \
380              "1" ((USItype)(al)),                                       \
381              "g" ((USItype)(bl)))
382 #if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)
383 #define umul_ppmm(w1, w0, u, v) \
384   __asm__ ("mulu%.l %3,%1:%0"                                           \
385            : "=d" ((USItype)(w0)),                                      \
386              "=d" ((USItype)(w1))                                       \
387            : "%0" ((USItype)(u)),                                       \
388              "dmi" ((USItype)(v)))
389 #define UMUL_TIME 45
390 #define udiv_qrnnd(q, r, n1, n0, d) \
391   __asm__ ("divu%.l %4,%1:%0"                                           \
392            : "=d" ((USItype)(q)),                                       \
393              "=d" ((USItype)(r))                                        \
394            : "0" ((USItype)(n0)),                                       \
395              "1" ((USItype)(n1)),                                       \
396              "dmi" ((USItype)(d)))
397 #define UDIV_TIME 90
398 #define sdiv_qrnnd(q, r, n1, n0, d) \
399   __asm__ ("divs%.l %4,%1:%0"                                           \
400            : "=d" ((USItype)(q)),                                       \
401              "=d" ((USItype)(r))                                        \
402            : "0" ((USItype)(n0)),                                       \
403              "1" ((USItype)(n1)),                                       \
404              "dmi" ((USItype)(d)))
405 #define count_leading_zeros(count, x) \
406   __asm__ ("bfffo %1{%b2:%b2},%0"                                       \
407            : "=d" ((USItype)(count))                                    \
408            : "od" ((USItype)(x)), "n" (0))
409 #else /* not mc68020 */
410 #define umul_ppmm(xh, xl, a, b) \
411   __asm__ ("| Inlined umul_ppmm
412         movel   %2,d0
413         movel   %3,d1
414         movel   d0,d2
415         swap    d0
416         movel   d1,d3
417         swap    d1
418         movew   d2,d4
419         mulu    d3,d4
420         mulu    d1,d2
421         mulu    d0,d3
422         mulu    d0,d1
423         movel   d4,d0
424         eorw    d0,d0
425         swap    d0
426         addl    d0,d2
427         addl    d3,d2
428         jcc     1f
429         addl    #65536,d1
430 1:      swap    d2
431         moveq   #0,d0
432         movew   d2,d0
433         movew   d4,d2
434         movel   d2,%1
435         addl    d1,d0
436         movel   d0,%0"                                                  \
437            : "=g" ((USItype)(xh)),                                      \
438              "=g" ((USItype)(xl))                                       \
439            : "g" ((USItype)(a)),                                        \
440              "g" ((USItype)(b))                                         \
441            : "d0", "d1", "d2", "d3", "d4")
442 #define UMUL_TIME 100
443 #define UDIV_TIME 400
444 #endif /* not mc68020 */
445 #endif /* mc68000 */
446
447 #if defined (__m88000__)
448 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
449   __asm__ ("addu.co %1,%r4,%r5
450         addu.ci %0,%r2,%r3"                                             \
451            : "=r" ((USItype)(sh)),                                      \
452              "=&r" ((USItype)(sl))                                      \
453            : "%rJ" ((USItype)(ah)),                                     \
454              "rJ" ((USItype)(bh)),                                      \
455              "%rJ" ((USItype)(al)),                                     \
456              "rJ" ((USItype)(bl)))
457 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
458   __asm__ ("subu.co %1,%r4,%r5
459         subu.ci %0,%r2,%r3"                                             \
460            : "=r" ((USItype)(sh)),                                      \
461              "=&r" ((USItype)(sl))                                      \
462            : "rJ" ((USItype)(ah)),                                      \
463              "rJ" ((USItype)(bh)),                                      \
464              "rJ" ((USItype)(al)),                                      \
465              "rJ" ((USItype)(bl)))
466 #define UMUL_TIME 17
467 #define UDIV_TIME 150
468 #define count_leading_zeros(count, x) \
469   do {                                                                  \
470     USItype __cbtmp;                                                    \
471     __asm__ ("ff1 %0,%1"                                                \
472              : "=r" (__cbtmp)                                           \
473              : "r" ((USItype)(x)));                                     \
474     (count) = __cbtmp ^ 31;                                             \
475   } while (0)
476 #if defined (__mc88110__)
477 #define umul_ppmm(w1, w0, u, v) \
478   __asm__ ("mulu.d      r10,%2,%3
479         or      %0,r10,0
480         or      %1,r11,0"                                               \
481            : "=r" (w1),                                                 \
482              "=r" (w0)                                                  \
483            : "r" ((USItype)(u)),                                        \
484              "r" ((USItype)(v))                                         \
485            : "r10", "r11")
486 #define udiv_qrnnd(q, r, n1, n0, d) \
487   __asm__ ("or  r10,%2,0
488         or      r11,%3,0
489         divu.d  r10,r10,%4
490         mulu    %1,%4,r11
491         subu    %1,%3,%1
492         or      %0,r11,0"                                               \
493            : "=r" (q),                                                  \
494              "=&r" (r)                                                  \
495            : "r" ((USItype)(n1)),                                       \
496              "r" ((USItype)(n0)),                                       \
497              "r" ((USItype)(d))                                         \
498            : "r10", "r11")
499 #endif
500 #endif /* __m88000__ */
501
502 #if defined (__mips__)
503 #define umul_ppmm(w1, w0, u, v) \
504   __asm__ ("multu %2,%3
505         mflo %0
506         mfhi %1"                                                        \
507            : "=d" ((USItype)(w0)),                                      \
508              "=d" ((USItype)(w1))                                       \
509            : "d" ((USItype)(u)),                                        \
510              "d" ((USItype)(v)))
511 #define UMUL_TIME 5
512 #define UDIV_TIME 100
513 #endif /* __mips__ */
514
515 #if defined (__ns32000__)
516 #define __umulsidi3(u, v) \
517   ({UDItype __w;                                                        \
518     __asm__ ("meid %2,%0"                                               \
519              : "=g" (__w)                                               \
520              : "%0" ((USItype)(u)),                                     \
521                "g" ((USItype)(v)));                                     \
522     __w; })
523 #define div_qrnnd(q, r, n1, n0, d) \
524   __asm__ ("movd %2,r0
525         movd %3,r1
526         deid %4,r0
527         movd r1,%0
528         movd r0,%1"                                                     \
529            : "=g" ((USItype)(q)),                                       \
530              "=g" ((USItype)(r))                                        \
531            : "g" ((USItype)(n0)),                                       \
532              "g" ((USItype)(n1)),                                       \
533              "g" ((USItype)(d))                                         \
534            : "r0", "r1")
535 #endif /* __ns32000__ */
536
537 #if defined (__pyr__)
538 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
539   __asm__ ("addw        %5,%1
540         addwc   %3,%0"                                                  \
541            : "=r" ((USItype)(sh)),                                      \
542              "=&r" ((USItype)(sl))                                      \
543            : "%0" ((USItype)(ah)),                                      \
544              "g" ((USItype)(bh)),                                       \
545              "%1" ((USItype)(al)),                                      \
546              "g" ((USItype)(bl)))
547 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
548   __asm__ ("subw        %5,%1
549         subwb   %3,%0"                                                  \
550            : "=r" ((USItype)(sh)),                                      \
551              "=&r" ((USItype)(sl))                                      \
552            : "0" ((USItype)(ah)),                                       \
553              "g" ((USItype)(bh)),                                       \
554              "1" ((USItype)(al)),                                       \
555              "g" ((USItype)(bl)))
556 /* This insn doesn't work on ancient pyramids.  */
557 #define umul_ppmm(w1, w0, u, v) \
558   ({union {                                                             \
559         UDItype __ll;                                                   \
560         struct {USItype __h, __l;} __i;                                 \
561      } __xx;                                                            \
562   __xx.__i.__l = u;                                                     \
563   __asm__ ("uemul %3,%0"                                                \
564            : "=r" (__xx.__i.__h),                                       \
565              "=r" (__xx.__i.__l)                                        \
566            : "1" (__xx.__i.__l),                                        \
567              "g" ((UDItype)(v)));                                       \
568   (w1) = __xx.__i.__h;                                                  \
569   (w0) = __xx.__i.__l;})
570 #endif /* __pyr__ */
571
572 #if defined (__ibm032__) /* RT/ROMP */
573 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
574   __asm__ ("a %1,%5
575         ae %0,%3"                                                       \
576            : "=r" ((USItype)(sh)),                                      \
577              "=&r" ((USItype)(sl))                                      \
578            : "%0" ((USItype)(ah)),                                      \
579              "r" ((USItype)(bh)),                                       \
580              "%1" ((USItype)(al)),                                      \
581              "r" ((USItype)(bl)))
582 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
583   __asm__ ("s %1,%5
584         se %0,%3"                                                       \
585            : "=r" ((USItype)(sh)),                                      \
586              "=&r" ((USItype)(sl))                                      \
587            : "0" ((USItype)(ah)),                                       \
588              "r" ((USItype)(bh)),                                       \
589              "1" ((USItype)(al)),                                       \
590              "r" ((USItype)(bl)))
591 #define umul_ppmm(ph, pl, m0, m1) \
592   do {                                                                  \
593     USItype __m0 = (m0), __m1 = (m1);                                   \
594     __asm__ (                                                           \
595        "s       r2,r2
596         mts     r10,%2
597         m       r2,%3
598         m       r2,%3
599         m       r2,%3
600         m       r2,%3
601         m       r2,%3
602         m       r2,%3
603         m       r2,%3
604         m       r2,%3
605         m       r2,%3
606         m       r2,%3
607         m       r2,%3
608         m       r2,%3
609         m       r2,%3
610         m       r2,%3
611         m       r2,%3
612         m       r2,%3
613         cas     %0,r2,r0
614         mfs     r10,%1"                                                 \
615              : "=r" ((USItype)(ph)),                                    \
616                "=r" ((USItype)(pl))                                     \
617              : "%r" (__m0),                                             \
618                 "r" (__m1)                                              \
619              : "r2");                                                   \
620     (ph) += ((((SItype) __m0 >> 31) & __m1)                             \
621              + (((SItype) __m1 >> 31) & __m0));                         \
622   } while (0)
623 #define UMUL_TIME 20
624 #define UDIV_TIME 200
625 #define count_leading_zeros(count, x) \
626   do {                                                                  \
627     if ((x) >= 0x10000)                                                 \
628       __asm__ ("clz     %0,%1"                                          \
629                : "=r" ((USItype)(count))                                \
630                : "r" ((USItype)(x) >> 16));                             \
631     else                                                                \
632       {                                                                 \
633         __asm__ ("clz   %0,%1"                                          \
634                  : "=r" ((USItype)(count))                              \
635                  : "r" ((USItype)(x)));                                 \
636         (count) += 16;                                                  \
637       }                                                                 \
638   } while (0)
639 #endif
640
641 #if defined (__sparc__)
642 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
643   __asm__ ("addcc %4,%5,%1
644         addx %2,%3,%0"                                                  \
645            : "=r" ((USItype)(sh)),                                      \
646              "=&r" ((USItype)(sl))                                      \
647            : "%r" ((USItype)(ah)),                                      \
648              "rI" ((USItype)(bh)),                                      \
649              "%r" ((USItype)(al)),                                      \
650              "rI" ((USItype)(bl))                                       \
651            __CLOBBER_CC)
652 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
653   __asm__ ("subcc %4,%5,%1
654         subx %2,%3,%0"                                                  \
655            : "=r" ((USItype)(sh)),                                      \
656              "=&r" ((USItype)(sl))                                      \
657            : "r" ((USItype)(ah)),                                       \
658              "rI" ((USItype)(bh)),                                      \
659              "r" ((USItype)(al)),                                       \
660              "rI" ((USItype)(bl))                                       \
661            __CLOBBER_CC)
662 #if defined (__sparc_v8__)
663 #define umul_ppmm(w1, w0, u, v) \
664   __asm__ ("umul %2,%3,%1;rd %%y,%0"                                    \
665            : "=r" ((USItype)(w1)),                                      \
666              "=r" ((USItype)(w0))                                       \
667            : "r" ((USItype)(u)),                                        \
668              "r" ((USItype)(v)))
669 #define udiv_qrnnd(q, r, n1, n0, d) \
670   __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
671            : "=&r" ((USItype)(q)),                                      \
672              "=&r" ((USItype)(r))                                       \
673            : "r" ((USItype)(n1)),                                       \
674              "r" ((USItype)(n0)),                                       \
675              "r" ((USItype)(d)))
676 #else
677 #if defined (__sparclite__)
678 /* This has hardware multiply but not divide.  It also has two additional
679    instructions scan (ffs from high bit) and divscc.  */
680 #define umul_ppmm(w1, w0, u, v) \
681   __asm__ ("umul %2,%3,%1;rd %%y,%0"                                    \
682            : "=r" ((USItype)(w1)),                                      \
683              "=r" ((USItype)(w0))                                       \
684            : "r" ((USItype)(u)),                                        \
685              "r" ((USItype)(v)))
686 #define udiv_qrnnd(q, r, n1, n0, d) \
687   __asm__ ("! Inlined udiv_qrnnd
688         wr      %%g0,%2,%%y     ! Not a delayed write for sparclite
689         tst     %%g0
690         divscc  %3,%4,%%g1
691         divscc  %%g1,%4,%%g1
692         divscc  %%g1,%4,%%g1
693         divscc  %%g1,%4,%%g1
694         divscc  %%g1,%4,%%g1
695         divscc  %%g1,%4,%%g1
696         divscc  %%g1,%4,%%g1
697         divscc  %%g1,%4,%%g1
698         divscc  %%g1,%4,%%g1
699         divscc  %%g1,%4,%%g1
700         divscc  %%g1,%4,%%g1
701         divscc  %%g1,%4,%%g1
702         divscc  %%g1,%4,%%g1
703         divscc  %%g1,%4,%%g1
704         divscc  %%g1,%4,%%g1
705         divscc  %%g1,%4,%%g1
706         divscc  %%g1,%4,%%g1
707         divscc  %%g1,%4,%%g1
708         divscc  %%g1,%4,%%g1
709         divscc  %%g1,%4,%%g1
710         divscc  %%g1,%4,%%g1
711         divscc  %%g1,%4,%%g1
712         divscc  %%g1,%4,%%g1
713         divscc  %%g1,%4,%%g1
714         divscc  %%g1,%4,%%g1
715         divscc  %%g1,%4,%%g1
716         divscc  %%g1,%4,%%g1
717         divscc  %%g1,%4,%%g1
718         divscc  %%g1,%4,%%g1
719         divscc  %%g1,%4,%%g1
720         divscc  %%g1,%4,%%g1
721         divscc  %%g1,%4,%0
722         rd      %%y,%1
723         bl,a 1f
724         add     %1,%4,%1
725 1:      ! End of inline udiv_qrnnd"                                     \
726            : "=r" ((USItype)(q)),                                       \
727              "=r" ((USItype)(r))                                        \
728            : "r" ((USItype)(n1)),                                       \
729              "r" ((USItype)(n0)),                                       \
730              "rI" ((USItype)(d))                                        \
731            : "%g1" __AND_CLOBBER_CC)
732 #define UDIV_TIME 37
733 #define count_leading_zeros(count, x) \
734   __asm__ ("scan %1,0,%0"                                               \
735            : "=r" ((USItype)(x))                                        \
736            : "r" ((USItype)(count)))
737 #else
738 /* SPARC without integer multiplication and divide instructions.
739    (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
740 #define umul_ppmm(w1, w0, u, v) \
741   __asm__ ("! Inlined umul_ppmm
742         wr      %%g0,%2,%%y     ! SPARC has 0-3 delay insn after a wr
743         sra     %3,31,%%g2      ! Don't move this insn
744         and     %2,%%g2,%%g2    ! Don't move this insn
745         andcc   %%g0,0,%%g1     ! Don't move this insn
746         mulscc  %%g1,%3,%%g1
747         mulscc  %%g1,%3,%%g1
748         mulscc  %%g1,%3,%%g1
749         mulscc  %%g1,%3,%%g1
750         mulscc  %%g1,%3,%%g1
751         mulscc  %%g1,%3,%%g1
752         mulscc  %%g1,%3,%%g1
753         mulscc  %%g1,%3,%%g1
754         mulscc  %%g1,%3,%%g1
755         mulscc  %%g1,%3,%%g1
756         mulscc  %%g1,%3,%%g1
757         mulscc  %%g1,%3,%%g1
758         mulscc  %%g1,%3,%%g1
759         mulscc  %%g1,%3,%%g1
760         mulscc  %%g1,%3,%%g1
761         mulscc  %%g1,%3,%%g1
762         mulscc  %%g1,%3,%%g1
763         mulscc  %%g1,%3,%%g1
764         mulscc  %%g1,%3,%%g1
765         mulscc  %%g1,%3,%%g1
766         mulscc  %%g1,%3,%%g1
767         mulscc  %%g1,%3,%%g1
768         mulscc  %%g1,%3,%%g1
769         mulscc  %%g1,%3,%%g1
770         mulscc  %%g1,%3,%%g1
771         mulscc  %%g1,%3,%%g1
772         mulscc  %%g1,%3,%%g1
773         mulscc  %%g1,%3,%%g1
774         mulscc  %%g1,%3,%%g1
775         mulscc  %%g1,%3,%%g1
776         mulscc  %%g1,%3,%%g1
777         mulscc  %%g1,%3,%%g1
778         mulscc  %%g1,0,%%g1
779         add     %%g1,%%g2,%0
780         rd      %%y,%1"                                                 \
781            : "=r" ((USItype)(w1)),                                      \
782              "=r" ((USItype)(w0))                                       \
783            : "%rI" ((USItype)(u)),                                      \
784              "r" ((USItype)(v))                                         \
785            : "%g1", "%g2" __AND_CLOBBER_CC)
786 #define UMUL_TIME 39            /* 39 instructions */
787 /* It's quite necessary to add this much assembler for the sparc.
788    The default udiv_qrnnd (in C) is more than 10 times slower!  */
789 #define udiv_qrnnd(q, r, n1, n0, d) \
790   __asm__ ("! Inlined udiv_qrnnd
791         mov     32,%%g1
792         subcc   %1,%2,%%g0
793 1:      bcs     5f
794          addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
795         sub     %1,%2,%1        ! this kills msb of n
796         addx    %1,%1,%1        ! so this can't give carry
797         subcc   %%g1,1,%%g1
798 2:      bne     1b
799          subcc  %1,%2,%%g0
800         bcs     3f
801          addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
802         b       3f
803          sub    %1,%2,%1        ! this kills msb of n
804 4:      sub     %1,%2,%1
805 5:      addxcc  %1,%1,%1
806         bcc     2b
807          subcc  %%g1,1,%%g1
808 ! Got carry from n.  Subtract next step to cancel this carry.
809         bne     4b
810          addcc  %0,%0,%0        ! shift n1n0 and a 0-bit in lsb
811         sub     %1,%2,%1
812 3:      xnor    %0,0,%0
813         ! End of inline udiv_qrnnd"                                     \
814            : "=&r" ((USItype)(q)),                                      \
815              "=&r" ((USItype)(r))                                       \
816            : "r" ((USItype)(d)),                                        \
817              "1" ((USItype)(n1)),                                       \
818              "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC)
819 #define UDIV_TIME (3+7*32)      /* 7 instructions/iteration. 32 iterations. */
820 #endif /* __sparclite__ */
821 #endif /* __sparc_v8__ */
822 #endif /* __sparc__ */
823
824 #if defined (__vax__)
825 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
826   __asm__ ("addl2 %5,%1
827         adwc %3,%0"                                                     \
828            : "=g" ((USItype)(sh)),                                      \
829              "=&g" ((USItype)(sl))                                      \
830            : "%0" ((USItype)(ah)),                                      \
831              "g" ((USItype)(bh)),                                       \
832              "%1" ((USItype)(al)),                                      \
833              "g" ((USItype)(bl)))
834 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
835   __asm__ ("subl2 %5,%1
836         sbwc %3,%0"                                                     \
837            : "=g" ((USItype)(sh)),                                      \
838              "=&g" ((USItype)(sl))                                      \
839            : "0" ((USItype)(ah)),                                       \
840              "g" ((USItype)(bh)),                                       \
841              "1" ((USItype)(al)),                                       \
842              "g" ((USItype)(bl)))
843 #define umul_ppmm(xh, xl, m0, m1) \
844   do {                                                                  \
845     union {                                                             \
846         UDItype __ll;                                                   \
847         struct {USItype __l, __h;} __i;                                 \
848       } __xx;                                                           \
849     USItype __m0 = (m0), __m1 = (m1);                                   \
850     __asm__ ("emul %1,%2,$0,%0"                                         \
851              : "=r" (__xx.__ll)                                         \
852              : "g" (__m0),                                              \
853                "g" (__m1));                                             \
854     (xh) = __xx.__i.__h;                                                \
855     (xl) = __xx.__i.__l;                                                \
856     (xh) += ((((SItype) __m0 >> 31) & __m1)                             \
857              + (((SItype) __m1 >> 31) & __m0));                         \
858   } while (0)
859 #endif /* __vax__ */
860
861 #endif /* __GNUC__ */
862
863 /* If this machine has no inline assembler, use C macros.  */
864
865 #if !defined (add_ssaaaa)
866 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
867   do {                                                                  \
868     USItype __x;                                                        \
869     __x = (al) + (bl);                                                  \
870     (sh) = (ah) + (bh) + (__x < (al));                                  \
871     (sl) = __x;                                                         \
872   } while (0)
873 #endif
874
875 #if !defined (sub_ddmmss)
876 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
877   do {                                                                  \
878     USItype __x;                                                        \
879     __x = (al) - (bl);                                                  \
880     (sh) = (ah) - (bh) - (__x > (al));                                  \
881     (sl) = __x;                                                         \
882   } while (0)
883 #endif
884
885 #if !defined (umul_ppmm)
886 #define umul_ppmm(w1, w0, u, v)                                         \
887   do {                                                                  \
888     USItype __x0, __x1, __x2, __x3;                                     \
889     USItype __ul, __vl, __uh, __vh;                                     \
890                                                                         \
891     __ul = __ll_lowpart (u);                                            \
892     __uh = __ll_highpart (u);                                           \
893     __vl = __ll_lowpart (v);                                            \
894     __vh = __ll_highpart (v);                                           \
895                                                                         \
896     __x0 = (USItype) __ul * __vl;                                       \
897     __x1 = (USItype) __ul * __vh;                                       \
898     __x2 = (USItype) __uh * __vl;                                       \
899     __x3 = (USItype) __uh * __vh;                                       \
900                                                                         \
901     __x1 += __ll_highpart (__x0);/* this can't give carry */            \
902     __x1 += __x2;               /* but this indeed can */               \
903     if (__x1 < __x2)            /* did we get it? */                    \
904       __x3 += __ll_B;           /* yes, add it in the proper pos. */    \
905                                                                         \
906     (w1) = __x3 + __ll_highpart (__x1);                                 \
907     (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);          \
908   } while (0)
909 #endif
910
911 #if !defined (__umulsidi3)
912 #define __umulsidi3(u, v) \
913   ({DIunion __w;                                                        \
914     umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
915     __w.ll; })
916 #endif
917
918 /* Define this unconditionally, so it can be used for debugging.  */
919 #define __udiv_qrnnd_c(q, r, n1, n0, d) \
920   do {                                                                  \
921     USItype __d1, __d0, __q1, __q0;                                     \
922     USItype __r1, __r0, __m;                                            \
923     __d1 = __ll_highpart (d);                                           \
924     __d0 = __ll_lowpart (d);                                            \
925                                                                         \
926     __r1 = (n1) % __d1;                                                 \
927     __q1 = (n1) / __d1;                                                 \
928     __m = (USItype) __q1 * __d0;                                        \
929     __r1 = __r1 * __ll_B | __ll_highpart (n0);                          \
930     if (__r1 < __m)                                                     \
931       {                                                                 \
932         __q1--, __r1 += (d);                                            \
933         if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
934           if (__r1 < __m)                                               \
935             __q1--, __r1 += (d);                                        \
936       }                                                                 \
937     __r1 -= __m;                                                        \
938                                                                         \
939     __r0 = __r1 % __d1;                                                 \
940     __q0 = __r1 / __d1;                                                 \
941     __m = (USItype) __q0 * __d0;                                        \
942     __r0 = __r0 * __ll_B | __ll_lowpart (n0);                           \
943     if (__r0 < __m)                                                     \
944       {                                                                 \
945         __q0--, __r0 += (d);                                            \
946         if (__r0 >= (d))                                                \
947           if (__r0 < __m)                                               \
948             __q0--, __r0 += (d);                                        \
949       }                                                                 \
950     __r0 -= __m;                                                        \
951                                                                         \
952     (q) = (USItype) __q1 * __ll_B | __q0;                               \
953     (r) = __r0;                                                         \
954   } while (0)
955
956 /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
957    __udiv_w_sdiv (defined in libgcc or elsewhere).  */
958 #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
959 #define udiv_qrnnd(q, r, nh, nl, d) \
960   do {                                                                  \
961     USItype __r;                                                        \
962     (q) = __udiv_w_sdiv (&__r, nh, nl, d);                              \
963     (r) = __r;                                                          \
964   } while (0)
965 #endif
966
967 /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
968 #if !defined (udiv_qrnnd)
969 #define UDIV_NEEDS_NORMALIZATION 1
970 #define udiv_qrnnd __udiv_qrnnd_c
971 #endif
972
973 #if !defined (count_leading_zeros)
974 extern const UQItype __clz_tab[];
975 #define count_leading_zeros(count, x) \
976   do {                                                                  \
977     USItype __xr = (x);                                                 \
978     USItype __a;                                                        \
979                                                                         \
980     if (SI_TYPE_SIZE <= 32)                                             \
981       {                                                                 \
982         __a = __xr < (1<<2*__BITS4)                                     \
983           ? (__xr < (1<<__BITS4) ? 0 : __BITS4)                         \
984           : (__xr < (1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);           \
985       }                                                                 \
986     else                                                                \
987       {                                                                 \
988         for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)         \
989           if (((__xr >> __a) & 0xff) != 0)                              \
990             break;                                                      \
991       }                                                                 \
992                                                                         \
993     (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);            \
994   } while (0)
995 #endif
996
997 #ifndef UDIV_NEEDS_NORMALIZATION
998 #define UDIV_NEEDS_NORMALIZATION 0
999 #endif