|
|
1.1 root 1: /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
1.1.1.3 root 2: Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1.1 root 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:
1.1.1.4 root 18: #ifndef SI_TYPE_SIZE
19: #define SI_TYPE_SIZE 32
1.1 root 20: #endif
21:
1.1.1.4 root 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)
1.1 root 26:
1.1.1.2 root 27: /* Define auxiliary asm macros.
1.1 root 28:
29: 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
1.1.1.4 root 30: multiplies two USItype integers MULTIPLER and MULTIPLICAND,
31: and generates a two-part USItype product in HIGH_PROD and
1.1 root 32: LOW_PROD.
33:
1.1.1.4 root 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.
1.1 root 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:
1.1.1.4 root 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
1.1 root 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:
1.1.1.4 root 53: 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
1.1 root 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:
1.1.1.4 root 60: 7) sub_ddmmss(high_difference, low_difference, high_minuend,
1.1 root 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!
1.1.1.3 root 75: (E.g. WE32100, i960, IBM360.) */
1.1 root 76:
77: #if defined (__GNUC__) && !defined (NO_ASM)
78:
1.1.1.3 root 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:
1.1 root 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" \
1.1.1.4 root 93: : "=r" ((USItype)(sh)), \
94: "=&r" ((USItype)(sl)) \
95: : "%r" ((USItype)(ah)), \
96: "rI" ((USItype)(bh)), \
97: "%r" ((USItype)(al)), \
98: "rI" ((USItype)(bl)))
1.1 root 99: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
100: __asm__ ("sub %1,%4,%5
101: subc %0,%2,%3" \
1.1.1.4 root 102: : "=r" ((USItype)(sh)), \
103: "=&r" ((USItype)(sl)) \
104: : "r" ((USItype)(ah)), \
105: "rI" ((USItype)(bh)), \
106: "r" ((USItype)(al)), \
107: "rI" ((USItype)(bl)))
1.1 root 108: #define umul_ppmm(xh, xl, m0, m1) \
109: do { \
1.1.1.4 root 110: USItype __m0 = (m0), __m1 = (m1); \
1.1.1.3 root 111: __asm__ ("multiplu %0,%1,%2" \
1.1.1.4 root 112: : "=r" ((USItype)(xl)) \
1.1.1.3 root 113: : "r" (__m0), \
114: "r" (__m1)); \
115: __asm__ ("multmu %0,%1,%2" \
1.1.1.4 root 116: : "=r" ((USItype)(xh)) \
1.1.1.3 root 117: : "r" (__m0), \
118: "r" (__m1)); \
1.1 root 119: } while (0)
120: #define udiv_qrnnd(q, r, n1, n0, d) \
121: __asm__ ("dividu %0,%3,%4" \
1.1.1.4 root 122: : "=r" ((USItype)(q)), \
123: "=q" ((USItype)(r)) \
124: : "1" ((USItype)(n1)), \
125: "r" ((USItype)(n0)), \
126: "r" ((USItype)(d)))
1.1 root 127: #define count_leading_zeros(count, x) \
1.1.1.3 root 128: __asm__ ("clz %0,%1" \
1.1.1.4 root 129: : "=r" ((USItype)(count)) \
130: : "r" ((USItype)(x)))
1.1 root 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" \
1.1.1.4 root 137: : "=r" ((USItype)(sh)), \
138: "=&r" ((USItype)(sl)) \
139: : "%r" ((USItype)(ah)), \
140: "rI" ((USItype)(bh)), \
141: "%r" ((USItype)(al)), \
142: "rI" ((USItype)(bl)))
1.1 root 143: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
144: __asm__ ("subs %1,%4,%5
145: sbc %0,%2,%3" \
1.1.1.4 root 146: : "=r" ((USItype)(sh)), \
147: "=&r" ((USItype)(sl)) \
148: : "r" ((USItype)(ah)), \
149: "rI" ((USItype)(bh)), \
150: "r" ((USItype)(al)), \
151: "rI" ((USItype)(bl)))
1.1 root 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" \
1.1.1.4 root 158: : "=g" ((USItype)(sh)), \
159: "=&g" ((USItype)(sl)) \
160: : "%0" ((USItype)(ah)), \
161: "g" ((USItype)(bh)), \
162: "%1" ((USItype)(al)), \
163: "g" ((USItype)(bl)))
1.1 root 164: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
165: __asm__ ("sub.w %5,%1
166: subx %3,%0" \
1.1.1.4 root 167: : "=g" ((USItype)(sh)), \
168: "=&g" ((USItype)(sl)) \
169: : "0" ((USItype)(ah)), \
170: "g" ((USItype)(bh)), \
171: "1" ((USItype)(al)), \
172: "g" ((USItype)(bl)))
1.1 root 173: #define umul_ppmm(ph, pl, m0, m1) \
174: __asm__ ("mulx %3,%0,%1" \
1.1.1.4 root 175: : "=g" ((USItype)(ph)), \
176: "=r" ((USItype)(pl)) \
177: : "%0" ((USItype)(m0)), \
178: "g" ((USItype)(m1)))
1.1 root 179: #define udiv_qrnnd(q, r, nh, nl, d) \
180: __asm__ ("divx %4,%0,%1" \
1.1.1.4 root 181: : "=g" ((USItype)(q)), \
182: "=r" ((USItype)(r)) \
183: : "1" ((USItype)(nh)), \
184: "0" ((USItype)(nl)), \
185: "g" ((USItype)(d)))
1.1 root 186: #define count_leading_zeros(count, x) \
187: __asm__ ("bsch/1 %1,%0" \
1.1.1.3 root 188: : "=g" (count) \
1.1.1.4 root 189: : "g" ((USItype)(x)), \
190: "0" ((USItype)0))
1.1 root 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" \
1.1.1.4 root 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)))
1.1.1.3 root 212: #if defined (_PA_RISC1_1)
213: #define umul_ppmm(w1, w0, u, v) \
214: do { \
215: union \
216: { \
1.1.1.4 root 217: UDItype __f; \
218: struct {USItype __w1, __w0;} __w1w0; \
1.1.1.3 root 219: } __t; \
220: __asm__ ("xmpyu %1,%2,%0" \
221: : "=x" (__t.__f) \
1.1.1.4 root 222: : "x" ((USItype)(u)), \
223: "x" ((USItype)(v))); \
1.1.1.3 root 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
1.1 root 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" \
1.1.1.4 root 238: : "=r" ((USItype)(sh)), \
239: "=&r" ((USItype)(sl)) \
240: : "%0" ((USItype)(ah)), \
241: "g" ((USItype)(bh)), \
242: "%1" ((USItype)(al)), \
243: "g" ((USItype)(bl)))
1.1 root 244: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
245: __asm__ ("subl %5,%1
246: sbbl %3,%0" \
1.1.1.4 root 247: : "=r" ((USItype)(sh)), \
248: "=&r" ((USItype)(sl)) \
249: : "0" ((USItype)(ah)), \
250: "g" ((USItype)(bh)), \
251: "1" ((USItype)(al)), \
252: "g" ((USItype)(bl)))
1.1 root 253: #define umul_ppmm(w1, w0, u, v) \
254: __asm__ ("mull %3" \
1.1.1.4 root 255: : "=a" ((USItype)(w0)), \
256: "=d" ((USItype)(w1)) \
257: : "%0" ((USItype)(u)), \
258: "rm" ((USItype)(v)))
1.1 root 259: #define udiv_qrnnd(q, r, n1, n0, d) \
260: __asm__ ("divl %4" \
1.1.1.4 root 261: : "=a" ((USItype)(q)), \
262: "=d" ((USItype)(r)) \
263: : "0" ((USItype)(n0)), \
264: "1" ((USItype)(n1)), \
265: "rm" ((USItype)(d)))
1.1 root 266: #define count_leading_zeros(count, x) \
267: do { \
1.1.1.4 root 268: USItype __cbtmp; \
1.1 root 269: __asm__ ("bsrl %1,%0" \
1.1.1.4 root 270: : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
1.1 root 271: (count) = __cbtmp ^ 31; \
272: } while (0)
1.1.1.3 root 273: #define UMUL_TIME 40
274: #define UDIV_TIME 40
1.1 root 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: { \
1.1.1.4 root 285: DItype __ll; \
286: struct {USItype __l, __h;} __i; \
1.1 root 287: } __a, __b, __s; \
1.1.1.4 root 288: __a.__i.__l = (al); \
289: __a.__i.__h = (ah); \
290: __b.__i.__l = (bl); \
291: __b.__i.__h = (bh); \
1.1 root 292: __asm__ ("fiadd.dd %1,%2,%0" \
1.1.1.4 root 293: : "=f" (__s.__ll) \
294: : "%f" (__a.__ll), "f" (__b.__ll)); \
295: (sh) = __s.__i.__h; \
296: (sl) = __s.__i.__l; \
1.1 root 297: } while (0)
298: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
299: do { \
300: union \
301: { \
1.1.1.4 root 302: DItype __ll; \
303: struct {USItype __l, __h;} __i; \
1.1 root 304: } __a, __b, __s; \
1.1.1.4 root 305: __a.__i.__l = (al); \
306: __a.__i.__h = (ah); \
307: __b.__i.__l = (bl); \
308: __b.__i.__h = (bh); \
1.1 root 309: __asm__ ("fisub.dd %1,%2,%0" \
1.1.1.4 root 310: : "=f" (__s.__ll) \
311: : "%f" (__a.__ll), "f" (__b.__ll)); \
312: (sh) = __s.__i.__h; \
313: (sl) = __s.__i.__l; \
1.1 root 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) \
1.1.1.3 root 320: __asm__ ("a%I5 %1,%4,%5
1.1 root 321: ae %0,%2,%3" \
1.1.1.4 root 322: : "=r" ((USItype)(sh)), \
323: "=&r" ((USItype)(sl)) \
324: : "%r" ((USItype)(ah)), \
325: "r" ((USItype)(bh)), \
326: "%r" ((USItype)(al)), \
327: "rI" ((USItype)(bl)))
1.1 root 328: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1.1.1.3 root 329: __asm__ ("sf%I4 %1,%5,%4
1.1 root 330: sfe %0,%3,%2" \
1.1.1.4 root 331: : "=r" ((USItype)(sh)), \
332: "=&r" ((USItype)(sl)) \
333: : "r" ((USItype)(ah)), \
334: "r" ((USItype)(bh)), \
335: "rI" ((USItype)(al)), \
336: "r" ((USItype)(bl)))
1.1 root 337: #define umul_ppmm(xh, xl, m0, m1) \
338: do { \
1.1.1.4 root 339: USItype __m0 = (m0), __m1 = (m1); \
1.1 root 340: __asm__ ("mul %0,%2,%3" \
1.1.1.4 root 341: : "=r" ((USItype)(xh)), \
342: "=q" ((USItype)(xl)) \
1.1.1.3 root 343: : "r" (__m0), \
344: "r" (__m1)); \
1.1.1.4 root 345: (xh) += ((((SItype) __m0 >> 31) & __m1) \
346: + (((SItype) __m1 >> 31) & __m0)); \
1.1 root 347: } while (0)
1.1.1.3 root 348: #define smul_ppmm(xh, xl, m0, m1) \
349: __asm__ ("mul %0,%2,%3" \
1.1.1.4 root 350: : "=r" ((USItype)(xh)), \
351: "=q" ((USItype)(xl)) \
352: : "r" ((USItype)(m0)), \
353: "r" ((USItype)(m1)))
1.1 root 354: #define UMUL_TIME 8
1.1.1.3 root 355: #define sdiv_qrnnd(q, r, nh, nl, d) \
356: __asm__ ("div %0,%2,%4" \
1.1.1.4 root 357: : "=r" ((USItype)(q)), "=q" ((USItype)(r)) \
358: : "r" ((USItype)(nh)), "1" ((USItype)(nl)), "r" ((USItype)(d)))
1.1 root 359: #define UDIV_TIME 40
360: #define UDIV_NEEDS_NORMALIZATION 1
361: #define count_leading_zeros(count, x) \
362: __asm__ ("cntlz %0,%1" \
1.1.1.4 root 363: : "=r" ((USItype)(count)) \
364: : "r" ((USItype)(x)))
1.1 root 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" \
1.1.1.4 root 371: : "=d" ((USItype)(sh)), \
372: "=&d" ((USItype)(sl)) \
373: : "%0" ((USItype)(ah)), \
374: "d" ((USItype)(bh)), \
375: "%1" ((USItype)(al)), \
376: "g" ((USItype)(bl)))
1.1 root 377: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
378: __asm__ ("sub%.l %5,%1
379: subx%.l %3,%0" \
1.1.1.4 root 380: : "=d" ((USItype)(sh)), \
381: "=&d" ((USItype)(sl)) \
382: : "0" ((USItype)(ah)), \
383: "d" ((USItype)(bh)), \
384: "1" ((USItype)(al)), \
385: "g" ((USItype)(bl)))
1.1 root 386: #if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)
387: #define umul_ppmm(w1, w0, u, v) \
388: __asm__ ("mulu%.l %3,%1:%0" \
1.1.1.4 root 389: : "=d" ((USItype)(w0)), \
390: "=d" ((USItype)(w1)) \
391: : "%0" ((USItype)(u)), \
392: "dmi" ((USItype)(v)))
1.1.1.3 root 393: #define UMUL_TIME 45
1.1 root 394: #define udiv_qrnnd(q, r, n1, n0, d) \
395: __asm__ ("divu%.l %4,%1:%0" \
1.1.1.4 root 396: : "=d" ((USItype)(q)), \
397: "=d" ((USItype)(r)) \
398: : "0" ((USItype)(n0)), \
399: "1" ((USItype)(n1)), \
400: "dmi" ((USItype)(d)))
1.1.1.3 root 401: #define UDIV_TIME 90
402: #define sdiv_qrnnd(q, r, n1, n0, d) \
403: __asm__ ("divs%.l %4,%1:%0" \
1.1.1.4 root 404: : "=d" ((USItype)(q)), \
405: "=d" ((USItype)(r)) \
406: : "0" ((USItype)(n0)), \
407: "1" ((USItype)(n1)), \
408: "dmi" ((USItype)(d)))
1.1 root 409: #define count_leading_zeros(count, x) \
410: __asm__ ("bfffo %1{%b2:%b2},%0" \
1.1.1.4 root 411: : "=d" ((USItype)(count)) \
412: : "od" ((USItype)(x)), "n" (0))
1.1 root 413: #else /* not mc68020 */
1.1.1.5 ! root 414: /* %/ inserts REGISTER_PREFIX. */
1.1 root 415: #define umul_ppmm(xh, xl, a, b) \
416: __asm__ ("| Inlined umul_ppmm
1.1.1.5 ! root 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
1.1 root 433: jcc 1f
1.1.1.5 ! root 434: addl #65536,%/d1
! 435: 1: 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" \
1.1.1.4 root 442: : "=g" ((USItype)(xh)), \
443: "=g" ((USItype)(xl)) \
444: : "g" ((USItype)(a)), \
445: "g" ((USItype)(b)) \
1.1.1.3 root 446: : "d0", "d1", "d2", "d3", "d4")
447: #define UMUL_TIME 100
448: #define UDIV_TIME 400
1.1 root 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" \
1.1.1.4 root 456: : "=r" ((USItype)(sh)), \
457: "=&r" ((USItype)(sl)) \
458: : "%rJ" ((USItype)(ah)), \
459: "rJ" ((USItype)(bh)), \
460: "%rJ" ((USItype)(al)), \
461: "rJ" ((USItype)(bl)))
1.1 root 462: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
463: __asm__ ("subu.co %1,%r4,%r5
464: subu.ci %0,%r2,%r3" \
1.1.1.4 root 465: : "=r" ((USItype)(sh)), \
466: "=&r" ((USItype)(sl)) \
467: : "rJ" ((USItype)(ah)), \
468: "rJ" ((USItype)(bh)), \
469: "rJ" ((USItype)(al)), \
470: "rJ" ((USItype)(bl)))
1.1 root 471: #define UMUL_TIME 17
472: #define UDIV_TIME 150
473: #define count_leading_zeros(count, x) \
474: do { \
1.1.1.4 root 475: USItype __cbtmp; \
1.1 root 476: __asm__ ("ff1 %0,%1" \
1.1.1.3 root 477: : "=r" (__cbtmp) \
1.1.1.4 root 478: : "r" ((USItype)(x))); \
1.1 root 479: (count) = __cbtmp ^ 31; \
480: } while (0)
1.1.1.3 root 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) \
1.1.1.4 root 488: : "r" ((USItype)(u)), \
489: "r" ((USItype)(v)) \
1.1.1.3 root 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) \
1.1.1.4 root 500: : "r" ((USItype)(n1)), \
501: "r" ((USItype)(n0)), \
502: "r" ((USItype)(d)) \
1.1.1.3 root 503: : "r10", "r11")
504: #endif
1.1 root 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" \
1.1.1.4 root 512: : "=d" ((USItype)(w0)), \
513: "=d" ((USItype)(w1)) \
514: : "d" ((USItype)(u)), \
515: "d" ((USItype)(v)))
1.1 root 516: #define UMUL_TIME 5
517: #define UDIV_TIME 100
518: #endif /* __mips__ */
519:
520: #if defined (__ns32000__)
521: #define __umulsidi3(u, v) \
1.1.1.4 root 522: ({UDItype __w; \
1.1.1.3 root 523: __asm__ ("meid %2,%0" \
524: : "=g" (__w) \
1.1.1.4 root 525: : "%0" ((USItype)(u)), \
526: "g" ((USItype)(v))); \
1.1.1.3 root 527: __w; })
1.1 root 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" \
1.1.1.4 root 534: : "=g" ((USItype)(q)), \
535: "=g" ((USItype)(r)) \
536: : "g" ((USItype)(n0)), \
537: "g" ((USItype)(n1)), \
538: "g" ((USItype)(d)) \
1.1.1.3 root 539: : "r0", "r1")
1.1 root 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" \
1.1.1.4 root 546: : "=r" ((USItype)(sh)), \
547: "=&r" ((USItype)(sl)) \
548: : "%0" ((USItype)(ah)), \
549: "g" ((USItype)(bh)), \
550: "%1" ((USItype)(al)), \
551: "g" ((USItype)(bl)))
1.1 root 552: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
553: __asm__ ("subw %5,%1
554: subwb %3,%0" \
1.1.1.4 root 555: : "=r" ((USItype)(sh)), \
556: "=&r" ((USItype)(sl)) \
557: : "0" ((USItype)(ah)), \
558: "g" ((USItype)(bh)), \
559: "1" ((USItype)(al)), \
560: "g" ((USItype)(bl)))
1.1 root 561: /* This insn doesn't work on ancient pyramids. */
562: #define umul_ppmm(w1, w0, u, v) \
1.1.1.4 root 563: ({union { \
564: UDItype __ll; \
565: struct {USItype __h, __l;} __i; \
566: } __xx; \
567: __xx.__i.__l = u; \
1.1.1.3 root 568: __asm__ ("uemul %3,%0" \
1.1.1.4 root 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;})
1.1 root 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" \
1.1.1.4 root 581: : "=r" ((USItype)(sh)), \
582: "=&r" ((USItype)(sl)) \
583: : "%0" ((USItype)(ah)), \
584: "r" ((USItype)(bh)), \
585: "%1" ((USItype)(al)), \
586: "r" ((USItype)(bl)))
1.1 root 587: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
588: __asm__ ("s %1,%5
589: se %0,%3" \
1.1.1.4 root 590: : "=r" ((USItype)(sh)), \
591: "=&r" ((USItype)(sl)) \
592: : "0" ((USItype)(ah)), \
593: "r" ((USItype)(bh)), \
594: "1" ((USItype)(al)), \
595: "r" ((USItype)(bl)))
1.1 root 596: #define umul_ppmm(ph, pl, m0, m1) \
597: do { \
1.1.1.4 root 598: USItype __m0 = (m0), __m1 = (m1); \
1.1 root 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" \
1.1.1.4 root 620: : "=r" ((USItype)(ph)), \
621: "=r" ((USItype)(pl)) \
1.1.1.3 root 622: : "%r" (__m0), \
623: "r" (__m1) \
624: : "r2"); \
1.1.1.4 root 625: (ph) += ((((SItype) __m0 >> 31) & __m1) \
626: + (((SItype) __m1 >> 31) & __m0)); \
1.1 root 627: } while (0)
1.1.1.3 root 628: #define UMUL_TIME 20
629: #define UDIV_TIME 200
1.1 root 630: #define count_leading_zeros(count, x) \
631: do { \
632: if ((x) >= 0x10000) \
633: __asm__ ("clz %0,%1" \
1.1.1.4 root 634: : "=r" ((USItype)(count)) \
635: : "r" ((USItype)(x) >> 16)); \
1.1 root 636: else \
637: { \
638: __asm__ ("clz %0,%1" \
1.1.1.4 root 639: : "=r" ((USItype)(count)) \
640: : "r" ((USItype)(x))); \
1.1 root 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" \
1.1.1.4 root 650: : "=r" ((USItype)(sh)), \
651: "=&r" ((USItype)(sl)) \
652: : "%r" ((USItype)(ah)), \
653: "rI" ((USItype)(bh)), \
654: "%r" ((USItype)(al)), \
655: "rI" ((USItype)(bl)) \
1.1.1.3 root 656: __CLOBBER_CC)
1.1 root 657: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
658: __asm__ ("subcc %4,%5,%1
659: subx %2,%3,%0" \
1.1.1.4 root 660: : "=r" ((USItype)(sh)), \
661: "=&r" ((USItype)(sl)) \
662: : "r" ((USItype)(ah)), \
663: "rI" ((USItype)(bh)), \
664: "r" ((USItype)(al)), \
665: "rI" ((USItype)(bl)) \
1.1.1.3 root 666: __CLOBBER_CC)
1.1.1.4 root 667: #if defined (__sparc_v8__)
1.1 root 668: #define umul_ppmm(w1, w0, u, v) \
669: __asm__ ("umul %2,%3,%1;rd %%y,%0" \
1.1.1.4 root 670: : "=r" ((USItype)(w1)), \
671: "=r" ((USItype)(w0)) \
672: : "r" ((USItype)(u)), \
673: "r" ((USItype)(v)))
1.1 root 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"\
1.1.1.4 root 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
730: 1: ! 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)))
1.1 root 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" \
1.1.1.4 root 786: : "=r" ((USItype)(w1)), \
787: "=r" ((USItype)(w0)) \
788: : "%rI" ((USItype)(u)), \
789: "r" ((USItype)(v)) \
1.1.1.3 root 790: : "%g1", "%g2" __AND_CLOBBER_CC)
1.1 root 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
798: 1: 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
803: 2: 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
809: 4: sub %1,%2,%1
810: 5: 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
817: 3: xnor %0,0,%0
818: ! End of inline udiv_qrnnd" \
1.1.1.4 root 819: : "=&r" ((USItype)(q)), \
820: "=&r" ((USItype)(r)) \
821: : "r" ((USItype)(d)), \
822: "1" ((USItype)(n1)), \
823: "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC)
1.1 root 824: #define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */
1.1.1.4 root 825: #endif /* __sparclite__ */
826: #endif /* __sparc_v8__ */
1.1.1.3 root 827: #endif /* __sparc__ */
1.1 root 828:
829: #if defined (__vax__)
830: #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
831: __asm__ ("addl2 %5,%1
832: adwc %3,%0" \
1.1.1.4 root 833: : "=g" ((USItype)(sh)), \
834: "=&g" ((USItype)(sl)) \
835: : "%0" ((USItype)(ah)), \
836: "g" ((USItype)(bh)), \
837: "%1" ((USItype)(al)), \
838: "g" ((USItype)(bl)))
1.1 root 839: #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
840: __asm__ ("subl2 %5,%1
841: sbwc %3,%0" \
1.1.1.4 root 842: : "=g" ((USItype)(sh)), \
843: "=&g" ((USItype)(sl)) \
844: : "0" ((USItype)(ah)), \
845: "g" ((USItype)(bh)), \
846: "1" ((USItype)(al)), \
847: "g" ((USItype)(bl)))
1.1 root 848: #define umul_ppmm(xh, xl, m0, m1) \
849: do { \
1.1.1.4 root 850: union { \
851: UDItype __ll; \
852: struct {USItype __l, __h;} __i; \
853: } __xx; \
854: USItype __m0 = (m0), __m1 = (m1); \
1.1 root 855: __asm__ ("emul %1,%2,$0,%0" \
1.1.1.4 root 856: : "=r" (__xx.__ll) \
1.1.1.3 root 857: : "g" (__m0), \
858: "g" (__m1)); \
1.1.1.4 root 859: (xh) = __xx.__i.__h; \
860: (xl) = __xx.__i.__l; \
861: (xh) += ((((SItype) __m0 >> 31) & __m1) \
862: + (((SItype) __m1 >> 31) & __m0)); \
1.1 root 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 { \
1.1.1.4 root 873: USItype __x; \
1.1 root 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 { \
1.1.1.4 root 883: USItype __x; \
1.1 root 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 { \
1.1.1.4 root 893: USItype __x0, __x1, __x2, __x3; \
894: USItype __ul, __vl, __uh, __vh; \
1.1 root 895: \
896: __ul = __ll_lowpart (u); \
897: __uh = __ll_highpart (u); \
898: __vl = __ll_lowpart (v); \
899: __vh = __ll_highpart (v); \
900: \
1.1.1.4 root 901: __x0 = (USItype) __ul * __vl; \
902: __x1 = (USItype) __ul * __vh; \
903: __x2 = (USItype) __uh * __vl; \
904: __x3 = (USItype) __uh * __vh; \
1.1 root 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) \
1.1.1.4 root 918: ({DIunion __w; \
1.1 root 919: umul_ppmm (__w.s.high, __w.s.low, u, v); \
920: __w.ll; })
921: #endif
922:
1.1.1.3 root 923: /* Define this unconditionally, so it can be used for debugging. */
924: #define __udiv_qrnnd_c(q, r, n1, n0, d) \
1.1 root 925: do { \
1.1.1.4 root 926: USItype __d1, __d0, __q1, __q0; \
927: USItype __r1, __r0, __m; \
1.1 root 928: __d1 = __ll_highpart (d); \
929: __d0 = __ll_lowpart (d); \
930: \
931: __r1 = (n1) % __d1; \
932: __q1 = (n1) / __d1; \
1.1.1.4 root 933: __m = (USItype) __q1 * __d0; \
1.1 root 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; \
1.1.1.4 root 946: __m = (USItype) __q0 * __d0; \
1.1 root 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: \
1.1.1.4 root 957: (q) = (USItype) __q1 * __ll_B | __q0; \
1.1 root 958: (r) = __r0; \
959: } while (0)
1.1.1.4 root 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:
1.1.1.3 root 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
1.1 root 976: #endif
977:
978: #if !defined (count_leading_zeros)
1.1.1.4 root 979: extern const UQItype __clz_tab[];
1.1 root 980: #define count_leading_zeros(count, x) \
981: do { \
1.1.1.4 root 982: USItype __xr = (x); \
983: USItype __a; \
1.1 root 984: \
1.1.1.4 root 985: if (SI_TYPE_SIZE <= 32) \
1.1.1.3 root 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: { \
1.1.1.4 root 993: for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
1.1.1.3 root 994: if (((__xr >> __a) & 0xff) != 0) \
995: break; \
996: } \
1.1 root 997: \
1.1.1.4 root 998: (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
1.1 root 999: } while (0)
1000: #endif
1001:
1002: #ifndef UDIV_NEEDS_NORMALIZATION
1003: #define UDIV_NEEDS_NORMALIZATION 0
1004: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.