118334Speter/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. 2169689Skan Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 3169689Skan 2005 Free Software Foundation, Inc. 418334Speter 518334Speter This definition file is free software; you can redistribute it 618334Speter and/or modify it under the terms of the GNU General Public 718334Speter License as published by the Free Software Foundation; either 818334Speter version 2, or (at your option) any later version. 918334Speter 1018334Speter This definition file is distributed in the hope that it will be 1118334Speter useful, but WITHOUT ANY WARRANTY; without even the implied 1218334Speter warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 1318334Speter See the GNU General Public License for more details. 1418334Speter 1518334Speter You should have received a copy of the GNU General Public License 1618334Speter along with this program; if not, write to the Free Software 17169689Skan Foundation, Inc., 51 Franklin Street, Fifth Floor, 18169689Skan Boston, MA 02110-1301, USA. */ 1918334Speter 2090075Sobrien/* You have to define the following before including this file: 2190075Sobrien 2290075Sobrien UWtype -- An unsigned type, default type for operations (typically a "word") 2390075Sobrien UHWtype -- An unsigned type, at least half the size of UWtype. 2490075Sobrien UDWtype -- An unsigned type, at least twice as large a UWtype 2590075Sobrien W_TYPE_SIZE -- size in bits of UWtype 2690075Sobrien 2790075Sobrien UQItype -- Unsigned 8 bit type. 2890075Sobrien SItype, USItype -- Signed and unsigned 32 bit types. 2990075Sobrien DItype, UDItype -- Signed and unsigned 64 bit types. 3090075Sobrien 3190075Sobrien On a 32 bit machine UWtype should typically be USItype; 32169689Skan on a 64 bit machine, UWtype should typically be UDItype. */ 3390075Sobrien 3490075Sobrien#define __BITS4 (W_TYPE_SIZE / 4) 3590075Sobrien#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) 3690075Sobrien#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) 3790075Sobrien#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) 3890075Sobrien 3990075Sobrien#ifndef W_TYPE_SIZE 4090075Sobrien#define W_TYPE_SIZE 32 4190075Sobrien#define UWtype USItype 4290075Sobrien#define UHWtype USItype 4390075Sobrien#define UDWtype UDItype 4418334Speter#endif 4518334Speter 46169689Skanextern const UQItype __clz_tab[256]; 47169689Skan 4818334Speter/* Define auxiliary asm macros. 4918334Speter 50169689Skan 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two 51169689Skan UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype 5290075Sobrien word product in HIGH_PROD and LOW_PROD. 5318334Speter 5490075Sobrien 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a 5590075Sobrien UDWtype product. This is just a variant of umul_ppmm. 5618334Speter 5718334Speter 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 5890075Sobrien denominator) divides a UDWtype, composed by the UWtype integers 5990075Sobrien HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient 6090075Sobrien in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less 6190075Sobrien than DENOMINATOR for correct operation. If, in addition, the most 6290075Sobrien significant bit of DENOMINATOR must be 1, then the pre-processor symbol 6390075Sobrien UDIV_NEEDS_NORMALIZATION is defined to 1. 6418334Speter 6518334Speter 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 6690075Sobrien denominator). Like udiv_qrnnd but the numbers are signed. The quotient 6790075Sobrien is rounded towards 0. 6818334Speter 6990075Sobrien 5) count_leading_zeros(count, x) counts the number of zero-bits from the 70117395Skan msb to the first nonzero bit in the UWtype X. This is the number of 7190075Sobrien steps X needs to be shifted left to set the msb. Undefined for X == 0, 7290075Sobrien unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. 7318334Speter 7490075Sobrien 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts 7590075Sobrien from the least significant end. 7618334Speter 7790075Sobrien 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, 7890075Sobrien high_addend_2, low_addend_2) adds two UWtype integers, composed by 7990075Sobrien HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 8090075Sobrien respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow 8190075Sobrien (i.e. carry out) is not stored anywhere, and is lost. 8290075Sobrien 8390075Sobrien 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, 8490075Sobrien high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, 8590075Sobrien composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and 8690075Sobrien LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE 8790075Sobrien and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, 8818334Speter and is lost. 8918334Speter 9018334Speter If any of these macros are left undefined for a particular CPU, 9118334Speter C macros are used. */ 9218334Speter 9318334Speter/* The CPUs come in alphabetical order below. 9418334Speter 9518334Speter Please add support for more CPUs here, or improve the current support 9618334Speter for the CPUs below! 9718334Speter (E.g. WE32100, IBM360.) */ 9818334Speter 9918334Speter#if defined (__GNUC__) && !defined (NO_ASM) 10018334Speter 10118334Speter/* We sometimes need to clobber "cc" with gcc2, but that would not be 10218334Speter understood by gcc1. Use cpp to avoid major code duplication. */ 10318334Speter#if __GNUC__ < 2 10418334Speter#define __CLOBBER_CC 10518334Speter#define __AND_CLOBBER_CC 10618334Speter#else /* __GNUC__ >= 2 */ 10718334Speter#define __CLOBBER_CC : "cc" 10818334Speter#define __AND_CLOBBER_CC , "cc" 10918334Speter#endif /* __GNUC__ < 2 */ 11018334Speter 11190075Sobrien#if defined (__alpha) && W_TYPE_SIZE == 64 11290075Sobrien#define umul_ppmm(ph, pl, m0, m1) \ 11390075Sobrien do { \ 11490075Sobrien UDItype __m0 = (m0), __m1 = (m1); \ 115132718Skan (ph) = __builtin_alpha_umulh (__m0, __m1); \ 11690075Sobrien (pl) = __m0 * __m1; \ 11790075Sobrien } while (0) 11890075Sobrien#define UMUL_TIME 46 11990075Sobrien#ifndef LONGLONG_STANDALONE 12090075Sobrien#define udiv_qrnnd(q, r, n1, n0, d) \ 12190075Sobrien do { UDItype __r; \ 12290075Sobrien (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ 12390075Sobrien (r) = __r; \ 12490075Sobrien } while (0) 125117395Skanextern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); 12690075Sobrien#define UDIV_TIME 220 12790075Sobrien#endif /* LONGLONG_STANDALONE */ 12890075Sobrien#ifdef __alpha_cix__ 129132718Skan#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) 130132718Skan#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) 13190075Sobrien#define COUNT_LEADING_ZEROS_0 64 13290075Sobrien#else 13390075Sobrien#define count_leading_zeros(COUNT,X) \ 13490075Sobrien do { \ 13590075Sobrien UDItype __xr = (X), __t, __a; \ 136132718Skan __t = __builtin_alpha_cmpbge (0, __xr); \ 13790075Sobrien __a = __clz_tab[__t ^ 0xff] - 1; \ 138132718Skan __t = __builtin_alpha_extbl (__xr, __a); \ 13990075Sobrien (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ 14090075Sobrien } while (0) 14190075Sobrien#define count_trailing_zeros(COUNT,X) \ 14290075Sobrien do { \ 14390075Sobrien UDItype __xr = (X), __t, __a; \ 144132718Skan __t = __builtin_alpha_cmpbge (0, __xr); \ 14590075Sobrien __t = ~__t & -~__t; \ 14690075Sobrien __a = ((__t & 0xCC) != 0) * 2; \ 14790075Sobrien __a += ((__t & 0xF0) != 0) * 4; \ 14890075Sobrien __a += ((__t & 0xAA) != 0); \ 149132718Skan __t = __builtin_alpha_extbl (__xr, __a); \ 15090075Sobrien __a <<= 3; \ 15190075Sobrien __t &= -__t; \ 15290075Sobrien __a += ((__t & 0xCC) != 0) * 2; \ 15390075Sobrien __a += ((__t & 0xF0) != 0) * 4; \ 15490075Sobrien __a += ((__t & 0xAA) != 0); \ 15590075Sobrien (COUNT) = __a; \ 15690075Sobrien } while (0) 15790075Sobrien#endif /* __alpha_cix__ */ 15890075Sobrien#endif /* __alpha */ 15990075Sobrien 16090075Sobrien#if defined (__arc__) && W_TYPE_SIZE == 32 16150397Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 16290075Sobrien __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ 16350397Sobrien : "=r" ((USItype) (sh)), \ 16450397Sobrien "=&r" ((USItype) (sl)) \ 16550397Sobrien : "%r" ((USItype) (ah)), \ 16650397Sobrien "rIJ" ((USItype) (bh)), \ 16750397Sobrien "%r" ((USItype) (al)), \ 16850397Sobrien "rIJ" ((USItype) (bl))) 16950397Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 17090075Sobrien __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ 17150397Sobrien : "=r" ((USItype) (sh)), \ 17250397Sobrien "=&r" ((USItype) (sl)) \ 17350397Sobrien : "r" ((USItype) (ah)), \ 17450397Sobrien "rIJ" ((USItype) (bh)), \ 17550397Sobrien "r" ((USItype) (al)), \ 17650397Sobrien "rIJ" ((USItype) (bl))) 17790075Sobrien/* Call libgcc routine. */ 17850397Sobrien#define umul_ppmm(w1, w0, u, v) \ 17950397Sobriendo { \ 18090075Sobrien DWunion __w; \ 18150397Sobrien __w.ll = __umulsidi3 (u, v); \ 18250397Sobrien w1 = __w.s.high; \ 18350397Sobrien w0 = __w.s.low; \ 18450397Sobrien} while (0) 18550397Sobrien#define __umulsidi3 __umulsidi3 18650397SobrienUDItype __umulsidi3 (USItype, USItype); 18750397Sobrien#endif 18850397Sobrien 189169689Skan#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32 19018334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 19190075Sobrien __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ 19250397Sobrien : "=r" ((USItype) (sh)), \ 19350397Sobrien "=&r" ((USItype) (sl)) \ 19450397Sobrien : "%r" ((USItype) (ah)), \ 19550397Sobrien "rI" ((USItype) (bh)), \ 19650397Sobrien "%r" ((USItype) (al)), \ 197169689Skan "rI" ((USItype) (bl)) __CLOBBER_CC) 19818334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 19990075Sobrien __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ 20050397Sobrien : "=r" ((USItype) (sh)), \ 20150397Sobrien "=&r" ((USItype) (sl)) \ 20250397Sobrien : "r" ((USItype) (ah)), \ 20350397Sobrien "rI" ((USItype) (bh)), \ 20450397Sobrien "r" ((USItype) (al)), \ 205169689Skan "rI" ((USItype) (bl)) __CLOBBER_CC) 20618334Speter#define umul_ppmm(xh, xl, a, b) \ 20718334Speter{register USItype __t0, __t1, __t2; \ 208244273Sandrew __asm__ ("/* Inlined umul_ppmm */\n" \ 20990075Sobrien " mov %2, %5, lsr #16\n" \ 21090075Sobrien " mov %0, %6, lsr #16\n" \ 21190075Sobrien " bic %3, %5, %2, lsl #16\n" \ 21290075Sobrien " bic %4, %6, %0, lsl #16\n" \ 21390075Sobrien " mul %1, %3, %4\n" \ 21490075Sobrien " mul %4, %2, %4\n" \ 21590075Sobrien " mul %3, %0, %3\n" \ 21690075Sobrien " mul %0, %2, %0\n" \ 21790075Sobrien " adds %3, %4, %3\n" \ 21890075Sobrien " addcs %0, %0, #65536\n" \ 21990075Sobrien " adds %1, %1, %3, lsl #16\n" \ 22090075Sobrien " adc %0, %0, %3, lsr #16" \ 22150397Sobrien : "=&r" ((USItype) (xh)), \ 22250397Sobrien "=r" ((USItype) (xl)), \ 22318334Speter "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ 22450397Sobrien : "r" ((USItype) (a)), \ 225169689Skan "r" ((USItype) (b)) __CLOBBER_CC );} 22618334Speter#define UMUL_TIME 20 22718334Speter#define UDIV_TIME 100 22818334Speter#endif /* __arm__ */ 22918334Speter 23090075Sobrien#if defined (__hppa) && W_TYPE_SIZE == 32 23118334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 23290075Sobrien __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ 23350397Sobrien : "=r" ((USItype) (sh)), \ 23450397Sobrien "=&r" ((USItype) (sl)) \ 23550397Sobrien : "%rM" ((USItype) (ah)), \ 23650397Sobrien "rM" ((USItype) (bh)), \ 23750397Sobrien "%rM" ((USItype) (al)), \ 23850397Sobrien "rM" ((USItype) (bl))) 23918334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 24090075Sobrien __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ 24150397Sobrien : "=r" ((USItype) (sh)), \ 24250397Sobrien "=&r" ((USItype) (sl)) \ 24350397Sobrien : "rM" ((USItype) (ah)), \ 24450397Sobrien "rM" ((USItype) (bh)), \ 24550397Sobrien "rM" ((USItype) (al)), \ 24650397Sobrien "rM" ((USItype) (bl))) 24718334Speter#if defined (_PA_RISC1_1) 24818334Speter#define umul_ppmm(w1, w0, u, v) \ 24918334Speter do { \ 25018334Speter union \ 25118334Speter { \ 25218334Speter UDItype __f; \ 25318334Speter struct {USItype __w1, __w0;} __w1w0; \ 25418334Speter } __t; \ 25518334Speter __asm__ ("xmpyu %1,%2,%0" \ 25618334Speter : "=x" (__t.__f) \ 25750397Sobrien : "x" ((USItype) (u)), \ 25850397Sobrien "x" ((USItype) (v))); \ 25918334Speter (w1) = __t.__w1w0.__w1; \ 26018334Speter (w0) = __t.__w1w0.__w0; \ 26118334Speter } while (0) 26218334Speter#define UMUL_TIME 8 26318334Speter#else 26418334Speter#define UMUL_TIME 30 26518334Speter#endif 26618334Speter#define UDIV_TIME 40 26718334Speter#define count_leading_zeros(count, x) \ 26818334Speter do { \ 26918334Speter USItype __tmp; \ 27018334Speter __asm__ ( \ 27190075Sobrien "ldi 1,%0\n" \ 27290075Sobrien" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ 27390075Sobrien" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ 27490075Sobrien" ldo 16(%0),%0 ; Yes. Perform add.\n" \ 27590075Sobrien" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ 27690075Sobrien" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ 27790075Sobrien" ldo 8(%0),%0 ; Yes. Perform add.\n" \ 27890075Sobrien" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ 27990075Sobrien" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ 28090075Sobrien" ldo 4(%0),%0 ; Yes. Perform add.\n" \ 28190075Sobrien" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ 28290075Sobrien" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ 28390075Sobrien" ldo 2(%0),%0 ; Yes. Perform add.\n" \ 28490075Sobrien" extru %1,30,1,%1 ; Extract bit 1.\n" \ 28590075Sobrien" sub %0,%1,%0 ; Subtract it.\n" \ 28690075Sobrien : "=r" (count), "=r" (__tmp) : "1" (x)); \ 28718334Speter } while (0) 28818334Speter#endif 28918334Speter 290117395Skan#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 29190075Sobrien#define smul_ppmm(xh, xl, m0, m1) \ 29290075Sobrien do { \ 29390075Sobrien union {DItype __ll; \ 29490075Sobrien struct {USItype __h, __l;} __i; \ 295117395Skan } __x; \ 296117395Skan __asm__ ("lr %N0,%1\n\tmr %0,%2" \ 297117395Skan : "=&r" (__x.__ll) \ 298117395Skan : "r" (m0), "r" (m1)); \ 299117395Skan (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ 30090075Sobrien } while (0) 30190075Sobrien#define sdiv_qrnnd(q, r, n1, n0, d) \ 30290075Sobrien do { \ 30390075Sobrien union {DItype __ll; \ 30490075Sobrien struct {USItype __h, __l;} __i; \ 305117395Skan } __x; \ 306117395Skan __x.__i.__h = n1; __x.__i.__l = n0; \ 30790075Sobrien __asm__ ("dr %0,%2" \ 308117395Skan : "=r" (__x.__ll) \ 309117395Skan : "0" (__x.__ll), "r" (d)); \ 310117395Skan (q) = __x.__i.__l; (r) = __x.__i.__h; \ 31190075Sobrien } while (0) 31290075Sobrien#endif 31390075Sobrien 31490075Sobrien#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 31518334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 31690075Sobrien __asm__ ("addl %5,%1\n\tadcl %3,%0" \ 317211537Srpaulo : "=r" ((USItype) (sh)), \ 318211537Srpaulo "=&r" ((USItype) (sl)) \ 319211537Srpaulo : "%0" ((USItype) (ah)), \ 320211537Srpaulo "g" ((USItype) (bh)), \ 321211537Srpaulo "%1" ((USItype) (al)), \ 322211537Srpaulo "g" ((USItype) (bl))) 32318334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 32490075Sobrien __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ 325211505Srpaulo : "=r" (sh), \ 326211505Srpaulo "=&r" (sl) \ 327211537Srpaulo : "0" ((USItype) (ah)), \ 328211537Srpaulo "g" ((USItype) (bh)), \ 329211537Srpaulo "1" ((USItype) (al)), \ 330211537Srpaulo "g" ((USItype) (bl))) 33118334Speter#define umul_ppmm(w1, w0, u, v) \ 33218334Speter __asm__ ("mull %3" \ 333211505Srpaulo : "=a" (w0), \ 334211505Srpaulo "=d" (w1) \ 335211537Srpaulo : "%0" ((USItype) (u)), \ 336211537Srpaulo "rm" ((USItype) (v))) 33790075Sobrien#define udiv_qrnnd(q, r, n1, n0, dv) \ 33818334Speter __asm__ ("divl %4" \ 339211505Srpaulo : "=a" (q), \ 340211505Srpaulo "=d" (r) \ 341211537Srpaulo : "0" ((USItype) (n0)), \ 342211537Srpaulo "1" ((USItype) (n1)), \ 343211537Srpaulo "rm" ((USItype) (dv))) 34418334Speter#define count_leading_zeros(count, x) \ 34518334Speter do { \ 34618334Speter USItype __cbtmp; \ 34718334Speter __asm__ ("bsrl %1,%0" \ 348211537Srpaulo : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ 34918334Speter (count) = __cbtmp ^ 31; \ 35018334Speter } while (0) 35190075Sobrien#define count_trailing_zeros(count, x) \ 35290075Sobrien __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) 35318334Speter#define UMUL_TIME 40 35418334Speter#define UDIV_TIME 40 35518334Speter#endif /* 80x86 */ 35618334Speter 35790075Sobrien#if defined (__i960__) && W_TYPE_SIZE == 32 35818334Speter#define umul_ppmm(w1, w0, u, v) \ 35918334Speter ({union {UDItype __ll; \ 36018334Speter struct {USItype __l, __h;} __i; \ 36118334Speter } __xx; \ 36218334Speter __asm__ ("emul %2,%1,%0" \ 36318334Speter : "=d" (__xx.__ll) \ 36450397Sobrien : "%dI" ((USItype) (u)), \ 36550397Sobrien "dI" ((USItype) (v))); \ 36618334Speter (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) 36718334Speter#define __umulsidi3(u, v) \ 36818334Speter ({UDItype __w; \ 36918334Speter __asm__ ("emul %2,%1,%0" \ 37018334Speter : "=d" (__w) \ 37150397Sobrien : "%dI" ((USItype) (u)), \ 37250397Sobrien "dI" ((USItype) (v))); \ 37390075Sobrien __w; }) 37418334Speter#endif /* __i960__ */ 37518334Speter 37690075Sobrien#if defined (__M32R__) && W_TYPE_SIZE == 32 37750397Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 37850397Sobrien /* The cmp clears the condition bit. */ \ 379132718Skan __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ 38050397Sobrien : "=r" ((USItype) (sh)), \ 38150397Sobrien "=&r" ((USItype) (sl)) \ 382132718Skan : "0" ((USItype) (ah)), \ 38350397Sobrien "r" ((USItype) (bh)), \ 384132718Skan "1" ((USItype) (al)), \ 38550397Sobrien "r" ((USItype) (bl)) \ 38650397Sobrien : "cbit") 38750397Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 38850397Sobrien /* The cmp clears the condition bit. */ \ 389132718Skan __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ 39050397Sobrien : "=r" ((USItype) (sh)), \ 39150397Sobrien "=&r" ((USItype) (sl)) \ 39250397Sobrien : "0" ((USItype) (ah)), \ 39350397Sobrien "r" ((USItype) (bh)), \ 39450397Sobrien "1" ((USItype) (al)), \ 39550397Sobrien "r" ((USItype) (bl)) \ 39650397Sobrien : "cbit") 39750397Sobrien#endif /* __M32R__ */ 39850397Sobrien 39990075Sobrien#if defined (__mc68000__) && W_TYPE_SIZE == 32 40018334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 40190075Sobrien __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ 40250397Sobrien : "=d" ((USItype) (sh)), \ 40350397Sobrien "=&d" ((USItype) (sl)) \ 40450397Sobrien : "%0" ((USItype) (ah)), \ 40550397Sobrien "d" ((USItype) (bh)), \ 40650397Sobrien "%1" ((USItype) (al)), \ 40750397Sobrien "g" ((USItype) (bl))) 40818334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 40990075Sobrien __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ 41050397Sobrien : "=d" ((USItype) (sh)), \ 41150397Sobrien "=&d" ((USItype) (sl)) \ 41250397Sobrien : "0" ((USItype) (ah)), \ 41350397Sobrien "d" ((USItype) (bh)), \ 41450397Sobrien "1" ((USItype) (al)), \ 41550397Sobrien "g" ((USItype) (bl))) 41650397Sobrien 417169689Skan/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ 418169689Skan#if (defined (__mc68020__) && !defined (__mc68060__)) 41918334Speter#define umul_ppmm(w1, w0, u, v) \ 42018334Speter __asm__ ("mulu%.l %3,%1:%0" \ 42150397Sobrien : "=d" ((USItype) (w0)), \ 42250397Sobrien "=d" ((USItype) (w1)) \ 42350397Sobrien : "%0" ((USItype) (u)), \ 42450397Sobrien "dmi" ((USItype) (v))) 42518334Speter#define UMUL_TIME 45 42618334Speter#define udiv_qrnnd(q, r, n1, n0, d) \ 42718334Speter __asm__ ("divu%.l %4,%1:%0" \ 42850397Sobrien : "=d" ((USItype) (q)), \ 42950397Sobrien "=d" ((USItype) (r)) \ 43050397Sobrien : "0" ((USItype) (n0)), \ 43150397Sobrien "1" ((USItype) (n1)), \ 43250397Sobrien "dmi" ((USItype) (d))) 43318334Speter#define UDIV_TIME 90 43418334Speter#define sdiv_qrnnd(q, r, n1, n0, d) \ 43518334Speter __asm__ ("divs%.l %4,%1:%0" \ 43650397Sobrien : "=d" ((USItype) (q)), \ 43750397Sobrien "=d" ((USItype) (r)) \ 43850397Sobrien : "0" ((USItype) (n0)), \ 43950397Sobrien "1" ((USItype) (n1)), \ 44050397Sobrien "dmi" ((USItype) (d))) 44150397Sobrien 442169689Skan#elif defined (__mcoldfire__) /* not mc68020 */ 443169689Skan 444132718Skan#define umul_ppmm(xh, xl, a, b) \ 445132718Skan __asm__ ("| Inlined umul_ppmm\n" \ 446132718Skan " move%.l %2,%/d0\n" \ 447132718Skan " move%.l %3,%/d1\n" \ 448132718Skan " move%.l %/d0,%/d2\n" \ 449132718Skan " swap %/d0\n" \ 450132718Skan " move%.l %/d1,%/d3\n" \ 451132718Skan " swap %/d1\n" \ 452132718Skan " move%.w %/d2,%/d4\n" \ 453132718Skan " mulu %/d3,%/d4\n" \ 454132718Skan " mulu %/d1,%/d2\n" \ 455132718Skan " mulu %/d0,%/d3\n" \ 456132718Skan " mulu %/d0,%/d1\n" \ 457132718Skan " move%.l %/d4,%/d0\n" \ 458132718Skan " clr%.w %/d0\n" \ 459132718Skan " swap %/d0\n" \ 460132718Skan " add%.l %/d0,%/d2\n" \ 461132718Skan " add%.l %/d3,%/d2\n" \ 462132718Skan " jcc 1f\n" \ 463132718Skan " add%.l %#65536,%/d1\n" \ 464132718Skan "1: swap %/d2\n" \ 465132718Skan " moveq %#0,%/d0\n" \ 466132718Skan " move%.w %/d2,%/d0\n" \ 467132718Skan " move%.w %/d4,%/d2\n" \ 468132718Skan " move%.l %/d2,%1\n" \ 469132718Skan " add%.l %/d1,%/d0\n" \ 470132718Skan " move%.l %/d0,%0" \ 471132718Skan : "=g" ((USItype) (xh)), \ 472132718Skan "=g" ((USItype) (xl)) \ 473132718Skan : "g" ((USItype) (a)), \ 474132718Skan "g" ((USItype) (b)) \ 475132718Skan : "d0", "d1", "d2", "d3", "d4") 476132718Skan#define UMUL_TIME 100 477132718Skan#define UDIV_TIME 400 478132718Skan#else /* not ColdFire */ 47918334Speter/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ 48018334Speter#define umul_ppmm(xh, xl, a, b) \ 48190075Sobrien __asm__ ("| Inlined umul_ppmm\n" \ 48290075Sobrien " move%.l %2,%/d0\n" \ 48390075Sobrien " move%.l %3,%/d1\n" \ 48490075Sobrien " move%.l %/d0,%/d2\n" \ 48590075Sobrien " swap %/d0\n" \ 48690075Sobrien " move%.l %/d1,%/d3\n" \ 48790075Sobrien " swap %/d1\n" \ 48890075Sobrien " move%.w %/d2,%/d4\n" \ 48990075Sobrien " mulu %/d3,%/d4\n" \ 49090075Sobrien " mulu %/d1,%/d2\n" \ 49190075Sobrien " mulu %/d0,%/d3\n" \ 49290075Sobrien " mulu %/d0,%/d1\n" \ 49390075Sobrien " move%.l %/d4,%/d0\n" \ 49490075Sobrien " eor%.w %/d0,%/d0\n" \ 49590075Sobrien " swap %/d0\n" \ 49690075Sobrien " add%.l %/d0,%/d2\n" \ 49790075Sobrien " add%.l %/d3,%/d2\n" \ 49890075Sobrien " jcc 1f\n" \ 49990075Sobrien " add%.l %#65536,%/d1\n" \ 50090075Sobrien "1: swap %/d2\n" \ 50190075Sobrien " moveq %#0,%/d0\n" \ 50290075Sobrien " move%.w %/d2,%/d0\n" \ 50390075Sobrien " move%.w %/d4,%/d2\n" \ 50490075Sobrien " move%.l %/d2,%1\n" \ 50590075Sobrien " add%.l %/d1,%/d0\n" \ 50690075Sobrien " move%.l %/d0,%0" \ 50750397Sobrien : "=g" ((USItype) (xh)), \ 50850397Sobrien "=g" ((USItype) (xl)) \ 50950397Sobrien : "g" ((USItype) (a)), \ 51050397Sobrien "g" ((USItype) (b)) \ 51118334Speter : "d0", "d1", "d2", "d3", "d4") 51218334Speter#define UMUL_TIME 100 51318334Speter#define UDIV_TIME 400 514169689Skan 51518334Speter#endif /* not mc68020 */ 51650397Sobrien 517132718Skan/* The '020, '030, '040 and '060 have bitfield insns. 518132718Skan cpu32 disguises as a 68020, but lacks them. */ 519169689Skan#if defined (__mc68020__) && !defined (__mcpu32__) 52050397Sobrien#define count_leading_zeros(count, x) \ 52150397Sobrien __asm__ ("bfffo %1{%b2:%b2},%0" \ 52250397Sobrien : "=d" ((USItype) (count)) \ 52350397Sobrien : "od" ((USItype) (x)), "n" (0)) 52450397Sobrien#endif 52518334Speter#endif /* mc68000 */ 52618334Speter 52790075Sobrien#if defined (__m88000__) && W_TYPE_SIZE == 32 52818334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 52990075Sobrien __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ 53050397Sobrien : "=r" ((USItype) (sh)), \ 53150397Sobrien "=&r" ((USItype) (sl)) \ 53250397Sobrien : "%rJ" ((USItype) (ah)), \ 53350397Sobrien "rJ" ((USItype) (bh)), \ 53450397Sobrien "%rJ" ((USItype) (al)), \ 53550397Sobrien "rJ" ((USItype) (bl))) 53618334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 53790075Sobrien __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ 53850397Sobrien : "=r" ((USItype) (sh)), \ 53950397Sobrien "=&r" ((USItype) (sl)) \ 54050397Sobrien : "rJ" ((USItype) (ah)), \ 54150397Sobrien "rJ" ((USItype) (bh)), \ 54250397Sobrien "rJ" ((USItype) (al)), \ 54350397Sobrien "rJ" ((USItype) (bl))) 54418334Speter#define count_leading_zeros(count, x) \ 54518334Speter do { \ 54618334Speter USItype __cbtmp; \ 54718334Speter __asm__ ("ff1 %0,%1" \ 54818334Speter : "=r" (__cbtmp) \ 54950397Sobrien : "r" ((USItype) (x))); \ 55018334Speter (count) = __cbtmp ^ 31; \ 55118334Speter } while (0) 55290075Sobrien#define COUNT_LEADING_ZEROS_0 63 /* sic */ 55318334Speter#if defined (__mc88110__) 55418334Speter#define umul_ppmm(wh, wl, u, v) \ 55518334Speter do { \ 55618334Speter union {UDItype __ll; \ 55718334Speter struct {USItype __h, __l;} __i; \ 55818334Speter } __xx; \ 55918334Speter __asm__ ("mulu.d %0,%1,%2" \ 56018334Speter : "=r" (__xx.__ll) \ 56150397Sobrien : "r" ((USItype) (u)), \ 56250397Sobrien "r" ((USItype) (v))); \ 56318334Speter (wh) = __xx.__i.__h; \ 56418334Speter (wl) = __xx.__i.__l; \ 56518334Speter } while (0) 56618334Speter#define udiv_qrnnd(q, r, n1, n0, d) \ 56718334Speter ({union {UDItype __ll; \ 56818334Speter struct {USItype __h, __l;} __i; \ 56918334Speter } __xx; \ 57018334Speter USItype __q; \ 57118334Speter __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ 57218334Speter __asm__ ("divu.d %0,%1,%2" \ 57318334Speter : "=r" (__q) \ 57418334Speter : "r" (__xx.__ll), \ 57550397Sobrien "r" ((USItype) (d))); \ 57618334Speter (r) = (n0) - __q * (d); (q) = __q; }) 57718334Speter#define UMUL_TIME 5 57818334Speter#define UDIV_TIME 25 57918334Speter#else 58018334Speter#define UMUL_TIME 17 58118334Speter#define UDIV_TIME 150 58218334Speter#endif /* __mc88110__ */ 58318334Speter#endif /* __m88000__ */ 58418334Speter 58590075Sobrien#if defined (__mips__) && W_TYPE_SIZE == 32 58618334Speter#define umul_ppmm(w1, w0, u, v) \ 58718334Speter __asm__ ("multu %2,%3" \ 58850397Sobrien : "=l" ((USItype) (w0)), \ 58950397Sobrien "=h" ((USItype) (w1)) \ 59050397Sobrien : "d" ((USItype) (u)), \ 59150397Sobrien "d" ((USItype) (v))) 59218334Speter#define UMUL_TIME 10 59318334Speter#define UDIV_TIME 100 59418334Speter#endif /* __mips__ */ 59518334Speter 59690075Sobrien#if defined (__ns32000__) && W_TYPE_SIZE == 32 59718334Speter#define umul_ppmm(w1, w0, u, v) \ 59818334Speter ({union {UDItype __ll; \ 59918334Speter struct {USItype __l, __h;} __i; \ 60018334Speter } __xx; \ 60118334Speter __asm__ ("meid %2,%0" \ 60218334Speter : "=g" (__xx.__ll) \ 60350397Sobrien : "%0" ((USItype) (u)), \ 60450397Sobrien "g" ((USItype) (v))); \ 60518334Speter (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) 60618334Speter#define __umulsidi3(u, v) \ 60718334Speter ({UDItype __w; \ 60818334Speter __asm__ ("meid %2,%0" \ 60918334Speter : "=g" (__w) \ 61050397Sobrien : "%0" ((USItype) (u)), \ 61150397Sobrien "g" ((USItype) (v))); \ 61218334Speter __w; }) 61318334Speter#define udiv_qrnnd(q, r, n1, n0, d) \ 61418334Speter ({union {UDItype __ll; \ 61518334Speter struct {USItype __l, __h;} __i; \ 61618334Speter } __xx; \ 61718334Speter __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ 61818334Speter __asm__ ("deid %2,%0" \ 61918334Speter : "=g" (__xx.__ll) \ 62018334Speter : "0" (__xx.__ll), \ 62150397Sobrien "g" ((USItype) (d))); \ 62218334Speter (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) 62390075Sobrien#define count_trailing_zeros(count,x) \ 624117395Skan do { \ 625117395Skan __asm__ ("ffsd %2,%0" \ 626117395Skan : "=r" ((USItype) (count)) \ 627117395Skan : "0" ((USItype) 0), \ 628117395Skan "r" ((USItype) (x))); \ 62990075Sobrien } while (0) 63018334Speter#endif /* __ns32000__ */ 63118334Speter 632117395Skan/* FIXME: We should test _IBMR2 here when we add assembly support for the 633117395Skan system vendor compilers. 634117395Skan FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good 635117395Skan enough, since that hits ARM and m68k too. */ 636117395Skan#if (defined (_ARCH_PPC) /* AIX */ \ 637117395Skan || defined (_ARCH_PWR) /* AIX */ \ 638117395Skan || defined (_ARCH_COM) /* AIX */ \ 639117395Skan || defined (__powerpc__) /* gcc */ \ 640117395Skan || defined (__POWERPC__) /* BEOS */ \ 641117395Skan || defined (__ppc__) /* Darwin */ \ 642161651Skan || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ 643161651Skan || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ 644161651Skan && CPU_FAMILY == PPC) \ 645117395Skan ) && W_TYPE_SIZE == 32 64618334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 64718334Speter do { \ 64818334Speter if (__builtin_constant_p (bh) && (bh) == 0) \ 64918334Speter __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ 650117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 651117395Skan else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ 65218334Speter __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ 653117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 65418334Speter else \ 65518334Speter __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ 656117395Skan : "=r" (sh), "=&r" (sl) \ 657117395Skan : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ 65818334Speter } while (0) 65918334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 66018334Speter do { \ 66118334Speter if (__builtin_constant_p (ah) && (ah) == 0) \ 66218334Speter __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ 663117395Skan : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 664117395Skan else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ 66518334Speter __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ 666117395Skan : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 66718334Speter else if (__builtin_constant_p (bh) && (bh) == 0) \ 66818334Speter __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ 669117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 670117395Skan else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ 67118334Speter __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ 672117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 67318334Speter else \ 67418334Speter __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ 675117395Skan : "=r" (sh), "=&r" (sl) \ 676117395Skan : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ 67718334Speter } while (0) 67818334Speter#define count_leading_zeros(count, x) \ 679117395Skan __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) 68090075Sobrien#define COUNT_LEADING_ZEROS_0 32 681117395Skan#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ 682161651Skan || defined (__ppc__) \ 683161651Skan || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ 684161651Skan || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ 685161651Skan && CPU_FAMILY == PPC) 68618334Speter#define umul_ppmm(ph, pl, m0, m1) \ 68718334Speter do { \ 68818334Speter USItype __m0 = (m0), __m1 = (m1); \ 689117395Skan __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 69018334Speter (pl) = __m0 * __m1; \ 69118334Speter } while (0) 69218334Speter#define UMUL_TIME 15 69318334Speter#define smul_ppmm(ph, pl, m0, m1) \ 69418334Speter do { \ 69518334Speter SItype __m0 = (m0), __m1 = (m1); \ 696117395Skan __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 69718334Speter (pl) = __m0 * __m1; \ 69818334Speter } while (0) 69918334Speter#define SMUL_TIME 14 70018334Speter#define UDIV_TIME 120 70190075Sobrien#elif defined (_ARCH_PWR) 70218334Speter#define UMUL_TIME 8 70318334Speter#define smul_ppmm(xh, xl, m0, m1) \ 704117395Skan __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) 70518334Speter#define SMUL_TIME 4 70618334Speter#define sdiv_qrnnd(q, r, nh, nl, d) \ 707117395Skan __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) 70818334Speter#define UDIV_TIME 100 70918334Speter#endif 710117395Skan#endif /* 32-bit POWER architecture variants. */ 71118334Speter 712117395Skan/* We should test _IBMR2 here when we add assembly support for the system 713117395Skan vendor compilers. */ 714117395Skan#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 71518334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 716117395Skan do { \ 717117395Skan if (__builtin_constant_p (bh) && (bh) == 0) \ 718117395Skan __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ 719117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 720117395Skan else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ 721117395Skan __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ 722117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 723117395Skan else \ 724117395Skan __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ 725117395Skan : "=r" (sh), "=&r" (sl) \ 726117395Skan : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ 727117395Skan } while (0) 72818334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 729117395Skan do { \ 730117395Skan if (__builtin_constant_p (ah) && (ah) == 0) \ 731117395Skan __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ 732117395Skan : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 733117395Skan else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ 734117395Skan __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ 735117395Skan : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 736117395Skan else if (__builtin_constant_p (bh) && (bh) == 0) \ 737117395Skan __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ 738117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 739117395Skan else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ 740117395Skan __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ 741117395Skan : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 742117395Skan else \ 743117395Skan __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ 744117395Skan : "=r" (sh), "=&r" (sl) \ 745117395Skan : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ 746117395Skan } while (0) 747117395Skan#define count_leading_zeros(count, x) \ 748117395Skan __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) 749117395Skan#define COUNT_LEADING_ZEROS_0 64 750117395Skan#define umul_ppmm(ph, pl, m0, m1) \ 751117395Skan do { \ 752117395Skan UDItype __m0 = (m0), __m1 = (m1); \ 753117395Skan __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 754117395Skan (pl) = __m0 * __m1; \ 755117395Skan } while (0) 756117395Skan#define UMUL_TIME 15 757117395Skan#define smul_ppmm(ph, pl, m0, m1) \ 758117395Skan do { \ 759117395Skan DItype __m0 = (m0), __m1 = (m1); \ 760117395Skan __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 761117395Skan (pl) = __m0 * __m1; \ 762117395Skan } while (0) 763117395Skan#define SMUL_TIME 14 /* ??? */ 764117395Skan#define UDIV_TIME 120 /* ??? */ 765117395Skan#endif /* 64-bit PowerPC. */ 76618334Speter 76790075Sobrien#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 76818334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 76990075Sobrien __asm__ ("a %1,%5\n\tae %0,%3" \ 77050397Sobrien : "=r" ((USItype) (sh)), \ 77150397Sobrien "=&r" ((USItype) (sl)) \ 77250397Sobrien : "%0" ((USItype) (ah)), \ 77350397Sobrien "r" ((USItype) (bh)), \ 77450397Sobrien "%1" ((USItype) (al)), \ 77550397Sobrien "r" ((USItype) (bl))) 77618334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 77790075Sobrien __asm__ ("s %1,%5\n\tse %0,%3" \ 77850397Sobrien : "=r" ((USItype) (sh)), \ 77950397Sobrien "=&r" ((USItype) (sl)) \ 78050397Sobrien : "0" ((USItype) (ah)), \ 78150397Sobrien "r" ((USItype) (bh)), \ 78250397Sobrien "1" ((USItype) (al)), \ 78350397Sobrien "r" ((USItype) (bl))) 78418334Speter#define umul_ppmm(ph, pl, m0, m1) \ 78518334Speter do { \ 78618334Speter USItype __m0 = (m0), __m1 = (m1); \ 78718334Speter __asm__ ( \ 78890075Sobrien "s r2,r2\n" \ 78990075Sobrien" mts r10,%2\n" \ 79090075Sobrien" m r2,%3\n" \ 79190075Sobrien" m r2,%3\n" \ 79290075Sobrien" m r2,%3\n" \ 79390075Sobrien" m r2,%3\n" \ 79490075Sobrien" m r2,%3\n" \ 79590075Sobrien" m r2,%3\n" \ 79690075Sobrien" m r2,%3\n" \ 79790075Sobrien" m r2,%3\n" \ 79890075Sobrien" m r2,%3\n" \ 79990075Sobrien" m r2,%3\n" \ 80090075Sobrien" m r2,%3\n" \ 80190075Sobrien" m r2,%3\n" \ 80290075Sobrien" m r2,%3\n" \ 80390075Sobrien" m r2,%3\n" \ 80490075Sobrien" m r2,%3\n" \ 80590075Sobrien" m r2,%3\n" \ 80690075Sobrien" cas %0,r2,r0\n" \ 80790075Sobrien" mfs r10,%1" \ 80850397Sobrien : "=r" ((USItype) (ph)), \ 80950397Sobrien "=r" ((USItype) (pl)) \ 81018334Speter : "%r" (__m0), \ 81118334Speter "r" (__m1) \ 81218334Speter : "r2"); \ 81318334Speter (ph) += ((((SItype) __m0 >> 31) & __m1) \ 81418334Speter + (((SItype) __m1 >> 31) & __m0)); \ 81518334Speter } while (0) 81618334Speter#define UMUL_TIME 20 81718334Speter#define UDIV_TIME 200 81818334Speter#define count_leading_zeros(count, x) \ 81918334Speter do { \ 82018334Speter if ((x) >= 0x10000) \ 82118334Speter __asm__ ("clz %0,%1" \ 82250397Sobrien : "=r" ((USItype) (count)) \ 82350397Sobrien : "r" ((USItype) (x) >> 16)); \ 82418334Speter else \ 82518334Speter { \ 82618334Speter __asm__ ("clz %0,%1" \ 82750397Sobrien : "=r" ((USItype) (count)) \ 82850397Sobrien : "r" ((USItype) (x))); \ 82918334Speter (count) += 16; \ 83018334Speter } \ 83118334Speter } while (0) 83218334Speter#endif 83318334Speter 834169689Skan#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32 835169689Skan#ifndef __sh1__ 83690075Sobrien#define umul_ppmm(w1, w0, u, v) \ 83790075Sobrien __asm__ ( \ 838169689Skan "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ 839169689Skan : "=r<" ((USItype)(w1)), \ 840169689Skan "=r<" ((USItype)(w0)) \ 84190075Sobrien : "r" ((USItype)(u)), \ 84290075Sobrien "r" ((USItype)(v)) \ 84390075Sobrien : "macl", "mach") 84490075Sobrien#define UMUL_TIME 5 84590075Sobrien#endif 84690075Sobrien 847169689Skan/* This is the same algorithm as __udiv_qrnnd_c. */ 848169689Skan#define UDIV_NEEDS_NORMALIZATION 1 849169689Skan 850169689Skan#define udiv_qrnnd(q, r, n1, n0, d) \ 851169689Skan do { \ 852169689Skan extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ 853169689Skan __attribute__ ((visibility ("hidden"))); \ 854169689Skan /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ 855169689Skan __asm__ ( \ 856169689Skan "mov%M4 %4,r5\n" \ 857169689Skan" swap.w %3,r4\n" \ 858169689Skan" swap.w r5,r6\n" \ 859169689Skan" jsr @%5\n" \ 860169689Skan" shll16 r6\n" \ 861169689Skan" swap.w r4,r4\n" \ 862169689Skan" jsr @%5\n" \ 863169689Skan" swap.w r1,%0\n" \ 864169689Skan" or r1,%0" \ 865169689Skan : "=r" (q), "=&z" (r) \ 866169689Skan : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ 867169689Skan : "r1", "r2", "r4", "r5", "r6", "pr"); \ 868169689Skan } while (0) 869169689Skan 870169689Skan#define UDIV_TIME 80 871169689Skan 872169689Skan#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 873169689Skan __asm__ ("clrt;subc %5,%1; subc %4,%0" \ 874169689Skan : "=r" (sh), "=r" (sl) \ 875169689Skan : "0" (ah), "1" (al), "r" (bh), "r" (bl)) 876169689Skan 877169689Skan#endif /* __sh__ */ 878169689Skan 87996263Sobrien#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 88096263Sobrien#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) 88196263Sobrien#define count_leading_zeros(count, x) \ 88296263Sobrien do \ 88396263Sobrien { \ 88496263Sobrien UDItype x_ = (USItype)(x); \ 88596263Sobrien SItype c_; \ 88696263Sobrien \ 88796263Sobrien __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ 88896263Sobrien (count) = c_ - 31; \ 88996263Sobrien } \ 89096263Sobrien while (0) 89196263Sobrien#define COUNT_LEADING_ZEROS_0 32 89296263Sobrien#endif 89396263Sobrien 89490075Sobrien#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ 89590075Sobrien && W_TYPE_SIZE == 32 89618334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 89790075Sobrien __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ 89850397Sobrien : "=r" ((USItype) (sh)), \ 89950397Sobrien "=&r" ((USItype) (sl)) \ 90050397Sobrien : "%rJ" ((USItype) (ah)), \ 90150397Sobrien "rI" ((USItype) (bh)), \ 90250397Sobrien "%rJ" ((USItype) (al)), \ 90350397Sobrien "rI" ((USItype) (bl)) \ 90418334Speter __CLOBBER_CC) 90518334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 90690075Sobrien __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ 90750397Sobrien : "=r" ((USItype) (sh)), \ 90850397Sobrien "=&r" ((USItype) (sl)) \ 90950397Sobrien : "rJ" ((USItype) (ah)), \ 91050397Sobrien "rI" ((USItype) (bh)), \ 91150397Sobrien "rJ" ((USItype) (al)), \ 91250397Sobrien "rI" ((USItype) (bl)) \ 91318334Speter __CLOBBER_CC) 91418334Speter#if defined (__sparc_v8__) 91518334Speter#define umul_ppmm(w1, w0, u, v) \ 91618334Speter __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 91750397Sobrien : "=r" ((USItype) (w1)), \ 91850397Sobrien "=r" ((USItype) (w0)) \ 91950397Sobrien : "r" ((USItype) (u)), \ 92050397Sobrien "r" ((USItype) (v))) 92190075Sobrien#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ 92218334Speter __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ 92390075Sobrien : "=&r" ((USItype) (__q)), \ 92490075Sobrien "=&r" ((USItype) (__r)) \ 92590075Sobrien : "r" ((USItype) (__n1)), \ 92690075Sobrien "r" ((USItype) (__n0)), \ 92790075Sobrien "r" ((USItype) (__d))) 92818334Speter#else 92918334Speter#if defined (__sparclite__) 93018334Speter/* This has hardware multiply but not divide. It also has two additional 93118334Speter instructions scan (ffs from high bit) and divscc. */ 93218334Speter#define umul_ppmm(w1, w0, u, v) \ 93318334Speter __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 93450397Sobrien : "=r" ((USItype) (w1)), \ 93550397Sobrien "=r" ((USItype) (w0)) \ 93650397Sobrien : "r" ((USItype) (u)), \ 93750397Sobrien "r" ((USItype) (v))) 93818334Speter#define udiv_qrnnd(q, r, n1, n0, d) \ 93990075Sobrien __asm__ ("! Inlined udiv_qrnnd\n" \ 94090075Sobrien" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ 94190075Sobrien" tst %%g0\n" \ 94290075Sobrien" divscc %3,%4,%%g1\n" \ 94390075Sobrien" divscc %%g1,%4,%%g1\n" \ 94490075Sobrien" divscc %%g1,%4,%%g1\n" \ 94590075Sobrien" divscc %%g1,%4,%%g1\n" \ 94690075Sobrien" divscc %%g1,%4,%%g1\n" \ 94790075Sobrien" divscc %%g1,%4,%%g1\n" \ 94890075Sobrien" divscc %%g1,%4,%%g1\n" \ 94990075Sobrien" divscc %%g1,%4,%%g1\n" \ 95090075Sobrien" divscc %%g1,%4,%%g1\n" \ 95190075Sobrien" divscc %%g1,%4,%%g1\n" \ 95290075Sobrien" divscc %%g1,%4,%%g1\n" \ 95390075Sobrien" divscc %%g1,%4,%%g1\n" \ 95490075Sobrien" divscc %%g1,%4,%%g1\n" \ 95590075Sobrien" divscc %%g1,%4,%%g1\n" \ 95690075Sobrien" divscc %%g1,%4,%%g1\n" \ 95790075Sobrien" divscc %%g1,%4,%%g1\n" \ 95890075Sobrien" divscc %%g1,%4,%%g1\n" \ 95990075Sobrien" divscc %%g1,%4,%%g1\n" \ 96090075Sobrien" divscc %%g1,%4,%%g1\n" \ 96190075Sobrien" divscc %%g1,%4,%%g1\n" \ 96290075Sobrien" divscc %%g1,%4,%%g1\n" \ 96390075Sobrien" divscc %%g1,%4,%%g1\n" \ 96490075Sobrien" divscc %%g1,%4,%%g1\n" \ 96590075Sobrien" divscc %%g1,%4,%%g1\n" \ 96690075Sobrien" divscc %%g1,%4,%%g1\n" \ 96790075Sobrien" divscc %%g1,%4,%%g1\n" \ 96890075Sobrien" divscc %%g1,%4,%%g1\n" \ 96990075Sobrien" divscc %%g1,%4,%%g1\n" \ 97090075Sobrien" divscc %%g1,%4,%%g1\n" \ 97190075Sobrien" divscc %%g1,%4,%%g1\n" \ 97290075Sobrien" divscc %%g1,%4,%%g1\n" \ 97390075Sobrien" divscc %%g1,%4,%0\n" \ 97490075Sobrien" rd %%y,%1\n" \ 97590075Sobrien" bl,a 1f\n" \ 97690075Sobrien" add %1,%4,%1\n" \ 97790075Sobrien"1: ! End of inline udiv_qrnnd" \ 97850397Sobrien : "=r" ((USItype) (q)), \ 97950397Sobrien "=r" ((USItype) (r)) \ 98050397Sobrien : "r" ((USItype) (n1)), \ 98150397Sobrien "r" ((USItype) (n0)), \ 98250397Sobrien "rI" ((USItype) (d)) \ 98390075Sobrien : "g1" __AND_CLOBBER_CC) 98418334Speter#define UDIV_TIME 37 98518334Speter#define count_leading_zeros(count, x) \ 98652284Sobrien do { \ 98752284Sobrien __asm__ ("scan %1,1,%0" \ 98852284Sobrien : "=r" ((USItype) (count)) \ 98952284Sobrien : "r" ((USItype) (x))); \ 99090075Sobrien } while (0) 99190075Sobrien/* Early sparclites return 63 for an argument of 0, but they warn that future 99290075Sobrien implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 99390075Sobrien undefined. */ 99418334Speter#else 99518334Speter/* SPARC without integer multiplication and divide instructions. 99618334Speter (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ 99718334Speter#define umul_ppmm(w1, w0, u, v) \ 99890075Sobrien __asm__ ("! Inlined umul_ppmm\n" \ 99990075Sobrien" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ 100090075Sobrien" sra %3,31,%%o5 ! Don't move this insn\n" \ 100190075Sobrien" and %2,%%o5,%%o5 ! Don't move this insn\n" \ 100290075Sobrien" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ 100390075Sobrien" mulscc %%g1,%3,%%g1\n" \ 100490075Sobrien" mulscc %%g1,%3,%%g1\n" \ 100590075Sobrien" mulscc %%g1,%3,%%g1\n" \ 100690075Sobrien" mulscc %%g1,%3,%%g1\n" \ 100790075Sobrien" mulscc %%g1,%3,%%g1\n" \ 100890075Sobrien" mulscc %%g1,%3,%%g1\n" \ 100990075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101090075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101190075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101290075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101390075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101490075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101590075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101690075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101790075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101890075Sobrien" mulscc %%g1,%3,%%g1\n" \ 101990075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102090075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102190075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102290075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102390075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102490075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102590075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102690075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102790075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102890075Sobrien" mulscc %%g1,%3,%%g1\n" \ 102990075Sobrien" mulscc %%g1,%3,%%g1\n" \ 103090075Sobrien" mulscc %%g1,%3,%%g1\n" \ 103190075Sobrien" mulscc %%g1,%3,%%g1\n" \ 103290075Sobrien" mulscc %%g1,%3,%%g1\n" \ 103390075Sobrien" mulscc %%g1,%3,%%g1\n" \ 103490075Sobrien" mulscc %%g1,%3,%%g1\n" \ 103590075Sobrien" mulscc %%g1,0,%%g1\n" \ 103690075Sobrien" add %%g1,%%o5,%0\n" \ 103790075Sobrien" rd %%y,%1" \ 103850397Sobrien : "=r" ((USItype) (w1)), \ 103950397Sobrien "=r" ((USItype) (w0)) \ 104050397Sobrien : "%rI" ((USItype) (u)), \ 104150397Sobrien "r" ((USItype) (v)) \ 104290075Sobrien : "g1", "o5" __AND_CLOBBER_CC) 104318334Speter#define UMUL_TIME 39 /* 39 instructions */ 104418334Speter/* It's quite necessary to add this much assembler for the sparc. 104518334Speter The default udiv_qrnnd (in C) is more than 10 times slower! */ 104690075Sobrien#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ 104790075Sobrien __asm__ ("! Inlined udiv_qrnnd\n" \ 104890075Sobrien" mov 32,%%g1\n" \ 104990075Sobrien" subcc %1,%2,%%g0\n" \ 105090075Sobrien"1: bcs 5f\n" \ 105190075Sobrien" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ 105290075Sobrien" sub %1,%2,%1 ! this kills msb of n\n" \ 105390075Sobrien" addx %1,%1,%1 ! so this can't give carry\n" \ 105490075Sobrien" subcc %%g1,1,%%g1\n" \ 105590075Sobrien"2: bne 1b\n" \ 105690075Sobrien" subcc %1,%2,%%g0\n" \ 105790075Sobrien" bcs 3f\n" \ 105890075Sobrien" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ 105990075Sobrien" b 3f\n" \ 106090075Sobrien" sub %1,%2,%1 ! this kills msb of n\n" \ 106190075Sobrien"4: sub %1,%2,%1\n" \ 106290075Sobrien"5: addxcc %1,%1,%1\n" \ 106390075Sobrien" bcc 2b\n" \ 106490075Sobrien" subcc %%g1,1,%%g1\n" \ 106590075Sobrien"! Got carry from n. Subtract next step to cancel this carry.\n" \ 106690075Sobrien" bne 4b\n" \ 106790075Sobrien" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ 106890075Sobrien" sub %1,%2,%1\n" \ 106990075Sobrien"3: xnor %0,0,%0\n" \ 107090075Sobrien" ! End of inline udiv_qrnnd" \ 107190075Sobrien : "=&r" ((USItype) (__q)), \ 107290075Sobrien "=&r" ((USItype) (__r)) \ 107390075Sobrien : "r" ((USItype) (__d)), \ 107490075Sobrien "1" ((USItype) (__n1)), \ 107590075Sobrien "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) 107690075Sobrien#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ 107718334Speter#endif /* __sparclite__ */ 107818334Speter#endif /* __sparc_v8__ */ 107990075Sobrien#endif /* sparc32 */ 108018334Speter 108190075Sobrien#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ 108290075Sobrien && W_TYPE_SIZE == 64 108390075Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 108490075Sobrien __asm__ ("addcc %r4,%5,%1\n\t" \ 108590075Sobrien "add %r2,%3,%0\n\t" \ 108690075Sobrien "bcs,a,pn %%xcc, 1f\n\t" \ 108790075Sobrien "add %0, 1, %0\n" \ 108890075Sobrien "1:" \ 1089263763Sdim : "=r" (sh), \ 1090263763Sdim "=&r" (sl) \ 109190075Sobrien : "%rJ" ((UDItype)(ah)), \ 109290075Sobrien "rI" ((UDItype)(bh)), \ 109390075Sobrien "%rJ" ((UDItype)(al)), \ 109490075Sobrien "rI" ((UDItype)(bl)) \ 109590075Sobrien __CLOBBER_CC) 109690075Sobrien 109790075Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 109890075Sobrien __asm__ ("subcc %r4,%5,%1\n\t" \ 109990075Sobrien "sub %r2,%3,%0\n\t" \ 110090075Sobrien "bcs,a,pn %%xcc, 1f\n\t" \ 110190075Sobrien "sub %0, 1, %0\n\t" \ 110290075Sobrien "1:" \ 1103263763Sdim : "=r" (sh), \ 1104263763Sdim "=&r" (sl) \ 110590075Sobrien : "rJ" ((UDItype)(ah)), \ 110690075Sobrien "rI" ((UDItype)(bh)), \ 110790075Sobrien "rJ" ((UDItype)(al)), \ 110890075Sobrien "rI" ((UDItype)(bl)) \ 110990075Sobrien __CLOBBER_CC) 111090075Sobrien 111190075Sobrien#define umul_ppmm(wh, wl, u, v) \ 111290075Sobrien do { \ 111390075Sobrien UDItype tmp1, tmp2, tmp3, tmp4; \ 111490075Sobrien __asm__ __volatile__ ( \ 111590075Sobrien "srl %7,0,%3\n\t" \ 111690075Sobrien "mulx %3,%6,%1\n\t" \ 111790075Sobrien "srlx %6,32,%2\n\t" \ 111890075Sobrien "mulx %2,%3,%4\n\t" \ 111990075Sobrien "sllx %4,32,%5\n\t" \ 112090075Sobrien "srl %6,0,%3\n\t" \ 112190075Sobrien "sub %1,%5,%5\n\t" \ 112290075Sobrien "srlx %5,32,%5\n\t" \ 112390075Sobrien "addcc %4,%5,%4\n\t" \ 112490075Sobrien "srlx %7,32,%5\n\t" \ 112590075Sobrien "mulx %3,%5,%3\n\t" \ 112690075Sobrien "mulx %2,%5,%5\n\t" \ 112790075Sobrien "sethi %%hi(0x80000000),%2\n\t" \ 112890075Sobrien "addcc %4,%3,%4\n\t" \ 112990075Sobrien "srlx %4,32,%4\n\t" \ 113090075Sobrien "add %2,%2,%2\n\t" \ 113190075Sobrien "movcc %%xcc,%%g0,%2\n\t" \ 113290075Sobrien "addcc %5,%4,%5\n\t" \ 113390075Sobrien "sllx %3,32,%3\n\t" \ 113490075Sobrien "add %1,%3,%1\n\t" \ 113590075Sobrien "add %5,%2,%0" \ 1136263763Sdim : "=r" (wh), \ 1137263763Sdim "=&r" (wl), \ 113890075Sobrien "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ 113990075Sobrien : "r" ((UDItype)(u)), \ 114090075Sobrien "r" ((UDItype)(v)) \ 114190075Sobrien __CLOBBER_CC); \ 114290075Sobrien } while (0) 114390075Sobrien#define UMUL_TIME 96 114490075Sobrien#define UDIV_TIME 230 114590075Sobrien#endif /* sparc64 */ 114690075Sobrien 114790075Sobrien#if defined (__vax__) && W_TYPE_SIZE == 32 114818334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 114990075Sobrien __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ 115050397Sobrien : "=g" ((USItype) (sh)), \ 115150397Sobrien "=&g" ((USItype) (sl)) \ 115250397Sobrien : "%0" ((USItype) (ah)), \ 115350397Sobrien "g" ((USItype) (bh)), \ 115450397Sobrien "%1" ((USItype) (al)), \ 115550397Sobrien "g" ((USItype) (bl))) 115618334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 115790075Sobrien __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ 115850397Sobrien : "=g" ((USItype) (sh)), \ 115950397Sobrien "=&g" ((USItype) (sl)) \ 116050397Sobrien : "0" ((USItype) (ah)), \ 116150397Sobrien "g" ((USItype) (bh)), \ 116250397Sobrien "1" ((USItype) (al)), \ 116350397Sobrien "g" ((USItype) (bl))) 116418334Speter#define umul_ppmm(xh, xl, m0, m1) \ 116518334Speter do { \ 116618334Speter union { \ 116718334Speter UDItype __ll; \ 116818334Speter struct {USItype __l, __h;} __i; \ 116918334Speter } __xx; \ 117018334Speter USItype __m0 = (m0), __m1 = (m1); \ 117118334Speter __asm__ ("emul %1,%2,$0,%0" \ 117218334Speter : "=r" (__xx.__ll) \ 117318334Speter : "g" (__m0), \ 117418334Speter "g" (__m1)); \ 117518334Speter (xh) = __xx.__i.__h; \ 117618334Speter (xl) = __xx.__i.__l; \ 117718334Speter (xh) += ((((SItype) __m0 >> 31) & __m1) \ 117818334Speter + (((SItype) __m1 >> 31) & __m0)); \ 117918334Speter } while (0) 118018334Speter#define sdiv_qrnnd(q, r, n1, n0, d) \ 118118334Speter do { \ 118218334Speter union {DItype __ll; \ 118318334Speter struct {SItype __l, __h;} __i; \ 118418334Speter } __xx; \ 118518334Speter __xx.__i.__h = n1; __xx.__i.__l = n0; \ 118618334Speter __asm__ ("ediv %3,%2,%0,%1" \ 118718334Speter : "=g" (q), "=g" (r) \ 118818334Speter : "g" (__xx.__ll), "g" (d)); \ 118918334Speter } while (0) 119018334Speter#endif /* __vax__ */ 119118334Speter 119290075Sobrien#if defined (__z8000__) && W_TYPE_SIZE == 16 119390075Sobrien#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 119490075Sobrien __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ 119590075Sobrien : "=r" ((unsigned int)(sh)), \ 119690075Sobrien "=&r" ((unsigned int)(sl)) \ 119790075Sobrien : "%0" ((unsigned int)(ah)), \ 119890075Sobrien "r" ((unsigned int)(bh)), \ 119990075Sobrien "%1" ((unsigned int)(al)), \ 120090075Sobrien "rQR" ((unsigned int)(bl))) 120190075Sobrien#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 120290075Sobrien __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ 120390075Sobrien : "=r" ((unsigned int)(sh)), \ 120490075Sobrien "=&r" ((unsigned int)(sl)) \ 120590075Sobrien : "0" ((unsigned int)(ah)), \ 120690075Sobrien "r" ((unsigned int)(bh)), \ 120790075Sobrien "1" ((unsigned int)(al)), \ 120890075Sobrien "rQR" ((unsigned int)(bl))) 120990075Sobrien#define umul_ppmm(xh, xl, m0, m1) \ 121090075Sobrien do { \ 121190075Sobrien union {long int __ll; \ 121290075Sobrien struct {unsigned int __h, __l;} __i; \ 121390075Sobrien } __xx; \ 121490075Sobrien unsigned int __m0 = (m0), __m1 = (m1); \ 121590075Sobrien __asm__ ("mult %S0,%H3" \ 121690075Sobrien : "=r" (__xx.__i.__h), \ 121790075Sobrien "=r" (__xx.__i.__l) \ 121890075Sobrien : "%1" (__m0), \ 121990075Sobrien "rQR" (__m1)); \ 122090075Sobrien (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ 122190075Sobrien (xh) += ((((signed int) __m0 >> 15) & __m1) \ 122290075Sobrien + (((signed int) __m1 >> 15) & __m0)); \ 122390075Sobrien } while (0) 122490075Sobrien#endif /* __z8000__ */ 122590075Sobrien 122618334Speter#endif /* __GNUC__ */ 122718334Speter 122818334Speter/* If this machine has no inline assembler, use C macros. */ 122918334Speter 123018334Speter#if !defined (add_ssaaaa) 123118334Speter#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 123218334Speter do { \ 123390075Sobrien UWtype __x; \ 123418334Speter __x = (al) + (bl); \ 123518334Speter (sh) = (ah) + (bh) + (__x < (al)); \ 123618334Speter (sl) = __x; \ 123718334Speter } while (0) 123818334Speter#endif 123918334Speter 124018334Speter#if !defined (sub_ddmmss) 124118334Speter#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 124218334Speter do { \ 124390075Sobrien UWtype __x; \ 124418334Speter __x = (al) - (bl); \ 124518334Speter (sh) = (ah) - (bh) - (__x > (al)); \ 124618334Speter (sl) = __x; \ 124718334Speter } while (0) 124818334Speter#endif 124918334Speter 1250117395Skan/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of 1251117395Skan smul_ppmm. */ 1252117395Skan#if !defined (umul_ppmm) && defined (smul_ppmm) 1253117395Skan#define umul_ppmm(w1, w0, u, v) \ 1254117395Skan do { \ 1255117395Skan UWtype __w1; \ 1256117395Skan UWtype __xm0 = (u), __xm1 = (v); \ 1257117395Skan smul_ppmm (__w1, w0, __xm0, __xm1); \ 1258117395Skan (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ 1259117395Skan + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ 1260117395Skan } while (0) 1261117395Skan#endif 1262117395Skan 1263117395Skan/* If we still don't have umul_ppmm, define it using plain C. */ 126418334Speter#if !defined (umul_ppmm) 126518334Speter#define umul_ppmm(w1, w0, u, v) \ 126618334Speter do { \ 126790075Sobrien UWtype __x0, __x1, __x2, __x3; \ 126890075Sobrien UHWtype __ul, __vl, __uh, __vh; \ 126918334Speter \ 127018334Speter __ul = __ll_lowpart (u); \ 127118334Speter __uh = __ll_highpart (u); \ 127218334Speter __vl = __ll_lowpart (v); \ 127318334Speter __vh = __ll_highpart (v); \ 127418334Speter \ 127590075Sobrien __x0 = (UWtype) __ul * __vl; \ 127690075Sobrien __x1 = (UWtype) __ul * __vh; \ 127790075Sobrien __x2 = (UWtype) __uh * __vl; \ 127890075Sobrien __x3 = (UWtype) __uh * __vh; \ 127918334Speter \ 128018334Speter __x1 += __ll_highpart (__x0);/* this can't give carry */ \ 128118334Speter __x1 += __x2; /* but this indeed can */ \ 128218334Speter if (__x1 < __x2) /* did we get it? */ \ 128390075Sobrien __x3 += __ll_B; /* yes, add it in the proper pos. */ \ 128418334Speter \ 128518334Speter (w1) = __x3 + __ll_highpart (__x1); \ 128618334Speter (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ 128718334Speter } while (0) 128818334Speter#endif 128918334Speter 129018334Speter#if !defined (__umulsidi3) 129118334Speter#define __umulsidi3(u, v) \ 129290075Sobrien ({DWunion __w; \ 129318334Speter umul_ppmm (__w.s.high, __w.s.low, u, v); \ 129418334Speter __w.ll; }) 129518334Speter#endif 129618334Speter 129718334Speter/* Define this unconditionally, so it can be used for debugging. */ 129818334Speter#define __udiv_qrnnd_c(q, r, n1, n0, d) \ 129918334Speter do { \ 130090075Sobrien UWtype __d1, __d0, __q1, __q0; \ 130190075Sobrien UWtype __r1, __r0, __m; \ 130218334Speter __d1 = __ll_highpart (d); \ 130318334Speter __d0 = __ll_lowpart (d); \ 130418334Speter \ 130518334Speter __r1 = (n1) % __d1; \ 130618334Speter __q1 = (n1) / __d1; \ 130790075Sobrien __m = (UWtype) __q1 * __d0; \ 130818334Speter __r1 = __r1 * __ll_B | __ll_highpart (n0); \ 130918334Speter if (__r1 < __m) \ 131018334Speter { \ 131118334Speter __q1--, __r1 += (d); \ 131218334Speter if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ 131318334Speter if (__r1 < __m) \ 131418334Speter __q1--, __r1 += (d); \ 131518334Speter } \ 131618334Speter __r1 -= __m; \ 131718334Speter \ 131818334Speter __r0 = __r1 % __d1; \ 131918334Speter __q0 = __r1 / __d1; \ 132090075Sobrien __m = (UWtype) __q0 * __d0; \ 132118334Speter __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ 132218334Speter if (__r0 < __m) \ 132318334Speter { \ 132418334Speter __q0--, __r0 += (d); \ 132518334Speter if (__r0 >= (d)) \ 132618334Speter if (__r0 < __m) \ 132718334Speter __q0--, __r0 += (d); \ 132818334Speter } \ 132918334Speter __r0 -= __m; \ 133018334Speter \ 133190075Sobrien (q) = (UWtype) __q1 * __ll_B | __q0; \ 133218334Speter (r) = __r0; \ 133318334Speter } while (0) 133418334Speter 133518334Speter/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through 133618334Speter __udiv_w_sdiv (defined in libgcc or elsewhere). */ 133718334Speter#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) 133818334Speter#define udiv_qrnnd(q, r, nh, nl, d) \ 133918334Speter do { \ 134018334Speter USItype __r; \ 134118334Speter (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ 134218334Speter (r) = __r; \ 134318334Speter } while (0) 134418334Speter#endif 134518334Speter 134618334Speter/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ 134718334Speter#if !defined (udiv_qrnnd) 134818334Speter#define UDIV_NEEDS_NORMALIZATION 1 134918334Speter#define udiv_qrnnd __udiv_qrnnd_c 135018334Speter#endif 135118334Speter 135218334Speter#if !defined (count_leading_zeros) 135318334Speter#define count_leading_zeros(count, x) \ 135418334Speter do { \ 135590075Sobrien UWtype __xr = (x); \ 135690075Sobrien UWtype __a; \ 135718334Speter \ 135890075Sobrien if (W_TYPE_SIZE <= 32) \ 135918334Speter { \ 136090075Sobrien __a = __xr < ((UWtype)1<<2*__BITS4) \ 136190075Sobrien ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ 136290075Sobrien : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ 136318334Speter } \ 136418334Speter else \ 136518334Speter { \ 136690075Sobrien for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ 136718334Speter if (((__xr >> __a) & 0xff) != 0) \ 136818334Speter break; \ 136918334Speter } \ 137018334Speter \ 137190075Sobrien (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ 137218334Speter } while (0) 137390075Sobrien#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE 137418334Speter#endif 137518334Speter 137690075Sobrien#if !defined (count_trailing_zeros) 137790075Sobrien/* Define count_trailing_zeros using count_leading_zeros. The latter might be 137890075Sobrien defined in asm, but if it is not, the C version above is good enough. */ 137990075Sobrien#define count_trailing_zeros(count, x) \ 138090075Sobrien do { \ 138190075Sobrien UWtype __ctz_x = (x); \ 138290075Sobrien UWtype __ctz_c; \ 138390075Sobrien count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ 138490075Sobrien (count) = W_TYPE_SIZE - 1 - __ctz_c; \ 138590075Sobrien } while (0) 138690075Sobrien#endif 138790075Sobrien 138818334Speter#ifndef UDIV_NEEDS_NORMALIZATION 138918334Speter#define UDIV_NEEDS_NORMALIZATION 0 139018334Speter#endif 1391