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