|
|
1.1 root 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 sdiv_qrnnd(q, r, n1, n0, d) \
267: __asm__ ("idivl %4" \
268: : "=a" ((USItype)(q)), \
269: "=d" ((USItype)(r)) \
270: : "0" ((USItype)(n0)), \
271: "1" ((USItype)(n1)), \
272: "rm" ((USItype)(d)))
273: #define count_leading_zeros(count, x) \
274: do { \
275: USItype __cbtmp; \
276: __asm__ ("bsrl %1,%0" \
277: : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
278: (count) = __cbtmp ^ 31; \
279: } while (0)
280: #define UMUL_TIME 40
281: #define UDIV_TIME 40
282: #endif /* 80x86 */
283:
284: #if defined (__i860__)
285: #if 0
286: /* Make sure these patterns really improve the code before
287: switching them on. */
288: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
289: do { \
290: union \
291: { \
292: DItype __ll; \
293: struct {USItype __l, __h;} __i; \
294: } __a, __b, __s; \
295: __a.__i.__l = (al); \
296: __a.__i.__h = (ah); \
297: __b.__i.__l = (bl); \
298: __b.__i.__h = (bh); \
299: __asm__ ("fiadd.dd %1,%2,%0" \
300: : "=f" (__s.__ll) \
301: : "%f" (__a.__ll), "f" (__b.__ll)); \
302: (sh) = __s.__i.__h; \
303: (sl) = __s.__i.__l; \
304: } while (0)
305: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
306: do { \
307: union \
308: { \
309: DItype __ll; \
310: struct {USItype __l, __h;} __i; \
311: } __a, __b, __s; \
312: __a.__i.__l = (al); \
313: __a.__i.__h = (ah); \
314: __b.__i.__l = (bl); \
315: __b.__i.__h = (bh); \
316: __asm__ ("fisub.dd %1,%2,%0" \
317: : "=f" (__s.__ll) \
318: : "%f" (__a.__ll), "f" (__b.__ll)); \
319: (sh) = __s.__i.__h; \
320: (sl) = __s.__i.__l; \
321: } while (0)
322: #endif
323: #endif /* __i860__ */
324:
325: #if defined (___IBMR2__) /* IBM RS6000 */
326: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
327: __asm__ ("a%I5 %1,%4,%5
328: ae %0,%2,%3" \
329: : "=r" ((USItype)(sh)), \
330: "=&r" ((USItype)(sl)) \
331: : "%r" ((USItype)(ah)), \
332: "r" ((USItype)(bh)), \
333: "%r" ((USItype)(al)), \
334: "rI" ((USItype)(bl)))
335: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
336: __asm__ ("sf%I4 %1,%5,%4
337: sfe %0,%3,%2" \
338: : "=r" ((USItype)(sh)), \
339: "=&r" ((USItype)(sl)) \
340: : "r" ((USItype)(ah)), \
341: "r" ((USItype)(bh)), \
342: "rI" ((USItype)(al)), \
343: "r" ((USItype)(bl)))
344: #define umul_ppmm(xh, xl, m0, m1) \
345: do { \
346: USItype __m0 = (m0), __m1 = (m1); \
347: __asm__ ("mul %0,%2,%3" \
348: : "=r" ((USItype)(xh)), \
349: "=q" ((USItype)(xl)) \
350: : "r" (__m0), \
351: "r" (__m1)); \
352: (xh) += ((((SItype) __m0 >> 31) & __m1) \
353: + (((SItype) __m1 >> 31) & __m0)); \
354: } while (0)
355: #define smul_ppmm(xh, xl, m0, m1) \
356: __asm__ ("mul %0,%2,%3" \
357: : "=r" ((USItype)(xh)), \
358: "=q" ((USItype)(xl)) \
359: : "r" ((USItype)(m0)), \
360: "r" ((USItype)(m1)))
361: #define UMUL_TIME 8
362: #define sdiv_qrnnd(q, r, nh, nl, d) \
363: __asm__ ("div %0,%2,%4" \
364: : "=r" ((USItype)(q)), "=q" ((USItype)(r)) \
365: : "r" ((USItype)(nh)), "1" ((USItype)(nl)), "r" ((USItype)(d)))
366: #define UDIV_TIME 40
367: #define UDIV_NEEDS_NORMALIZATION 1
368: #define count_leading_zeros(count, x) \
369: __asm__ ("cntlz %0,%1" \
370: : "=r" ((USItype)(count)) \
371: : "r" ((USItype)(x)))
372: #endif /* ___IBMR2__ */
373:
374: #if defined (__mc68000__)
375: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
376: __asm__ ("add%.l %5,%1
377: addx%.l %3,%0" \
378: : "=d" ((USItype)(sh)), \
379: "=&d" ((USItype)(sl)) \
380: : "%0" ((USItype)(ah)), \
381: "d" ((USItype)(bh)), \
382: "%1" ((USItype)(al)), \
383: "g" ((USItype)(bl)))
384: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
385: __asm__ ("sub%.l %5,%1
386: subx%.l %3,%0" \
387: : "=d" ((USItype)(sh)), \
388: "=&d" ((USItype)(sl)) \
389: : "0" ((USItype)(ah)), \
390: "d" ((USItype)(bh)), \
391: "1" ((USItype)(al)), \
392: "g" ((USItype)(bl)))
393: #if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)
394: #define umul_ppmm(w1, w0, u, v) \
395: __asm__ ("mulu%.l %3,%1:%0" \
396: : "=d" ((USItype)(w0)), \
397: "=d" ((USItype)(w1)) \
398: : "%0" ((USItype)(u)), \
399: "dmi" ((USItype)(v)))
400: #define UMUL_TIME 45
401: #define udiv_qrnnd(q, r, n1, n0, d) \
402: __asm__ ("divu%.l %4,%1:%0" \
403: : "=d" ((USItype)(q)), \
404: "=d" ((USItype)(r)) \
405: : "0" ((USItype)(n0)), \
406: "1" ((USItype)(n1)), \
407: "dmi" ((USItype)(d)))
408: #define UDIV_TIME 90
409: #define sdiv_qrnnd(q, r, n1, n0, d) \
410: __asm__ ("divs%.l %4,%1:%0" \
411: : "=d" ((USItype)(q)), \
412: "=d" ((USItype)(r)) \
413: : "0" ((USItype)(n0)), \
414: "1" ((USItype)(n1)), \
415: "dmi" ((USItype)(d)))
416: #define count_leading_zeros(count, x) \
417: __asm__ ("bfffo %1{%b2:%b2},%0" \
418: : "=d" ((USItype)(count)) \
419: : "od" ((USItype)(x)), "n" (0))
420: #else /* not mc68020 */
421: /* %/ inserts REGISTER_PREFIX. */
422: #define umul_ppmm(xh, xl, a, b) \
423: __asm__ ("| Inlined umul_ppmm
424: movel %2,%/d0
425: movel %3,%/d1
426: movel %/d0,%/d2
427: swap %/d0
428: movel %/d1,%/d3
429: swap %/d1
430: movew %/d2,%/d4
431: mulu %/d3,%/d4
432: mulu %/d1,%/d2
433: mulu %/d0,%/d3
434: mulu %/d0,%/d1
435: movel %/d4,%/d0
436: eorw %/d0,%/d0
437: swap %/d0
438: addl %/d0,%/d2
439: addl %/d3,%/d2
440: jcc 1f
441: addl #65536,%/d1
442: 1: swap %/d2
443: moveq #0,%/d0
444: movew %/d2,%/d0
445: movew %/d4,%/d2
446: movel %/d2,%1
447: addl %/d1,%/d0
448: movel %/d0,%0" \
449: : "=g" ((USItype)(xh)), \
450: "=g" ((USItype)(xl)) \
451: : "g" ((USItype)(a)), \
452: "g" ((USItype)(b)) \
453: : "d0", "d1", "d2", "d3", "d4")
454: #define UMUL_TIME 100
455: #define UDIV_TIME 400
456: #endif /* not mc68020 */
457: #endif /* mc68000 */
458:
459: #if defined (__m88000__)
460: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
461: __asm__ ("addu.co %1,%r4,%r5
462: addu.ci %0,%r2,%r3" \
463: : "=r" ((USItype)(sh)), \
464: "=&r" ((USItype)(sl)) \
465: : "%rJ" ((USItype)(ah)), \
466: "rJ" ((USItype)(bh)), \
467: "%rJ" ((USItype)(al)), \
468: "rJ" ((USItype)(bl)))
469: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
470: __asm__ ("subu.co %1,%r4,%r5
471: subu.ci %0,%r2,%r3" \
472: : "=r" ((USItype)(sh)), \
473: "=&r" ((USItype)(sl)) \
474: : "rJ" ((USItype)(ah)), \
475: "rJ" ((USItype)(bh)), \
476: "rJ" ((USItype)(al)), \
477: "rJ" ((USItype)(bl)))
478: #define UMUL_TIME 17
479: #define UDIV_TIME 150
480: #define count_leading_zeros(count, x) \
481: do { \
482: USItype __cbtmp; \
483: __asm__ ("ff1 %0,%1" \
484: : "=r" (__cbtmp) \
485: : "r" ((USItype)(x))); \
486: (count) = __cbtmp ^ 31; \
487: } while (0)
488: #if defined (__mc88110__)
489: #define umul_ppmm(w1, w0, u, v) \
490: __asm__ ("mulu.d r10,%2,%3
491: or %0,r10,0
492: or %1,r11,0" \
493: : "=r" (w1), \
494: "=r" (w0) \
495: : "r" ((USItype)(u)), \
496: "r" ((USItype)(v)) \
497: : "r10", "r11")
498: #define udiv_qrnnd(q, r, n1, n0, d) \
499: __asm__ ("or r10,%2,0
500: or r11,%3,0
501: divu.d r10,r10,%4
502: mulu %1,%4,r11
503: subu %1,%3,%1
504: or %0,r11,0" \
505: : "=r" (q), \
506: "=&r" (r) \
507: : "r" ((USItype)(n1)), \
508: "r" ((USItype)(n0)), \
509: "r" ((USItype)(d)) \
510: : "r10", "r11")
511: #endif
512: #endif /* __m88000__ */
513:
514: #if defined (__mips__)
515: #define umul_ppmm(w1, w0, u, v) \
516: __asm__ ("multu %2,%3
517: mflo %0
518: mfhi %1" \
519: : "=d" ((USItype)(w0)), \
520: "=d" ((USItype)(w1)) \
521: : "d" ((USItype)(u)), \
522: "d" ((USItype)(v)))
523: #define UMUL_TIME 5
524: #define UDIV_TIME 100
525: #endif /* __mips__ */
526:
527: #if defined (__ns32000__)
528: #define __umulsidi3(u, v) \
529: ({UDItype __w; \
530: __asm__ ("meid %2,%0" \
531: : "=g" (__w) \
532: : "%0" ((USItype)(u)), \
533: "g" ((USItype)(v))); \
534: __w; })
535: #define div_qrnnd(q, r, n1, n0, d) \
536: __asm__ ("movd %2,r0
537: movd %3,r1
538: deid %4,r0
539: movd r1,%0
540: movd r0,%1" \
541: : "=g" ((USItype)(q)), \
542: "=g" ((USItype)(r)) \
543: : "g" ((USItype)(n0)), \
544: "g" ((USItype)(n1)), \
545: "g" ((USItype)(d)) \
546: : "r0", "r1")
547: #endif /* __ns32000__ */
548:
549: #if defined (__pyr__)
550: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
551: __asm__ ("addw %5,%1
552: addwc %3,%0" \
553: : "=r" ((USItype)(sh)), \
554: "=&r" ((USItype)(sl)) \
555: : "%0" ((USItype)(ah)), \
556: "g" ((USItype)(bh)), \
557: "%1" ((USItype)(al)), \
558: "g" ((USItype)(bl)))
559: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
560: __asm__ ("subw %5,%1
561: subwb %3,%0" \
562: : "=r" ((USItype)(sh)), \
563: "=&r" ((USItype)(sl)) \
564: : "0" ((USItype)(ah)), \
565: "g" ((USItype)(bh)), \
566: "1" ((USItype)(al)), \
567: "g" ((USItype)(bl)))
568: /* This insn doesn't work on ancient pyramids. */
569: #define umul_ppmm(w1, w0, u, v) \
570: ({union { \
571: UDItype __ll; \
572: struct {USItype __h, __l;} __i; \
573: } __xx; \
574: __xx.__i.__l = u; \
575: __asm__ ("uemul %3,%0" \
576: : "=r" (__xx.__i.__h), \
577: "=r" (__xx.__i.__l) \
578: : "1" (__xx.__i.__l), \
579: "g" ((UDItype)(v))); \
580: (w1) = __xx.__i.__h; \
581: (w0) = __xx.__i.__l;})
582: #endif /* __pyr__ */
583:
584: #if defined (__ibm032__) /* RT/ROMP */
585: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
586: __asm__ ("a %1,%5
587: ae %0,%3" \
588: : "=r" ((USItype)(sh)), \
589: "=&r" ((USItype)(sl)) \
590: : "%0" ((USItype)(ah)), \
591: "r" ((USItype)(bh)), \
592: "%1" ((USItype)(al)), \
593: "r" ((USItype)(bl)))
594: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
595: __asm__ ("s %1,%5
596: se %0,%3" \
597: : "=r" ((USItype)(sh)), \
598: "=&r" ((USItype)(sl)) \
599: : "0" ((USItype)(ah)), \
600: "r" ((USItype)(bh)), \
601: "1" ((USItype)(al)), \
602: "r" ((USItype)(bl)))
603: #define umul_ppmm(ph, pl, m0, m1) \
604: do { \
605: USItype __m0 = (m0), __m1 = (m1); \
606: __asm__ ( \
607: "s r2,r2
608: mts r10,%2
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: m r2,%3
619: m r2,%3
620: m r2,%3
621: m r2,%3
622: m r2,%3
623: m r2,%3
624: m r2,%3
625: cas %0,r2,r0
626: mfs r10,%1" \
627: : "=r" ((USItype)(ph)), \
628: "=r" ((USItype)(pl)) \
629: : "%r" (__m0), \
630: "r" (__m1) \
631: : "r2"); \
632: (ph) += ((((SItype) __m0 >> 31) & __m1) \
633: + (((SItype) __m1 >> 31) & __m0)); \
634: } while (0)
635: #define UMUL_TIME 20
636: #define UDIV_TIME 200
637: #define count_leading_zeros(count, x) \
638: do { \
639: if ((x) >= 0x10000) \
640: __asm__ ("clz %0,%1" \
641: : "=r" ((USItype)(count)) \
642: : "r" ((USItype)(x) >> 16)); \
643: else \
644: { \
645: __asm__ ("clz %0,%1" \
646: : "=r" ((USItype)(count)) \
647: : "r" ((USItype)(x))); \
648: (count) += 16; \
649: } \
650: } while (0)
651: #endif
652:
653: #if defined (__sparc__)
654: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
655: __asm__ ("addcc %4,%5,%1
656: addx %2,%3,%0" \
657: : "=r" ((USItype)(sh)), \
658: "=&r" ((USItype)(sl)) \
659: : "%r" ((USItype)(ah)), \
660: "rI" ((USItype)(bh)), \
661: "%r" ((USItype)(al)), \
662: "rI" ((USItype)(bl)) \
663: __CLOBBER_CC)
664: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
665: __asm__ ("subcc %4,%5,%1
666: subx %2,%3,%0" \
667: : "=r" ((USItype)(sh)), \
668: "=&r" ((USItype)(sl)) \
669: : "r" ((USItype)(ah)), \
670: "rI" ((USItype)(bh)), \
671: "r" ((USItype)(al)), \
672: "rI" ((USItype)(bl)) \
673: __CLOBBER_CC)
674: #if defined (__sparc_v8__)
675: #define umul_ppmm(w1, w0, u, v) \
676: __asm__ ("umul %2,%3,%1;rd %%y,%0" \
677: : "=r" ((USItype)(w1)), \
678: "=r" ((USItype)(w0)) \
679: : "r" ((USItype)(u)), \
680: "r" ((USItype)(v)))
681: #define udiv_qrnnd(q, r, n1, n0, d) \
682: __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
683: : "=&r" ((USItype)(q)), \
684: "=&r" ((USItype)(r)) \
685: : "r" ((USItype)(n1)), \
686: "r" ((USItype)(n0)), \
687: "r" ((USItype)(d)))
688: #else
689: #if defined (__sparclite__)
690: /* This has hardware multiply but not divide. It also has two additional
691: instructions scan (ffs from high bit) and divscc. */
692: #define umul_ppmm(w1, w0, u, v) \
693: __asm__ ("umul %2,%3,%1;rd %%y,%0" \
694: : "=r" ((USItype)(w1)), \
695: "=r" ((USItype)(w0)) \
696: : "r" ((USItype)(u)), \
697: "r" ((USItype)(v)))
698: #define udiv_qrnnd(q, r, n1, n0, d) \
699: __asm__ ("! Inlined udiv_qrnnd
700: wr %%g0,%2,%%y ! Not a delayed write for sparclite
701: tst %%g0
702: divscc %3,%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,%%g1
727: divscc %%g1,%4,%%g1
728: divscc %%g1,%4,%%g1
729: divscc %%g1,%4,%%g1
730: divscc %%g1,%4,%%g1
731: divscc %%g1,%4,%%g1
732: divscc %%g1,%4,%%g1
733: divscc %%g1,%4,%0
734: rd %%y,%1
735: bl,a 1f
736: add %1,%4,%1
737: 1: ! End of inline udiv_qrnnd" \
738: : "=r" ((USItype)(q)), \
739: "=r" ((USItype)(r)) \
740: : "r" ((USItype)(n1)), \
741: "r" ((USItype)(n0)), \
742: "rI" ((USItype)(d)) \
743: : "%g1" __AND_CLOBBER_CC)
744: #define UDIV_TIME 37
745: #define count_leading_zeros(count, x) \
746: __asm__ ("scan %1,0,%0" \
747: : "=r" ((USItype)(x)) \
748: : "r" ((USItype)(count)))
749: #else
750: /* SPARC without integer multiplication and divide instructions.
751: (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
752: #define umul_ppmm(w1, w0, u, v) \
753: __asm__ ("! Inlined umul_ppmm
754: wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr
755: sra %3,31,%%g2 ! Don't move this insn
756: and %2,%%g2,%%g2 ! Don't move this insn
757: andcc %%g0,0,%%g1 ! Don't move this insn
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,%3,%%g1
784: mulscc %%g1,%3,%%g1
785: mulscc %%g1,%3,%%g1
786: mulscc %%g1,%3,%%g1
787: mulscc %%g1,%3,%%g1
788: mulscc %%g1,%3,%%g1
789: mulscc %%g1,%3,%%g1
790: mulscc %%g1,0,%%g1
791: add %%g1,%%g2,%0
792: rd %%y,%1" \
793: : "=r" ((USItype)(w1)), \
794: "=r" ((USItype)(w0)) \
795: : "%rI" ((USItype)(u)), \
796: "r" ((USItype)(v)) \
797: : "%g1", "%g2" __AND_CLOBBER_CC)
798: #define UMUL_TIME 39 /* 39 instructions */
799: /* It's quite necessary to add this much assembler for the sparc.
800: The default udiv_qrnnd (in C) is more than 10 times slower! */
801: #define udiv_qrnnd(q, r, n1, n0, d) \
802: __asm__ ("! Inlined udiv_qrnnd
803: mov 32,%%g1
804: subcc %1,%2,%%g0
805: 1: bcs 5f
806: addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
807: sub %1,%2,%1 ! this kills msb of n
808: addx %1,%1,%1 ! so this can't give carry
809: subcc %%g1,1,%%g1
810: 2: bne 1b
811: subcc %1,%2,%%g0
812: bcs 3f
813: addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
814: b 3f
815: sub %1,%2,%1 ! this kills msb of n
816: 4: sub %1,%2,%1
817: 5: addxcc %1,%1,%1
818: bcc 2b
819: subcc %%g1,1,%%g1
820: ! Got carry from n. Subtract next step to cancel this carry.
821: bne 4b
822: addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb
823: sub %1,%2,%1
824: 3: xnor %0,0,%0
825: ! End of inline udiv_qrnnd" \
826: : "=&r" ((USItype)(q)), \
827: "=&r" ((USItype)(r)) \
828: : "r" ((USItype)(d)), \
829: "1" ((USItype)(n1)), \
830: "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC)
831: #define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */
832: #endif /* __sparclite__ */
833: #endif /* __sparc_v8__ */
834: #endif /* __sparc__ */
835:
836: #if defined (__vax__)
837: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
838: __asm__ ("addl2 %5,%1
839: adwc %3,%0" \
840: : "=g" ((USItype)(sh)), \
841: "=&g" ((USItype)(sl)) \
842: : "%0" ((USItype)(ah)), \
843: "g" ((USItype)(bh)), \
844: "%1" ((USItype)(al)), \
845: "g" ((USItype)(bl)))
846: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
847: __asm__ ("subl2 %5,%1
848: sbwc %3,%0" \
849: : "=g" ((USItype)(sh)), \
850: "=&g" ((USItype)(sl)) \
851: : "0" ((USItype)(ah)), \
852: "g" ((USItype)(bh)), \
853: "1" ((USItype)(al)), \
854: "g" ((USItype)(bl)))
855: #define umul_ppmm(xh, xl, m0, m1) \
856: do { \
857: union { \
858: UDItype __ll; \
859: struct {USItype __l, __h;} __i; \
860: } __xx; \
861: USItype __m0 = (m0), __m1 = (m1); \
862: __asm__ ("emul %1,%2,$0,%0" \
863: : "=r" (__xx.__ll) \
864: : "g" (__m0), \
865: "g" (__m1)); \
866: (xh) = __xx.__i.__h; \
867: (xl) = __xx.__i.__l; \
868: (xh) += ((((SItype) __m0 >> 31) & __m1) \
869: + (((SItype) __m1 >> 31) & __m0)); \
870: } while (0)
871: #endif /* __vax__ */
872:
873: #endif /* __GNUC__ */
874:
875: /* If this machine has no inline assembler, use C macros. */
876:
877: #if !defined (add_ssaaaa)
878: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
879: do { \
880: USItype __x; \
881: __x = (al) + (bl); \
882: (sh) = (ah) + (bh) + (__x < (al)); \
883: (sl) = __x; \
884: } while (0)
885: #endif
886:
887: #if !defined (sub_ddmmss)
888: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
889: do { \
890: USItype __x; \
891: __x = (al) - (bl); \
892: (sh) = (ah) - (bh) - (__x > (al)); \
893: (sl) = __x; \
894: } while (0)
895: #endif
896:
897: #if !defined (umul_ppmm)
898: #define umul_ppmm(w1, w0, u, v) \
899: do { \
900: USItype __x0, __x1, __x2, __x3; \
901: USItype __ul, __vl, __uh, __vh; \
902: \
903: __ul = __ll_lowpart (u); \
904: __uh = __ll_highpart (u); \
905: __vl = __ll_lowpart (v); \
906: __vh = __ll_highpart (v); \
907: \
908: __x0 = (USItype) __ul * __vl; \
909: __x1 = (USItype) __ul * __vh; \
910: __x2 = (USItype) __uh * __vl; \
911: __x3 = (USItype) __uh * __vh; \
912: \
913: __x1 += __ll_highpart (__x0);/* this can't give carry */ \
914: __x1 += __x2; /* but this indeed can */ \
915: if (__x1 < __x2) /* did we get it? */ \
916: __x3 += __ll_B; /* yes, add it in the proper pos. */ \
917: \
918: (w1) = __x3 + __ll_highpart (__x1); \
919: (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
920: } while (0)
921: #endif
922:
923: #if !defined (__umulsidi3)
924: #define __umulsidi3(u, v) \
925: ({DIunion __w; \
926: umul_ppmm (__w.s.high, __w.s.low, u, v); \
927: __w.ll; })
928: #endif
929:
930: /* Define this unconditionally, so it can be used for debugging. */
931: #define __udiv_qrnnd_c(q, r, n1, n0, d) \
932: do { \
933: USItype __d1, __d0, __q1, __q0; \
934: USItype __r1, __r0, __m; \
935: __d1 = __ll_highpart (d); \
936: __d0 = __ll_lowpart (d); \
937: \
938: __r1 = (n1) % __d1; \
939: __q1 = (n1) / __d1; \
940: __m = (USItype) __q1 * __d0; \
941: __r1 = __r1 * __ll_B | __ll_highpart (n0); \
942: if (__r1 < __m) \
943: { \
944: __q1--, __r1 += (d); \
945: if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
946: if (__r1 < __m) \
947: __q1--, __r1 += (d); \
948: } \
949: __r1 -= __m; \
950: \
951: __r0 = __r1 % __d1; \
952: __q0 = __r1 / __d1; \
953: __m = (USItype) __q0 * __d0; \
954: __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
955: if (__r0 < __m) \
956: { \
957: __q0--, __r0 += (d); \
958: if (__r0 >= (d)) \
959: if (__r0 < __m) \
960: __q0--, __r0 += (d); \
961: } \
962: __r0 -= __m; \
963: \
964: (q) = (USItype) __q1 * __ll_B | __q0; \
965: (r) = __r0; \
966: } while (0)
967:
968: /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
969: __udiv_w_sdiv (defined in libgcc or elsewhere). */
970: #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
971: #define udiv_qrnnd(q, r, nh, nl, d) \
972: do { \
973: USItype __r; \
974: (q) = __udiv_w_sdiv (&__r, nh, nl, d); \
975: (r) = __r; \
976: } while (0)
977: #endif
978:
979: /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
980: #if !defined (udiv_qrnnd)
981: #define UDIV_NEEDS_NORMALIZATION 1
982: #define udiv_qrnnd __udiv_qrnnd_c
983: #endif
984:
985: #if !defined (count_leading_zeros)
986: extern const UQItype __clz_tab[];
987: #define count_leading_zeros(count, x) \
988: do { \
989: USItype __xr = (x); \
990: USItype __a; \
991: \
992: if (SI_TYPE_SIZE <= 32) \
993: { \
994: __a = __xr < (1<<2*__BITS4) \
995: ? (__xr < (1<<__BITS4) ? 0 : __BITS4) \
996: : (__xr < (1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
997: } \
998: else \
999: { \
1000: for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
1001: if (((__xr >> __a) & 0xff) != 0) \
1002: break; \
1003: } \
1004: \
1005: (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
1006: } while (0)
1007: #endif
1008:
1009: #ifndef UDIV_NEEDS_NORMALIZATION
1010: #define UDIV_NEEDS_NORMALIZATION 0
1011: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.