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