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