Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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