159691Selan /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. 259691Selan Copyright (C) 1991, 1992 Free Software Foundation, Inc. 359691Selan 459691Selan This definition file is free software; you can redistribute it 559691Selan and/or modify it under the terms of the GNU General Public 659691Selan License as published by the Free Software Foundation; either 759691Selan version 2, or (at your option) any later version. 859691Selan 959691Selan This definition file is distributed in the hope that it will be 1059691Selan useful, but WITHOUT ANY WARRANTY; without even the implied 1159691Selan warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 1259691Selan See the GNU General Public License for more details. 1359691Selan 1459691Selan You should have received a copy of the GNU General Public License 1559691Selan along with this program; if not, write to the Free Software 1659691Selan Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 1759691Selan 1859691Selan #ifndef SI_TYPE_SIZE 1959691Selan #define SI_TYPE_SIZE 32 2059691Selan #endif 2159691Selan 2259691Selan #define __BITS4 (SI_TYPE_SIZE / 4) 2359691Selan #define __ll_B (1L << (SI_TYPE_SIZE / 2)) 2459691Selan #define __ll_lowpart(t) ((USItype) (t) % __ll_B) 2559691Selan #define __ll_highpart(t) ((USItype) (t) / __ll_B) 2659691Selan 2759691Selan /* Define auxiliary asm macros. 2859691Selan 2959691Selan 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) 3059691Selan multiplies two USItype integers MULTIPLER and MULTIPLICAND, 3159691Selan and generates a two-part USItype product in HIGH_PROD and 3259691Selan LOW_PROD. 3359691Selan 3459691Selan 2) __umulsidi3(a,b) multiplies two USItype integers A and B, 3559691Selan and returns a UDItype product. This is just a variant of umul_ppmm. 3659691Selan 3759691Selan 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 3859691Selan denominator) divides a two-word unsigned integer, composed by the 3959691Selan integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and 4059691Selan places the quotient in QUOTIENT and the remainder in REMAINDER. 4159691Selan HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. 4259691Selan If, in addition, the most significant bit of DENOMINATOR must be 1, 4359691Selan then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. 4459691Selan 4559691Selan 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 4659691Selan denominator). Like udiv_qrnnd but the numbers are signed. The 4759691Selan quotient is rounded towards 0. 4859691Selan 4959691Selan 5) count_leading_zeros(count, x) counts the number of zero-bits from 5059691Selan the msb to the first non-zero bit. This is the number of steps X 5159691Selan needs to be shifted left to set the msb. Undefined for X == 0. 5259691Selan 5359691Selan 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, 5459691Selan high_addend_2, low_addend_2) adds two two-word unsigned integers, 5559691Selan composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and 5659691Selan LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and 5759691Selan LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is 5859691Selan lost. 5959691Selan 6059691Selan 7) sub_ddmmss(high_difference, low_difference, high_minuend, 6159691Selan low_minuend, high_subtrahend, low_subtrahend) subtracts two 6259691Selan two-word unsigned integers, composed by HIGH_MINUEND_1 and 6359691Selan LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 6459691Selan respectively. The result is placed in HIGH_DIFFERENCE and 6559691Selan LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, 6659691Selan and is lost. 6759691Selan 6859691Selan If any of these macros are left undefined for a particular CPU, 6959691Selan C macros are used. */ 7059691Selan 7159691Selan /* The CPUs come in alphabetical order below. 7259691Selan 7359691Selan Please add support for more CPUs here, or improve the current support 7459691Selan for the CPUs below! 7559691Selan (E.g. WE32100, i960, IBM360.) */ 7659691Selan 7759691Selan #if defined (__GNUC__) && !defined (NO_ASM) 7859691Selan 7959691Selan /* We sometimes need to clobber "cc" with gcc2, but that would not be 8059691Selan understood by gcc1. Use cpp to avoid major code duplication. */ 8159691Selan #if __GNUC__ < 2 8259691Selan #define __CLOBBER_CC 8359691Selan #define __AND_CLOBBER_CC 8459691Selan #else /* __GNUC__ >= 2 */ 8559691Selan #define __CLOBBER_CC : "cc" 8659691Selan #define __AND_CLOBBER_CC , "cc" 8759691Selan #endif /* __GNUC__ < 2 */ 8859691Selan 8959691Selan #if defined (__a29k__) || defined (___AM29K__) 9059691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 9159691Selan __asm__ ("add %1,%4,%5 9259691Selan addc %0,%2,%3" \ 9359691Selan : "=r" ((USItype)(sh)), \ 9459691Selan "=&r" ((USItype)(sl)) \ 9559691Selan : "%r" ((USItype)(ah)), \ 9659691Selan "rI" ((USItype)(bh)), \ 9759691Selan "%r" ((USItype)(al)), \ 9859691Selan "rI" ((USItype)(bl))) 9959691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 10059691Selan __asm__ ("sub %1,%4,%5 10159691Selan subc %0,%2,%3" \ 10259691Selan : "=r" ((USItype)(sh)), \ 10359691Selan "=&r" ((USItype)(sl)) \ 10459691Selan : "r" ((USItype)(ah)), \ 10559691Selan "rI" ((USItype)(bh)), \ 10659691Selan "r" ((USItype)(al)), \ 10759691Selan "rI" ((USItype)(bl))) 10859691Selan #define umul_ppmm(xh, xl, m0, m1) \ 10959691Selan do { \ 11059691Selan USItype __m0 = (m0), __m1 = (m1); \ 11159691Selan __asm__ ("multiplu %0,%1,%2" \ 11259691Selan : "=r" ((USItype)(xl)) \ 11359691Selan : "r" (__m0), \ 11459691Selan "r" (__m1)); \ 11559691Selan __asm__ ("multmu %0,%1,%2" \ 11659691Selan : "=r" ((USItype)(xh)) \ 11759691Selan : "r" (__m0), \ 11859691Selan "r" (__m1)); \ 11959691Selan } while (0) 12059691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 12159691Selan __asm__ ("dividu %0,%3,%4" \ 12259691Selan : "=r" ((USItype)(q)), \ 12359691Selan "=q" ((USItype)(r)) \ 12459691Selan : "1" ((USItype)(n1)), \ 12559691Selan "r" ((USItype)(n0)), \ 12659691Selan "r" ((USItype)(d))) 12759691Selan #define count_leading_zeros(count, x) \ 12859691Selan __asm__ ("clz %0,%1" \ 12959691Selan : "=r" ((USItype)(count)) \ 13059691Selan : "r" ((USItype)(x))) 13159691Selan #endif /* __a29k__ */ 13259691Selan 13359691Selan #if defined (__arm__) 13459691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 13559691Selan __asm__ ("adds %1,%4,%5 13659691Selan adc %0,%2,%3" \ 13759691Selan : "=r" ((USItype)(sh)), \ 13859691Selan "=&r" ((USItype)(sl)) \ 13959691Selan : "%r" ((USItype)(ah)), \ 14059691Selan "rI" ((USItype)(bh)), \ 14159691Selan "%r" ((USItype)(al)), \ 14259691Selan "rI" ((USItype)(bl))) 14359691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 14459691Selan __asm__ ("subs %1,%4,%5 14559691Selan sbc %0,%2,%3" \ 14659691Selan : "=r" ((USItype)(sh)), \ 14759691Selan "=&r" ((USItype)(sl)) \ 14859691Selan : "r" ((USItype)(ah)), \ 14959691Selan "rI" ((USItype)(bh)), \ 15059691Selan "r" ((USItype)(al)), \ 15159691Selan "rI" ((USItype)(bl))) 15259691Selan #endif /* __arm__ */ 15359691Selan 15459691Selan #if defined (__gmicro__) 15559691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 15659691Selan __asm__ ("add.w %5,%1 15759691Selan addx %3,%0" \ 15859691Selan : "=g" ((USItype)(sh)), \ 15959691Selan "=&g" ((USItype)(sl)) \ 16059691Selan : "%0" ((USItype)(ah)), \ 16159691Selan "g" ((USItype)(bh)), \ 16259691Selan "%1" ((USItype)(al)), \ 16359691Selan "g" ((USItype)(bl))) 16459691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 16559691Selan __asm__ ("sub.w %5,%1 16659691Selan subx %3,%0" \ 16759691Selan : "=g" ((USItype)(sh)), \ 16859691Selan "=&g" ((USItype)(sl)) \ 16959691Selan : "0" ((USItype)(ah)), \ 17059691Selan "g" ((USItype)(bh)), \ 17159691Selan "1" ((USItype)(al)), \ 17259691Selan "g" ((USItype)(bl))) 17359691Selan #define umul_ppmm(ph, pl, m0, m1) \ 17459691Selan __asm__ ("mulx %3,%0,%1" \ 17559691Selan : "=g" ((USItype)(ph)), \ 17659691Selan "=r" ((USItype)(pl)) \ 17759691Selan : "%0" ((USItype)(m0)), \ 17859691Selan "g" ((USItype)(m1))) 17959691Selan #define udiv_qrnnd(q, r, nh, nl, d) \ 18059691Selan __asm__ ("divx %4,%0,%1" \ 18159691Selan : "=g" ((USItype)(q)), \ 18259691Selan "=r" ((USItype)(r)) \ 18359691Selan : "1" ((USItype)(nh)), \ 18459691Selan "0" ((USItype)(nl)), \ 18559691Selan "g" ((USItype)(d))) 18659691Selan #define count_leading_zeros(count, x) \ 18759691Selan __asm__ ("bsch/1 %1,%0" \ 18859691Selan : "=g" (count) \ 18959691Selan : "g" ((USItype)(x)), \ 19059691Selan "0" ((USItype)0)) 19159691Selan #endif 19259691Selan 19359691Selan #if defined (__hppa) 19459691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 19559691Selan __asm__ ("add %4,%5,%1 19659691Selan addc %2,%3,%0" \ 19759691Selan : "=r" ((USItype)(sh)), \ 19859691Selan "=&r" ((USItype)(sl)) \ 19959691Selan : "%rM" ((USItype)(ah)), \ 20059691Selan "rM" ((USItype)(bh)), \ 20159691Selan "%rM" ((USItype)(al)), \ 20259691Selan "rM" ((USItype)(bl))) 20359691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 20459691Selan __asm__ ("sub %4,%5,%1 20559691Selan subb %2,%3,%0" \ 20659691Selan : "=r" ((USItype)(sh)), \ 20759691Selan "=&r" ((USItype)(sl)) \ 20859691Selan : "rM" ((USItype)(ah)), \ 20959691Selan "rM" ((USItype)(bh)), \ 21059691Selan "rM" ((USItype)(al)), \ 21159691Selan "rM" ((USItype)(bl))) 21259691Selan #if defined (_PA_RISC1_1) 21359691Selan #define umul_ppmm(w1, w0, u, v) \ 21459691Selan do { \ 21559691Selan union \ 21659691Selan { \ 21759691Selan UDItype __f; \ 21859691Selan struct {USItype __w1, __w0;} __w1w0; \ 21959691Selan } __t; \ 22059691Selan __asm__ ("xmpyu %1,%2,%0" \ 22159691Selan : "=x" (__t.__f) \ 22259691Selan : "x" ((USItype)(u)), \ 22359691Selan "x" ((USItype)(v))); \ 22459691Selan (w1) = __t.__w1w0.__w1; \ 22559691Selan (w0) = __t.__w1w0.__w0; \ 22659691Selan } while (0) 22759691Selan #define UMUL_TIME 8 22859691Selan #else 22959691Selan #define UMUL_TIME 30 23059691Selan #endif 23159691Selan #define UDIV_TIME 40 23259691Selan #endif 23359691Selan 23459691Selan #if defined (__i386__) || defined (__i486__) 23559691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 23659691Selan __asm__ ("addl %5,%1 23759691Selan adcl %3,%0" \ 23859691Selan : "=r" ((USItype)(sh)), \ 23959691Selan "=&r" ((USItype)(sl)) \ 24059691Selan : "%0" ((USItype)(ah)), \ 24159691Selan "g" ((USItype)(bh)), \ 24259691Selan "%1" ((USItype)(al)), \ 24359691Selan "g" ((USItype)(bl))) 24459691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 24559691Selan __asm__ ("subl %5,%1 24659691Selan sbbl %3,%0" \ 24759691Selan : "=r" ((USItype)(sh)), \ 24859691Selan "=&r" ((USItype)(sl)) \ 24959691Selan : "0" ((USItype)(ah)), \ 25059691Selan "g" ((USItype)(bh)), \ 25159691Selan "1" ((USItype)(al)), \ 25259691Selan "g" ((USItype)(bl))) 25359691Selan #define umul_ppmm(w1, w0, u, v) \ 25459691Selan __asm__ ("mull %3" \ 25559691Selan : "=a" ((USItype)(w0)), \ 25659691Selan "=d" ((USItype)(w1)) \ 25759691Selan : "%0" ((USItype)(u)), \ 25859691Selan "rm" ((USItype)(v))) 25959691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 26059691Selan __asm__ ("divl %4" \ 26159691Selan : "=a" ((USItype)(q)), \ 26259691Selan "=d" ((USItype)(r)) \ 26359691Selan : "0" ((USItype)(n0)), \ 26459691Selan "1" ((USItype)(n1)), \ 26559691Selan "rm" ((USItype)(d))) 26659691Selan #define count_leading_zeros(count, x) \ 26759691Selan do { \ 26859691Selan USItype __cbtmp; \ 26959691Selan __asm__ ("bsrl %1,%0" \ 27059691Selan : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ 27159691Selan (count) = __cbtmp ^ 31; \ 27259691Selan } while (0) 27359691Selan #define UMUL_TIME 40 27459691Selan #define UDIV_TIME 40 27559691Selan #endif /* 80x86 */ 27659691Selan 27759691Selan #if defined (__i860__) 27859691Selan #if 0 27959691Selan /* Make sure these patterns really improve the code before 28059691Selan switching them on. */ 28159691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 28259691Selan do { \ 28359691Selan union \ 28459691Selan { \ 28559691Selan DItype __ll; \ 28659691Selan struct {USItype __l, __h;} __i; \ 28759691Selan } __a, __b, __s; \ 28859691Selan __a.__i.__l = (al); \ 28959691Selan __a.__i.__h = (ah); \ 29059691Selan __b.__i.__l = (bl); \ 29159691Selan __b.__i.__h = (bh); \ 29259691Selan __asm__ ("fiadd.dd %1,%2,%0" \ 29359691Selan : "=f" (__s.__ll) \ 29459691Selan : "%f" (__a.__ll), "f" (__b.__ll)); \ 29559691Selan (sh) = __s.__i.__h; \ 29659691Selan (sl) = __s.__i.__l; \ 29759691Selan } while (0) 29859691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 29959691Selan do { \ 30059691Selan union \ 30159691Selan { \ 30259691Selan DItype __ll; \ 30359691Selan struct {USItype __l, __h;} __i; \ 30459691Selan } __a, __b, __s; \ 30559691Selan __a.__i.__l = (al); \ 30659691Selan __a.__i.__h = (ah); \ 30759691Selan __b.__i.__l = (bl); \ 30859691Selan __b.__i.__h = (bh); \ 30959691Selan __asm__ ("fisub.dd %1,%2,%0" \ 31059691Selan : "=f" (__s.__ll) \ 31159691Selan : "%f" (__a.__ll), "f" (__b.__ll)); \ 31259691Selan (sh) = __s.__i.__h; \ 31359691Selan (sl) = __s.__i.__l; \ 31459691Selan } while (0) 31559691Selan #endif 31659691Selan #endif /* __i860__ */ 31759691Selan 31859691Selan #if defined (___IBMR2__) /* IBM RS6000 */ 31959691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 32059691Selan __asm__ ("a%I5 %1,%4,%5 32159691Selan ae %0,%2,%3" \ 32259691Selan : "=r" ((USItype)(sh)), \ 32359691Selan "=&r" ((USItype)(sl)) \ 32459691Selan : "%r" ((USItype)(ah)), \ 32559691Selan "r" ((USItype)(bh)), \ 32659691Selan "%r" ((USItype)(al)), \ 32759691Selan "rI" ((USItype)(bl))) 32859691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 32959691Selan __asm__ ("sf%I4 %1,%5,%4 33059691Selan sfe %0,%3,%2" \ 33159691Selan : "=r" ((USItype)(sh)), \ 33259691Selan "=&r" ((USItype)(sl)) \ 33359691Selan : "r" ((USItype)(ah)), \ 33459691Selan "r" ((USItype)(bh)), \ 33559691Selan "rI" ((USItype)(al)), \ 33659691Selan "r" ((USItype)(bl))) 33759691Selan #define umul_ppmm(xh, xl, m0, m1) \ 33859691Selan do { \ 33959691Selan USItype __m0 = (m0), __m1 = (m1); \ 34059691Selan __asm__ ("mul %0,%2,%3" \ 34159691Selan : "=r" ((USItype)(xh)), \ 34259691Selan "=q" ((USItype)(xl)) \ 34359691Selan : "r" (__m0), \ 34459691Selan "r" (__m1)); \ 34559691Selan (xh) += ((((SItype) __m0 >> 31) & __m1) \ 34659691Selan + (((SItype) __m1 >> 31) & __m0)); \ 34759691Selan } while (0) 34859691Selan #define smul_ppmm(xh, xl, m0, m1) \ 34959691Selan __asm__ ("mul %0,%2,%3" \ 35059691Selan : "=r" ((USItype)(xh)), \ 35159691Selan "=q" ((USItype)(xl)) \ 35259691Selan : "r" ((USItype)(m0)), \ 35359691Selan "r" ((USItype)(m1))) 35459691Selan #define UMUL_TIME 8 35559691Selan #define sdiv_qrnnd(q, r, nh, nl, d) \ 35659691Selan __asm__ ("div %0,%2,%4" \ 35759691Selan : "=r" ((USItype)(q)), "=q" ((USItype)(r)) \ 35859691Selan : "r" ((USItype)(nh)), "1" ((USItype)(nl)), "r" ((USItype)(d))) 35959691Selan #define UDIV_TIME 40 36059691Selan #define UDIV_NEEDS_NORMALIZATION 1 36159691Selan #define count_leading_zeros(count, x) \ 36259691Selan __asm__ ("cntlz %0,%1" \ 36359691Selan : "=r" ((USItype)(count)) \ 36459691Selan : "r" ((USItype)(x))) 36559691Selan #endif /* ___IBMR2__ */ 36659691Selan 36759691Selan #if defined (__mc68000__) 36859691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 36959691Selan __asm__ ("add%.l %5,%1 37059691Selan addx%.l %3,%0" \ 37159691Selan : "=d" ((USItype)(sh)), \ 37259691Selan "=&d" ((USItype)(sl)) \ 37359691Selan : "%0" ((USItype)(ah)), \ 37459691Selan "d" ((USItype)(bh)), \ 37559691Selan "%1" ((USItype)(al)), \ 37659691Selan "g" ((USItype)(bl))) 37759691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 37859691Selan __asm__ ("sub%.l %5,%1 37959691Selan subx%.l %3,%0" \ 38059691Selan : "=d" ((USItype)(sh)), \ 38159691Selan "=&d" ((USItype)(sl)) \ 38259691Selan : "0" ((USItype)(ah)), \ 38359691Selan "d" ((USItype)(bh)), \ 38459691Selan "1" ((USItype)(al)), \ 38559691Selan "g" ((USItype)(bl))) 38659691Selan #if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020) 38759691Selan #define umul_ppmm(w1, w0, u, v) \ 38859691Selan __asm__ ("mulu%.l %3,%1:%0" \ 38959691Selan : "=d" ((USItype)(w0)), \ 39059691Selan "=d" ((USItype)(w1)) \ 39159691Selan : "%0" ((USItype)(u)), \ 39259691Selan "dmi" ((USItype)(v))) 39359691Selan #define UMUL_TIME 45 39459691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 39559691Selan __asm__ ("divu%.l %4,%1:%0" \ 39659691Selan : "=d" ((USItype)(q)), \ 39759691Selan "=d" ((USItype)(r)) \ 39859691Selan : "0" ((USItype)(n0)), \ 39959691Selan "1" ((USItype)(n1)), \ 40059691Selan "dmi" ((USItype)(d))) 40159691Selan #define UDIV_TIME 90 40259691Selan #define sdiv_qrnnd(q, r, n1, n0, d) \ 40359691Selan __asm__ ("divs%.l %4,%1:%0" \ 40459691Selan : "=d" ((USItype)(q)), \ 40559691Selan "=d" ((USItype)(r)) \ 40659691Selan : "0" ((USItype)(n0)), \ 40759691Selan "1" ((USItype)(n1)), \ 40859691Selan "dmi" ((USItype)(d))) 40959691Selan #define count_leading_zeros(count, x) \ 41059691Selan __asm__ ("bfffo %1{%b2:%b2},%0" \ 41159691Selan : "=d" ((USItype)(count)) \ 41259691Selan : "od" ((USItype)(x)), "n" (0)) 41359691Selan #else /* not mc68020 */ 414*60380Selan /* %/ inserts REGISTER_PREFIX. */ 41559691Selan #define umul_ppmm(xh, xl, a, b) \ 41659691Selan __asm__ ("| Inlined umul_ppmm 417*60380Selan movel %2,%/d0 418*60380Selan movel %3,%/d1 419*60380Selan movel %/d0,%/d2 420*60380Selan swap %/d0 421*60380Selan movel %/d1,%/d3 422*60380Selan swap %/d1 423*60380Selan movew %/d2,%/d4 424*60380Selan mulu %/d3,%/d4 425*60380Selan mulu %/d1,%/d2 426*60380Selan mulu %/d0,%/d3 427*60380Selan mulu %/d0,%/d1 428*60380Selan movel %/d4,%/d0 429*60380Selan eorw %/d0,%/d0 430*60380Selan swap %/d0 431*60380Selan addl %/d0,%/d2 432*60380Selan addl %/d3,%/d2 43359691Selan jcc 1f 434*60380Selan addl #65536,%/d1 435*60380Selan 1: swap %/d2 436*60380Selan moveq #0,%/d0 437*60380Selan movew %/d2,%/d0 438*60380Selan movew %/d4,%/d2 439*60380Selan movel %/d2,%1 440*60380Selan addl %/d1,%/d0 441*60380Selan movel %/d0,%0" \ 44259691Selan : "=g" ((USItype)(xh)), \ 44359691Selan "=g" ((USItype)(xl)) \ 44459691Selan : "g" ((USItype)(a)), \ 44559691Selan "g" ((USItype)(b)) \ 44659691Selan : "d0", "d1", "d2", "d3", "d4") 44759691Selan #define UMUL_TIME 100 44859691Selan #define UDIV_TIME 400 44959691Selan #endif /* not mc68020 */ 45059691Selan #endif /* mc68000 */ 45159691Selan 45259691Selan #if defined (__m88000__) 45359691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 45459691Selan __asm__ ("addu.co %1,%r4,%r5 45559691Selan addu.ci %0,%r2,%r3" \ 45659691Selan : "=r" ((USItype)(sh)), \ 45759691Selan "=&r" ((USItype)(sl)) \ 45859691Selan : "%rJ" ((USItype)(ah)), \ 45959691Selan "rJ" ((USItype)(bh)), \ 46059691Selan "%rJ" ((USItype)(al)), \ 46159691Selan "rJ" ((USItype)(bl))) 46259691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 46359691Selan __asm__ ("subu.co %1,%r4,%r5 46459691Selan subu.ci %0,%r2,%r3" \ 46559691Selan : "=r" ((USItype)(sh)), \ 46659691Selan "=&r" ((USItype)(sl)) \ 46759691Selan : "rJ" ((USItype)(ah)), \ 46859691Selan "rJ" ((USItype)(bh)), \ 46959691Selan "rJ" ((USItype)(al)), \ 47059691Selan "rJ" ((USItype)(bl))) 47159691Selan #define UMUL_TIME 17 47259691Selan #define UDIV_TIME 150 47359691Selan #define count_leading_zeros(count, x) \ 47459691Selan do { \ 47559691Selan USItype __cbtmp; \ 47659691Selan __asm__ ("ff1 %0,%1" \ 47759691Selan : "=r" (__cbtmp) \ 47859691Selan : "r" ((USItype)(x))); \ 47959691Selan (count) = __cbtmp ^ 31; \ 48059691Selan } while (0) 48159691Selan #if defined (__mc88110__) 48259691Selan #define umul_ppmm(w1, w0, u, v) \ 48359691Selan __asm__ ("mulu.d r10,%2,%3 48459691Selan or %0,r10,0 48559691Selan or %1,r11,0" \ 48659691Selan : "=r" (w1), \ 48759691Selan "=r" (w0) \ 48859691Selan : "r" ((USItype)(u)), \ 48959691Selan "r" ((USItype)(v)) \ 49059691Selan : "r10", "r11") 49159691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 49259691Selan __asm__ ("or r10,%2,0 49359691Selan or r11,%3,0 49459691Selan divu.d r10,r10,%4 49559691Selan mulu %1,%4,r11 49659691Selan subu %1,%3,%1 49759691Selan or %0,r11,0" \ 49859691Selan : "=r" (q), \ 49959691Selan "=&r" (r) \ 50059691Selan : "r" ((USItype)(n1)), \ 50159691Selan "r" ((USItype)(n0)), \ 50259691Selan "r" ((USItype)(d)) \ 50359691Selan : "r10", "r11") 50459691Selan #endif 50559691Selan #endif /* __m88000__ */ 50659691Selan 50759691Selan #if defined (__mips__) 50859691Selan #define umul_ppmm(w1, w0, u, v) \ 50959691Selan __asm__ ("multu %2,%3 51059691Selan mflo %0 51159691Selan mfhi %1" \ 51259691Selan : "=d" ((USItype)(w0)), \ 51359691Selan "=d" ((USItype)(w1)) \ 51459691Selan : "d" ((USItype)(u)), \ 51559691Selan "d" ((USItype)(v))) 51659691Selan #define UMUL_TIME 5 51759691Selan #define UDIV_TIME 100 51859691Selan #endif /* __mips__ */ 51959691Selan 52059691Selan #if defined (__ns32000__) 52159691Selan #define __umulsidi3(u, v) \ 52259691Selan ({UDItype __w; \ 52359691Selan __asm__ ("meid %2,%0" \ 52459691Selan : "=g" (__w) \ 52559691Selan : "%0" ((USItype)(u)), \ 52659691Selan "g" ((USItype)(v))); \ 52759691Selan __w; }) 52859691Selan #define div_qrnnd(q, r, n1, n0, d) \ 52959691Selan __asm__ ("movd %2,r0 53059691Selan movd %3,r1 53159691Selan deid %4,r0 53259691Selan movd r1,%0 53359691Selan movd r0,%1" \ 53459691Selan : "=g" ((USItype)(q)), \ 53559691Selan "=g" ((USItype)(r)) \ 53659691Selan : "g" ((USItype)(n0)), \ 53759691Selan "g" ((USItype)(n1)), \ 53859691Selan "g" ((USItype)(d)) \ 53959691Selan : "r0", "r1") 54059691Selan #endif /* __ns32000__ */ 54159691Selan 54259691Selan #if defined (__pyr__) 54359691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 54459691Selan __asm__ ("addw %5,%1 54559691Selan addwc %3,%0" \ 54659691Selan : "=r" ((USItype)(sh)), \ 54759691Selan "=&r" ((USItype)(sl)) \ 54859691Selan : "%0" ((USItype)(ah)), \ 54959691Selan "g" ((USItype)(bh)), \ 55059691Selan "%1" ((USItype)(al)), \ 55159691Selan "g" ((USItype)(bl))) 55259691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 55359691Selan __asm__ ("subw %5,%1 55459691Selan subwb %3,%0" \ 55559691Selan : "=r" ((USItype)(sh)), \ 55659691Selan "=&r" ((USItype)(sl)) \ 55759691Selan : "0" ((USItype)(ah)), \ 55859691Selan "g" ((USItype)(bh)), \ 55959691Selan "1" ((USItype)(al)), \ 56059691Selan "g" ((USItype)(bl))) 56159691Selan /* This insn doesn't work on ancient pyramids. */ 56259691Selan #define umul_ppmm(w1, w0, u, v) \ 56359691Selan ({union { \ 56459691Selan UDItype __ll; \ 56559691Selan struct {USItype __h, __l;} __i; \ 56659691Selan } __xx; \ 56759691Selan __xx.__i.__l = u; \ 56859691Selan __asm__ ("uemul %3,%0" \ 56959691Selan : "=r" (__xx.__i.__h), \ 57059691Selan "=r" (__xx.__i.__l) \ 57159691Selan : "1" (__xx.__i.__l), \ 57259691Selan "g" ((UDItype)(v))); \ 57359691Selan (w1) = __xx.__i.__h; \ 57459691Selan (w0) = __xx.__i.__l;}) 57559691Selan #endif /* __pyr__ */ 57659691Selan 57759691Selan #if defined (__ibm032__) /* RT/ROMP */ 57859691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 57959691Selan __asm__ ("a %1,%5 58059691Selan ae %0,%3" \ 58159691Selan : "=r" ((USItype)(sh)), \ 58259691Selan "=&r" ((USItype)(sl)) \ 58359691Selan : "%0" ((USItype)(ah)), \ 58459691Selan "r" ((USItype)(bh)), \ 58559691Selan "%1" ((USItype)(al)), \ 58659691Selan "r" ((USItype)(bl))) 58759691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 58859691Selan __asm__ ("s %1,%5 58959691Selan se %0,%3" \ 59059691Selan : "=r" ((USItype)(sh)), \ 59159691Selan "=&r" ((USItype)(sl)) \ 59259691Selan : "0" ((USItype)(ah)), \ 59359691Selan "r" ((USItype)(bh)), \ 59459691Selan "1" ((USItype)(al)), \ 59559691Selan "r" ((USItype)(bl))) 59659691Selan #define umul_ppmm(ph, pl, m0, m1) \ 59759691Selan do { \ 59859691Selan USItype __m0 = (m0), __m1 = (m1); \ 59959691Selan __asm__ ( \ 60059691Selan "s r2,r2 60159691Selan mts r10,%2 60259691Selan m r2,%3 60359691Selan m r2,%3 60459691Selan m r2,%3 60559691Selan m r2,%3 60659691Selan m r2,%3 60759691Selan m r2,%3 60859691Selan m r2,%3 60959691Selan m r2,%3 61059691Selan m r2,%3 61159691Selan m r2,%3 61259691Selan m r2,%3 61359691Selan m r2,%3 61459691Selan m r2,%3 61559691Selan m r2,%3 61659691Selan m r2,%3 61759691Selan m r2,%3 61859691Selan cas %0,r2,r0 61959691Selan mfs r10,%1" \ 62059691Selan : "=r" ((USItype)(ph)), \ 62159691Selan "=r" ((USItype)(pl)) \ 62259691Selan : "%r" (__m0), \ 62359691Selan "r" (__m1) \ 62459691Selan : "r2"); \ 62559691Selan (ph) += ((((SItype) __m0 >> 31) & __m1) \ 62659691Selan + (((SItype) __m1 >> 31) & __m0)); \ 62759691Selan } while (0) 62859691Selan #define UMUL_TIME 20 62959691Selan #define UDIV_TIME 200 63059691Selan #define count_leading_zeros(count, x) \ 63159691Selan do { \ 63259691Selan if ((x) >= 0x10000) \ 63359691Selan __asm__ ("clz %0,%1" \ 63459691Selan : "=r" ((USItype)(count)) \ 63559691Selan : "r" ((USItype)(x) >> 16)); \ 63659691Selan else \ 63759691Selan { \ 63859691Selan __asm__ ("clz %0,%1" \ 63959691Selan : "=r" ((USItype)(count)) \ 64059691Selan : "r" ((USItype)(x))); \ 64159691Selan (count) += 16; \ 64259691Selan } \ 64359691Selan } while (0) 64459691Selan #endif 64559691Selan 64659691Selan #if defined (__sparc__) 64759691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 64859691Selan __asm__ ("addcc %4,%5,%1 64959691Selan addx %2,%3,%0" \ 65059691Selan : "=r" ((USItype)(sh)), \ 65159691Selan "=&r" ((USItype)(sl)) \ 65259691Selan : "%r" ((USItype)(ah)), \ 65359691Selan "rI" ((USItype)(bh)), \ 65459691Selan "%r" ((USItype)(al)), \ 65559691Selan "rI" ((USItype)(bl)) \ 65659691Selan __CLOBBER_CC) 65759691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 65859691Selan __asm__ ("subcc %4,%5,%1 65959691Selan subx %2,%3,%0" \ 66059691Selan : "=r" ((USItype)(sh)), \ 66159691Selan "=&r" ((USItype)(sl)) \ 66259691Selan : "r" ((USItype)(ah)), \ 66359691Selan "rI" ((USItype)(bh)), \ 66459691Selan "r" ((USItype)(al)), \ 66559691Selan "rI" ((USItype)(bl)) \ 66659691Selan __CLOBBER_CC) 66759691Selan #if defined (__sparc_v8__) 66859691Selan #define umul_ppmm(w1, w0, u, v) \ 66959691Selan __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 67059691Selan : "=r" ((USItype)(w1)), \ 67159691Selan "=r" ((USItype)(w0)) \ 67259691Selan : "r" ((USItype)(u)), \ 67359691Selan "r" ((USItype)(v))) 67459691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 67559691Selan __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ 67659691Selan : "=&r" ((USItype)(q)), \ 67759691Selan "=&r" ((USItype)(r)) \ 67859691Selan : "r" ((USItype)(n1)), \ 67959691Selan "r" ((USItype)(n0)), \ 68059691Selan "r" ((USItype)(d))) 68159691Selan #else 68259691Selan #if defined (__sparclite__) 68359691Selan /* This has hardware multiply but not divide. It also has two additional 68459691Selan instructions scan (ffs from high bit) and divscc. */ 68559691Selan #define umul_ppmm(w1, w0, u, v) \ 68659691Selan __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 68759691Selan : "=r" ((USItype)(w1)), \ 68859691Selan "=r" ((USItype)(w0)) \ 68959691Selan : "r" ((USItype)(u)), \ 69059691Selan "r" ((USItype)(v))) 69159691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 69259691Selan __asm__ ("! Inlined udiv_qrnnd 69359691Selan wr %%g0,%2,%%y ! Not a delayed write for sparclite 69459691Selan tst %%g0 69559691Selan divscc %3,%4,%%g1 69659691Selan divscc %%g1,%4,%%g1 69759691Selan divscc %%g1,%4,%%g1 69859691Selan divscc %%g1,%4,%%g1 69959691Selan divscc %%g1,%4,%%g1 70059691Selan divscc %%g1,%4,%%g1 70159691Selan divscc %%g1,%4,%%g1 70259691Selan divscc %%g1,%4,%%g1 70359691Selan divscc %%g1,%4,%%g1 70459691Selan divscc %%g1,%4,%%g1 70559691Selan divscc %%g1,%4,%%g1 70659691Selan divscc %%g1,%4,%%g1 70759691Selan divscc %%g1,%4,%%g1 70859691Selan divscc %%g1,%4,%%g1 70959691Selan divscc %%g1,%4,%%g1 71059691Selan divscc %%g1,%4,%%g1 71159691Selan divscc %%g1,%4,%%g1 71259691Selan divscc %%g1,%4,%%g1 71359691Selan divscc %%g1,%4,%%g1 71459691Selan divscc %%g1,%4,%%g1 71559691Selan divscc %%g1,%4,%%g1 71659691Selan divscc %%g1,%4,%%g1 71759691Selan divscc %%g1,%4,%%g1 71859691Selan divscc %%g1,%4,%%g1 71959691Selan divscc %%g1,%4,%%g1 72059691Selan divscc %%g1,%4,%%g1 72159691Selan divscc %%g1,%4,%%g1 72259691Selan divscc %%g1,%4,%%g1 72359691Selan divscc %%g1,%4,%%g1 72459691Selan divscc %%g1,%4,%%g1 72559691Selan divscc %%g1,%4,%%g1 72659691Selan divscc %%g1,%4,%0 72759691Selan rd %%y,%1 72859691Selan bl,a 1f 72959691Selan add %1,%4,%1 73059691Selan 1: ! End of inline udiv_qrnnd" \ 73159691Selan : "=r" ((USItype)(q)), \ 73259691Selan "=r" ((USItype)(r)) \ 73359691Selan : "r" ((USItype)(n1)), \ 73459691Selan "r" ((USItype)(n0)), \ 73559691Selan "rI" ((USItype)(d)) \ 73659691Selan : "%g1" __AND_CLOBBER_CC) 73759691Selan #define UDIV_TIME 37 73859691Selan #define count_leading_zeros(count, x) \ 73959691Selan __asm__ ("scan %1,0,%0" \ 74059691Selan : "=r" ((USItype)(x)) \ 74159691Selan : "r" ((USItype)(count))) 74259691Selan #else 74359691Selan /* SPARC without integer multiplication and divide instructions. 74459691Selan (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ 74559691Selan #define umul_ppmm(w1, w0, u, v) \ 74659691Selan __asm__ ("! Inlined umul_ppmm 74759691Selan wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr 74859691Selan sra %3,31,%%g2 ! Don't move this insn 74959691Selan and %2,%%g2,%%g2 ! Don't move this insn 75059691Selan andcc %%g0,0,%%g1 ! Don't move this insn 75159691Selan mulscc %%g1,%3,%%g1 75259691Selan mulscc %%g1,%3,%%g1 75359691Selan mulscc %%g1,%3,%%g1 75459691Selan mulscc %%g1,%3,%%g1 75559691Selan mulscc %%g1,%3,%%g1 75659691Selan mulscc %%g1,%3,%%g1 75759691Selan mulscc %%g1,%3,%%g1 75859691Selan mulscc %%g1,%3,%%g1 75959691Selan mulscc %%g1,%3,%%g1 76059691Selan mulscc %%g1,%3,%%g1 76159691Selan mulscc %%g1,%3,%%g1 76259691Selan mulscc %%g1,%3,%%g1 76359691Selan mulscc %%g1,%3,%%g1 76459691Selan mulscc %%g1,%3,%%g1 76559691Selan mulscc %%g1,%3,%%g1 76659691Selan mulscc %%g1,%3,%%g1 76759691Selan mulscc %%g1,%3,%%g1 76859691Selan mulscc %%g1,%3,%%g1 76959691Selan mulscc %%g1,%3,%%g1 77059691Selan mulscc %%g1,%3,%%g1 77159691Selan mulscc %%g1,%3,%%g1 77259691Selan mulscc %%g1,%3,%%g1 77359691Selan mulscc %%g1,%3,%%g1 77459691Selan mulscc %%g1,%3,%%g1 77559691Selan mulscc %%g1,%3,%%g1 77659691Selan mulscc %%g1,%3,%%g1 77759691Selan mulscc %%g1,%3,%%g1 77859691Selan mulscc %%g1,%3,%%g1 77959691Selan mulscc %%g1,%3,%%g1 78059691Selan mulscc %%g1,%3,%%g1 78159691Selan mulscc %%g1,%3,%%g1 78259691Selan mulscc %%g1,%3,%%g1 78359691Selan mulscc %%g1,0,%%g1 78459691Selan add %%g1,%%g2,%0 78559691Selan rd %%y,%1" \ 78659691Selan : "=r" ((USItype)(w1)), \ 78759691Selan "=r" ((USItype)(w0)) \ 78859691Selan : "%rI" ((USItype)(u)), \ 78959691Selan "r" ((USItype)(v)) \ 79059691Selan : "%g1", "%g2" __AND_CLOBBER_CC) 79159691Selan #define UMUL_TIME 39 /* 39 instructions */ 79259691Selan /* It's quite necessary to add this much assembler for the sparc. 79359691Selan The default udiv_qrnnd (in C) is more than 10 times slower! */ 79459691Selan #define udiv_qrnnd(q, r, n1, n0, d) \ 79559691Selan __asm__ ("! Inlined udiv_qrnnd 79659691Selan mov 32,%%g1 79759691Selan subcc %1,%2,%%g0 79859691Selan 1: bcs 5f 79959691Selan addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb 80059691Selan sub %1,%2,%1 ! this kills msb of n 80159691Selan addx %1,%1,%1 ! so this can't give carry 80259691Selan subcc %%g1,1,%%g1 80359691Selan 2: bne 1b 80459691Selan subcc %1,%2,%%g0 80559691Selan bcs 3f 80659691Selan addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb 80759691Selan b 3f 80859691Selan sub %1,%2,%1 ! this kills msb of n 80959691Selan 4: sub %1,%2,%1 81059691Selan 5: addxcc %1,%1,%1 81159691Selan bcc 2b 81259691Selan subcc %%g1,1,%%g1 81359691Selan ! Got carry from n. Subtract next step to cancel this carry. 81459691Selan bne 4b 81559691Selan addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb 81659691Selan sub %1,%2,%1 81759691Selan 3: xnor %0,0,%0 81859691Selan ! End of inline udiv_qrnnd" \ 81959691Selan : "=&r" ((USItype)(q)), \ 82059691Selan "=&r" ((USItype)(r)) \ 82159691Selan : "r" ((USItype)(d)), \ 82259691Selan "1" ((USItype)(n1)), \ 82359691Selan "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC) 82459691Selan #define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ 82559691Selan #endif /* __sparclite__ */ 82659691Selan #endif /* __sparc_v8__ */ 82759691Selan #endif /* __sparc__ */ 82859691Selan 82959691Selan #if defined (__vax__) 83059691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 83159691Selan __asm__ ("addl2 %5,%1 83259691Selan adwc %3,%0" \ 83359691Selan : "=g" ((USItype)(sh)), \ 83459691Selan "=&g" ((USItype)(sl)) \ 83559691Selan : "%0" ((USItype)(ah)), \ 83659691Selan "g" ((USItype)(bh)), \ 83759691Selan "%1" ((USItype)(al)), \ 83859691Selan "g" ((USItype)(bl))) 83959691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 84059691Selan __asm__ ("subl2 %5,%1 84159691Selan sbwc %3,%0" \ 84259691Selan : "=g" ((USItype)(sh)), \ 84359691Selan "=&g" ((USItype)(sl)) \ 84459691Selan : "0" ((USItype)(ah)), \ 84559691Selan "g" ((USItype)(bh)), \ 84659691Selan "1" ((USItype)(al)), \ 84759691Selan "g" ((USItype)(bl))) 84859691Selan #define umul_ppmm(xh, xl, m0, m1) \ 84959691Selan do { \ 85059691Selan union { \ 85159691Selan UDItype __ll; \ 85259691Selan struct {USItype __l, __h;} __i; \ 85359691Selan } __xx; \ 85459691Selan USItype __m0 = (m0), __m1 = (m1); \ 85559691Selan __asm__ ("emul %1,%2,$0,%0" \ 85659691Selan : "=r" (__xx.__ll) \ 85759691Selan : "g" (__m0), \ 85859691Selan "g" (__m1)); \ 85959691Selan (xh) = __xx.__i.__h; \ 86059691Selan (xl) = __xx.__i.__l; \ 86159691Selan (xh) += ((((SItype) __m0 >> 31) & __m1) \ 86259691Selan + (((SItype) __m1 >> 31) & __m0)); \ 86359691Selan } while (0) 86459691Selan #endif /* __vax__ */ 86559691Selan 86659691Selan #endif /* __GNUC__ */ 86759691Selan 86859691Selan /* If this machine has no inline assembler, use C macros. */ 86959691Selan 87059691Selan #if !defined (add_ssaaaa) 87159691Selan #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 87259691Selan do { \ 87359691Selan USItype __x; \ 87459691Selan __x = (al) + (bl); \ 87559691Selan (sh) = (ah) + (bh) + (__x < (al)); \ 87659691Selan (sl) = __x; \ 87759691Selan } while (0) 87859691Selan #endif 87959691Selan 88059691Selan #if !defined (sub_ddmmss) 88159691Selan #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 88259691Selan do { \ 88359691Selan USItype __x; \ 88459691Selan __x = (al) - (bl); \ 88559691Selan (sh) = (ah) - (bh) - (__x > (al)); \ 88659691Selan (sl) = __x; \ 88759691Selan } while (0) 88859691Selan #endif 88959691Selan 89059691Selan #if !defined (umul_ppmm) 89159691Selan #define umul_ppmm(w1, w0, u, v) \ 89259691Selan do { \ 89359691Selan USItype __x0, __x1, __x2, __x3; \ 89459691Selan USItype __ul, __vl, __uh, __vh; \ 89559691Selan \ 89659691Selan __ul = __ll_lowpart (u); \ 89759691Selan __uh = __ll_highpart (u); \ 89859691Selan __vl = __ll_lowpart (v); \ 89959691Selan __vh = __ll_highpart (v); \ 90059691Selan \ 90159691Selan __x0 = (USItype) __ul * __vl; \ 90259691Selan __x1 = (USItype) __ul * __vh; \ 90359691Selan __x2 = (USItype) __uh * __vl; \ 90459691Selan __x3 = (USItype) __uh * __vh; \ 90559691Selan \ 90659691Selan __x1 += __ll_highpart (__x0);/* this can't give carry */ \ 90759691Selan __x1 += __x2; /* but this indeed can */ \ 90859691Selan if (__x1 < __x2) /* did we get it? */ \ 90959691Selan __x3 += __ll_B; /* yes, add it in the proper pos. */ \ 91059691Selan \ 91159691Selan (w1) = __x3 + __ll_highpart (__x1); \ 91259691Selan (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ 91359691Selan } while (0) 91459691Selan #endif 91559691Selan 91659691Selan #if !defined (__umulsidi3) 91759691Selan #define __umulsidi3(u, v) \ 91859691Selan ({DIunion __w; \ 91959691Selan umul_ppmm (__w.s.high, __w.s.low, u, v); \ 92059691Selan __w.ll; }) 92159691Selan #endif 92259691Selan 92359691Selan /* Define this unconditionally, so it can be used for debugging. */ 92459691Selan #define __udiv_qrnnd_c(q, r, n1, n0, d) \ 92559691Selan do { \ 92659691Selan USItype __d1, __d0, __q1, __q0; \ 92759691Selan USItype __r1, __r0, __m; \ 92859691Selan __d1 = __ll_highpart (d); \ 92959691Selan __d0 = __ll_lowpart (d); \ 93059691Selan \ 93159691Selan __r1 = (n1) % __d1; \ 93259691Selan __q1 = (n1) / __d1; \ 93359691Selan __m = (USItype) __q1 * __d0; \ 93459691Selan __r1 = __r1 * __ll_B | __ll_highpart (n0); \ 93559691Selan if (__r1 < __m) \ 93659691Selan { \ 93759691Selan __q1--, __r1 += (d); \ 93859691Selan if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ 93959691Selan if (__r1 < __m) \ 94059691Selan __q1--, __r1 += (d); \ 94159691Selan } \ 94259691Selan __r1 -= __m; \ 94359691Selan \ 94459691Selan __r0 = __r1 % __d1; \ 94559691Selan __q0 = __r1 / __d1; \ 94659691Selan __m = (USItype) __q0 * __d0; \ 94759691Selan __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ 94859691Selan if (__r0 < __m) \ 94959691Selan { \ 95059691Selan __q0--, __r0 += (d); \ 95159691Selan if (__r0 >= (d)) \ 95259691Selan if (__r0 < __m) \ 95359691Selan __q0--, __r0 += (d); \ 95459691Selan } \ 95559691Selan __r0 -= __m; \ 95659691Selan \ 95759691Selan (q) = (USItype) __q1 * __ll_B | __q0; \ 95859691Selan (r) = __r0; \ 95959691Selan } while (0) 96059691Selan 96159691Selan /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through 96259691Selan __udiv_w_sdiv (defined in libgcc or elsewhere). */ 96359691Selan #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) 96459691Selan #define udiv_qrnnd(q, r, nh, nl, d) \ 96559691Selan do { \ 96659691Selan USItype __r; \ 96759691Selan (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ 96859691Selan (r) = __r; \ 96959691Selan } while (0) 97059691Selan #endif 97159691Selan 97259691Selan /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ 97359691Selan #if !defined (udiv_qrnnd) 97459691Selan #define UDIV_NEEDS_NORMALIZATION 1 97559691Selan #define udiv_qrnnd __udiv_qrnnd_c 97659691Selan #endif 97759691Selan 97859691Selan #if !defined (count_leading_zeros) 97959691Selan extern const UQItype __clz_tab[]; 98059691Selan #define count_leading_zeros(count, x) \ 98159691Selan do { \ 98259691Selan USItype __xr = (x); \ 98359691Selan USItype __a; \ 98459691Selan \ 98559691Selan if (SI_TYPE_SIZE <= 32) \ 98659691Selan { \ 98759691Selan __a = __xr < (1<<2*__BITS4) \ 98859691Selan ? (__xr < (1<<__BITS4) ? 0 : __BITS4) \ 98959691Selan : (__xr < (1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ 99059691Selan } \ 99159691Selan else \ 99259691Selan { \ 99359691Selan for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ 99459691Selan if (((__xr >> __a) & 0xff) != 0) \ 99559691Selan break; \ 99659691Selan } \ 99759691Selan \ 99859691Selan (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ 99959691Selan } while (0) 100059691Selan #endif 100159691Selan 100259691Selan #ifndef UDIV_NEEDS_NORMALIZATION 100359691Selan #define UDIV_NEEDS_NORMALIZATION 0 100459691Selan #endif 1005