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