175fd0b74Schristos /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. 2*e992f068Schristos Copyright (C) 1991-2022 Free Software Foundation, Inc. 375fd0b74Schristos 475fd0b74Schristos This file is part of the GNU C Library. 575fd0b74Schristos 675fd0b74Schristos The GNU C Library is free software; you can redistribute it and/or 775fd0b74Schristos modify it under the terms of the GNU Lesser General Public 875fd0b74Schristos License as published by the Free Software Foundation; either 975fd0b74Schristos version 2.1 of the License, or (at your option) any later version. 1075fd0b74Schristos 1175fd0b74Schristos In addition to the permissions in the GNU Lesser General Public 1275fd0b74Schristos License, the Free Software Foundation gives you unlimited 1375fd0b74Schristos permission to link the compiled version of this file into 1475fd0b74Schristos combinations with other programs, and to distribute those 1575fd0b74Schristos combinations without any restriction coming from the use of this 1675fd0b74Schristos file. (The Lesser General Public License restrictions do apply in 1775fd0b74Schristos other respects; for example, they cover modification of the file, 1875fd0b74Schristos and distribution when not linked into a combine executable.) 1975fd0b74Schristos 2075fd0b74Schristos The GNU C Library is distributed in the hope that it will be useful, 2175fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 2275fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2375fd0b74Schristos Lesser General Public License for more details. 2475fd0b74Schristos 2575fd0b74Schristos You should have received a copy of the GNU Lesser General Public 2675fd0b74Schristos License along with the GNU C Library; if not, see 2775fd0b74Schristos <http://www.gnu.org/licenses/>. */ 2875fd0b74Schristos 2975fd0b74Schristos /* You have to define the following before including this file: 3075fd0b74Schristos 3175fd0b74Schristos UWtype -- An unsigned type, default type for operations (typically a "word") 3275fd0b74Schristos UHWtype -- An unsigned type, at least half the size of UWtype. 3375fd0b74Schristos UDWtype -- An unsigned type, at least twice as large a UWtype 3475fd0b74Schristos W_TYPE_SIZE -- size in bits of UWtype 3575fd0b74Schristos 3675fd0b74Schristos UQItype -- Unsigned 8 bit type. 3775fd0b74Schristos SItype, USItype -- Signed and unsigned 32 bit types. 3875fd0b74Schristos DItype, UDItype -- Signed and unsigned 64 bit types. 3975fd0b74Schristos 4075fd0b74Schristos On a 32 bit machine UWtype should typically be USItype; 4175fd0b74Schristos on a 64 bit machine, UWtype should typically be UDItype. */ 4275fd0b74Schristos 4375fd0b74Schristos #define __BITS4 (W_TYPE_SIZE / 4) 4475fd0b74Schristos #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) 4575fd0b74Schristos #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) 4675fd0b74Schristos #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) 4775fd0b74Schristos 4875fd0b74Schristos #ifndef W_TYPE_SIZE 4975fd0b74Schristos #define W_TYPE_SIZE 32 5075fd0b74Schristos #define UWtype USItype 5175fd0b74Schristos #define UHWtype USItype 5275fd0b74Schristos #define UDWtype UDItype 5375fd0b74Schristos #endif 5475fd0b74Schristos 5575fd0b74Schristos /* Used in glibc only. */ 5675fd0b74Schristos #ifndef attribute_hidden 5775fd0b74Schristos #define attribute_hidden 5875fd0b74Schristos #endif 5975fd0b74Schristos 6075fd0b74Schristos extern const UQItype __clz_tab[256] attribute_hidden; 6175fd0b74Schristos 6275fd0b74Schristos /* Define auxiliary asm macros. 6375fd0b74Schristos 6475fd0b74Schristos 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two 6575fd0b74Schristos UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype 6675fd0b74Schristos word product in HIGH_PROD and LOW_PROD. 6775fd0b74Schristos 6875fd0b74Schristos 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a 6975fd0b74Schristos UDWtype product. This is just a variant of umul_ppmm. 7075fd0b74Schristos 7175fd0b74Schristos 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 7275fd0b74Schristos denominator) divides a UDWtype, composed by the UWtype integers 7375fd0b74Schristos HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient 7475fd0b74Schristos in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less 7575fd0b74Schristos than DENOMINATOR for correct operation. If, in addition, the most 7675fd0b74Schristos significant bit of DENOMINATOR must be 1, then the pre-processor symbol 7775fd0b74Schristos UDIV_NEEDS_NORMALIZATION is defined to 1. 7875fd0b74Schristos 7975fd0b74Schristos 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 8075fd0b74Schristos denominator). Like udiv_qrnnd but the numbers are signed. The quotient 8175fd0b74Schristos is rounded towards 0. 8275fd0b74Schristos 8375fd0b74Schristos 5) count_leading_zeros(count, x) counts the number of zero-bits from the 8475fd0b74Schristos msb to the first nonzero bit in the UWtype X. This is the number of 8575fd0b74Schristos steps X needs to be shifted left to set the msb. Undefined for X == 0, 8675fd0b74Schristos unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. 8775fd0b74Schristos 8875fd0b74Schristos 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts 8975fd0b74Schristos from the least significant end. 9075fd0b74Schristos 9175fd0b74Schristos 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, 9275fd0b74Schristos high_addend_2, low_addend_2) adds two UWtype integers, composed by 9375fd0b74Schristos HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 9475fd0b74Schristos respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow 9575fd0b74Schristos (i.e. carry out) is not stored anywhere, and is lost. 9675fd0b74Schristos 9775fd0b74Schristos 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, 9875fd0b74Schristos high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, 9975fd0b74Schristos composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and 10075fd0b74Schristos LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE 10175fd0b74Schristos and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, 10275fd0b74Schristos and is lost. 10375fd0b74Schristos 10475fd0b74Schristos If any of these macros are left undefined for a particular CPU, 10575fd0b74Schristos C macros are used. */ 10675fd0b74Schristos 10775fd0b74Schristos /* The CPUs come in alphabetical order below. 10875fd0b74Schristos 10975fd0b74Schristos Please add support for more CPUs here, or improve the current support 11075fd0b74Schristos for the CPUs below! 11175fd0b74Schristos (E.g. WE32100, IBM360.) */ 11275fd0b74Schristos 11375fd0b74Schristos #if defined (__GNUC__) && !defined (NO_ASM) 11475fd0b74Schristos 11575fd0b74Schristos /* We sometimes need to clobber "cc" with gcc2, but that would not be 11675fd0b74Schristos understood by gcc1. Use cpp to avoid major code duplication. */ 11775fd0b74Schristos #if __GNUC__ < 2 11875fd0b74Schristos #define __CLOBBER_CC 11975fd0b74Schristos #define __AND_CLOBBER_CC 12075fd0b74Schristos #else /* __GNUC__ >= 2 */ 12175fd0b74Schristos #define __CLOBBER_CC : "cc" 12275fd0b74Schristos #define __AND_CLOBBER_CC , "cc" 12375fd0b74Schristos #endif /* __GNUC__ < 2 */ 12475fd0b74Schristos 12575fd0b74Schristos #if defined (__aarch64__) 12675fd0b74Schristos 12775fd0b74Schristos #if W_TYPE_SIZE == 32 12875fd0b74Schristos #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) 12975fd0b74Schristos #define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) 13075fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 13175fd0b74Schristos #endif /* W_TYPE_SIZE == 32 */ 13275fd0b74Schristos 13375fd0b74Schristos #if W_TYPE_SIZE == 64 13475fd0b74Schristos #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clzll (X)) 13575fd0b74Schristos #define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctzll (X)) 13675fd0b74Schristos #define COUNT_LEADING_ZEROS_0 64 13775fd0b74Schristos #endif /* W_TYPE_SIZE == 64 */ 13875fd0b74Schristos 13975fd0b74Schristos #endif /* __aarch64__ */ 14075fd0b74Schristos 14175fd0b74Schristos #if defined (__alpha) && W_TYPE_SIZE == 64 14275fd0b74Schristos /* There is a bug in g++ before version 5 that 14375fd0b74Schristos errors on __builtin_alpha_umulh. */ 14475fd0b74Schristos #if !defined(__cplusplus) || __GNUC__ >= 5 14575fd0b74Schristos #define umul_ppmm(ph, pl, m0, m1) \ 14675fd0b74Schristos do { \ 14775fd0b74Schristos UDItype __m0 = (m0), __m1 = (m1); \ 14875fd0b74Schristos (ph) = __builtin_alpha_umulh (__m0, __m1); \ 14975fd0b74Schristos (pl) = __m0 * __m1; \ 15075fd0b74Schristos } while (0) 15175fd0b74Schristos #define UMUL_TIME 46 15275fd0b74Schristos #endif /* !c++ */ 15375fd0b74Schristos #ifndef LONGLONG_STANDALONE 15475fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, d) \ 15575fd0b74Schristos do { UDItype __r; \ 15675fd0b74Schristos (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ 15775fd0b74Schristos (r) = __r; \ 15875fd0b74Schristos } while (0) 15975fd0b74Schristos extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); 16075fd0b74Schristos #define UDIV_TIME 220 16175fd0b74Schristos #endif /* LONGLONG_STANDALONE */ 16275fd0b74Schristos #ifdef __alpha_cix__ 16375fd0b74Schristos #define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) 16475fd0b74Schristos #define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) 16575fd0b74Schristos #define COUNT_LEADING_ZEROS_0 64 16675fd0b74Schristos #else 16775fd0b74Schristos #define count_leading_zeros(COUNT,X) \ 16875fd0b74Schristos do { \ 16975fd0b74Schristos UDItype __xr = (X), __t, __a; \ 17075fd0b74Schristos __t = __builtin_alpha_cmpbge (0, __xr); \ 17175fd0b74Schristos __a = __clz_tab[__t ^ 0xff] - 1; \ 17275fd0b74Schristos __t = __builtin_alpha_extbl (__xr, __a); \ 17375fd0b74Schristos (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ 17475fd0b74Schristos } while (0) 17575fd0b74Schristos #define count_trailing_zeros(COUNT,X) \ 17675fd0b74Schristos do { \ 17775fd0b74Schristos UDItype __xr = (X), __t, __a; \ 17875fd0b74Schristos __t = __builtin_alpha_cmpbge (0, __xr); \ 17975fd0b74Schristos __t = ~__t & -~__t; \ 18075fd0b74Schristos __a = ((__t & 0xCC) != 0) * 2; \ 18175fd0b74Schristos __a += ((__t & 0xF0) != 0) * 4; \ 18275fd0b74Schristos __a += ((__t & 0xAA) != 0); \ 18375fd0b74Schristos __t = __builtin_alpha_extbl (__xr, __a); \ 18475fd0b74Schristos __a <<= 3; \ 18575fd0b74Schristos __t &= -__t; \ 18675fd0b74Schristos __a += ((__t & 0xCC) != 0) * 2; \ 18775fd0b74Schristos __a += ((__t & 0xF0) != 0) * 4; \ 18875fd0b74Schristos __a += ((__t & 0xAA) != 0); \ 18975fd0b74Schristos (COUNT) = __a; \ 19075fd0b74Schristos } while (0) 19175fd0b74Schristos #endif /* __alpha_cix__ */ 19275fd0b74Schristos #endif /* __alpha */ 19375fd0b74Schristos 19475fd0b74Schristos #if defined (__arc__) && W_TYPE_SIZE == 32 19575fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 19675fd0b74Schristos __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ 19775fd0b74Schristos : "=r" ((USItype) (sh)), \ 19875fd0b74Schristos "=&r" ((USItype) (sl)) \ 19975fd0b74Schristos : "%r" ((USItype) (ah)), \ 200ede78133Schristos "rICal" ((USItype) (bh)), \ 20175fd0b74Schristos "%r" ((USItype) (al)), \ 202012573ebSchristos "rICal" ((USItype) (bl)) \ 203012573ebSchristos : "cc") 20475fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 20575fd0b74Schristos __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ 20675fd0b74Schristos : "=r" ((USItype) (sh)), \ 20775fd0b74Schristos "=&r" ((USItype) (sl)) \ 20875fd0b74Schristos : "r" ((USItype) (ah)), \ 209ede78133Schristos "rICal" ((USItype) (bh)), \ 21075fd0b74Schristos "r" ((USItype) (al)), \ 211012573ebSchristos "rICal" ((USItype) (bl)) \ 212012573ebSchristos : "cc") 21375fd0b74Schristos 21475fd0b74Schristos #define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) 21575fd0b74Schristos #ifdef __ARC_NORM__ 21675fd0b74Schristos #define count_leading_zeros(count, x) \ 21775fd0b74Schristos do \ 21875fd0b74Schristos { \ 21975fd0b74Schristos SItype c_; \ 22075fd0b74Schristos \ 22175fd0b74Schristos __asm__ ("norm.f\t%0,%1\n\tmov.mi\t%0,-1" : "=r" (c_) : "r" (x) : "cc");\ 22275fd0b74Schristos (count) = c_ + 1; \ 22375fd0b74Schristos } \ 22475fd0b74Schristos while (0) 22575fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 226ede78133Schristos #endif /* __ARC_NORM__ */ 227ede78133Schristos #endif /* __arc__ */ 22875fd0b74Schristos 22975fd0b74Schristos #if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \ 23075fd0b74Schristos && W_TYPE_SIZE == 32 23175fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 23275fd0b74Schristos __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ 23375fd0b74Schristos : "=r" ((USItype) (sh)), \ 23475fd0b74Schristos "=&r" ((USItype) (sl)) \ 23575fd0b74Schristos : "%r" ((USItype) (ah)), \ 23675fd0b74Schristos "rI" ((USItype) (bh)), \ 23775fd0b74Schristos "%r" ((USItype) (al)), \ 23875fd0b74Schristos "rI" ((USItype) (bl)) __CLOBBER_CC) 23975fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 24075fd0b74Schristos __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ 24175fd0b74Schristos : "=r" ((USItype) (sh)), \ 24275fd0b74Schristos "=&r" ((USItype) (sl)) \ 24375fd0b74Schristos : "r" ((USItype) (ah)), \ 24475fd0b74Schristos "rI" ((USItype) (bh)), \ 24575fd0b74Schristos "r" ((USItype) (al)), \ 24675fd0b74Schristos "rI" ((USItype) (bl)) __CLOBBER_CC) 24775fd0b74Schristos # if defined(__ARM_ARCH_2__) || defined(__ARM_ARCH_2A__) \ 24875fd0b74Schristos || defined(__ARM_ARCH_3__) 24975fd0b74Schristos # define umul_ppmm(xh, xl, a, b) \ 25075fd0b74Schristos do { \ 25175fd0b74Schristos register USItype __t0, __t1, __t2; \ 25275fd0b74Schristos __asm__ ("%@ Inlined umul_ppmm\n" \ 25375fd0b74Schristos " mov %2, %5, lsr #16\n" \ 25475fd0b74Schristos " mov %0, %6, lsr #16\n" \ 25575fd0b74Schristos " bic %3, %5, %2, lsl #16\n" \ 25675fd0b74Schristos " bic %4, %6, %0, lsl #16\n" \ 25775fd0b74Schristos " mul %1, %3, %4\n" \ 25875fd0b74Schristos " mul %4, %2, %4\n" \ 25975fd0b74Schristos " mul %3, %0, %3\n" \ 26075fd0b74Schristos " mul %0, %2, %0\n" \ 26175fd0b74Schristos " adds %3, %4, %3\n" \ 26275fd0b74Schristos " addcs %0, %0, #65536\n" \ 26375fd0b74Schristos " adds %1, %1, %3, lsl #16\n" \ 26475fd0b74Schristos " adc %0, %0, %3, lsr #16" \ 26575fd0b74Schristos : "=&r" ((USItype) (xh)), \ 26675fd0b74Schristos "=r" ((USItype) (xl)), \ 26775fd0b74Schristos "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ 26875fd0b74Schristos : "r" ((USItype) (a)), \ 26975fd0b74Schristos "r" ((USItype) (b)) __CLOBBER_CC ); \ 27075fd0b74Schristos } while (0) 27175fd0b74Schristos # define UMUL_TIME 20 27275fd0b74Schristos # else 27375fd0b74Schristos # define umul_ppmm(xh, xl, a, b) \ 27475fd0b74Schristos do { \ 27575fd0b74Schristos /* Generate umull, under compiler control. */ \ 27675fd0b74Schristos register UDItype __t0 = (UDItype)(USItype)(a) * (USItype)(b); \ 27775fd0b74Schristos (xl) = (USItype)__t0; \ 27875fd0b74Schristos (xh) = (USItype)(__t0 >> 32); \ 27975fd0b74Schristos } while (0) 28075fd0b74Schristos # define UMUL_TIME 3 28175fd0b74Schristos # endif 28275fd0b74Schristos # define UDIV_TIME 100 28375fd0b74Schristos #endif /* __arm__ */ 28475fd0b74Schristos 28575fd0b74Schristos #if defined(__arm__) 28675fd0b74Schristos /* Let gcc decide how best to implement count_leading_zeros. */ 28775fd0b74Schristos #define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) 28875fd0b74Schristos #define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X)) 28975fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 29075fd0b74Schristos #endif 29175fd0b74Schristos 29275fd0b74Schristos #if defined (__AVR__) 29375fd0b74Schristos 29475fd0b74Schristos #if W_TYPE_SIZE == 16 29575fd0b74Schristos #define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) 29675fd0b74Schristos #define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X)) 29775fd0b74Schristos #define COUNT_LEADING_ZEROS_0 16 29875fd0b74Schristos #endif /* W_TYPE_SIZE == 16 */ 29975fd0b74Schristos 30075fd0b74Schristos #if W_TYPE_SIZE == 32 30175fd0b74Schristos #define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) 30275fd0b74Schristos #define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) 30375fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 30475fd0b74Schristos #endif /* W_TYPE_SIZE == 32 */ 30575fd0b74Schristos 30675fd0b74Schristos #if W_TYPE_SIZE == 64 30775fd0b74Schristos #define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzll (X)) 30875fd0b74Schristos #define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzll (X)) 30975fd0b74Schristos #define COUNT_LEADING_ZEROS_0 64 31075fd0b74Schristos #endif /* W_TYPE_SIZE == 64 */ 31175fd0b74Schristos 31275fd0b74Schristos #endif /* defined (__AVR__) */ 31375fd0b74Schristos 31475fd0b74Schristos #if defined (__CRIS__) 31575fd0b74Schristos 31675fd0b74Schristos #if __CRIS_arch_version >= 3 31775fd0b74Schristos #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) 31875fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 31975fd0b74Schristos #endif /* __CRIS_arch_version >= 3 */ 32075fd0b74Schristos 32175fd0b74Schristos #if __CRIS_arch_version >= 8 32275fd0b74Schristos #define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) 32375fd0b74Schristos #endif /* __CRIS_arch_version >= 8 */ 32475fd0b74Schristos 32575fd0b74Schristos #if __CRIS_arch_version >= 10 32675fd0b74Schristos #define __umulsidi3(u,v) ((UDItype)(USItype) (u) * (UDItype)(USItype) (v)) 32775fd0b74Schristos #else 32875fd0b74Schristos #define __umulsidi3 __umulsidi3 32975fd0b74Schristos extern UDItype __umulsidi3 (USItype, USItype); 33075fd0b74Schristos #endif /* __CRIS_arch_version >= 10 */ 33175fd0b74Schristos 33275fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 33375fd0b74Schristos do { \ 33475fd0b74Schristos UDItype __x = __umulsidi3 (u, v); \ 33575fd0b74Schristos (w0) = (USItype) (__x); \ 33675fd0b74Schristos (w1) = (USItype) (__x >> 32); \ 33775fd0b74Schristos } while (0) 33875fd0b74Schristos 33975fd0b74Schristos /* FIXME: defining add_ssaaaa and sub_ddmmss should be advantageous for 34075fd0b74Schristos DFmode ("double" intrinsics, avoiding two of the three insns handling 34175fd0b74Schristos carry), but defining them as open-code C composing and doing the 34275fd0b74Schristos operation in DImode (UDImode) shows that the DImode needs work: 34375fd0b74Schristos register pressure from requiring neighboring registers and the 34475fd0b74Schristos traffic to and from them come to dominate, in the 4.7 series. */ 34575fd0b74Schristos 34675fd0b74Schristos #endif /* defined (__CRIS__) */ 34775fd0b74Schristos 34875fd0b74Schristos #if defined (__hppa) && W_TYPE_SIZE == 32 34975fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 35075fd0b74Schristos __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ 35175fd0b74Schristos : "=r" ((USItype) (sh)), \ 35275fd0b74Schristos "=&r" ((USItype) (sl)) \ 35375fd0b74Schristos : "%rM" ((USItype) (ah)), \ 35475fd0b74Schristos "rM" ((USItype) (bh)), \ 35575fd0b74Schristos "%rM" ((USItype) (al)), \ 35675fd0b74Schristos "rM" ((USItype) (bl))) 35775fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 35875fd0b74Schristos __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ 35975fd0b74Schristos : "=r" ((USItype) (sh)), \ 36075fd0b74Schristos "=&r" ((USItype) (sl)) \ 36175fd0b74Schristos : "rM" ((USItype) (ah)), \ 36275fd0b74Schristos "rM" ((USItype) (bh)), \ 36375fd0b74Schristos "rM" ((USItype) (al)), \ 36475fd0b74Schristos "rM" ((USItype) (bl))) 36575fd0b74Schristos #if defined (_PA_RISC1_1) 36675fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 36775fd0b74Schristos do { \ 36875fd0b74Schristos union \ 36975fd0b74Schristos { \ 37075fd0b74Schristos UDItype __f; \ 37175fd0b74Schristos struct {USItype __w1, __w0;} __w1w0; \ 37275fd0b74Schristos } __t; \ 37375fd0b74Schristos __asm__ ("xmpyu %1,%2,%0" \ 37475fd0b74Schristos : "=x" (__t.__f) \ 37575fd0b74Schristos : "x" ((USItype) (u)), \ 37675fd0b74Schristos "x" ((USItype) (v))); \ 37775fd0b74Schristos (w1) = __t.__w1w0.__w1; \ 37875fd0b74Schristos (w0) = __t.__w1w0.__w0; \ 37975fd0b74Schristos } while (0) 38075fd0b74Schristos #define UMUL_TIME 8 38175fd0b74Schristos #else 38275fd0b74Schristos #define UMUL_TIME 30 38375fd0b74Schristos #endif 38475fd0b74Schristos #define UDIV_TIME 40 38575fd0b74Schristos #define count_leading_zeros(count, x) \ 38675fd0b74Schristos do { \ 38775fd0b74Schristos USItype __tmp; \ 38875fd0b74Schristos __asm__ ( \ 38975fd0b74Schristos "ldi 1,%0\n" \ 39075fd0b74Schristos " extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ 39175fd0b74Schristos " extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ 39275fd0b74Schristos " ldo 16(%0),%0 ; Yes. Perform add.\n" \ 39375fd0b74Schristos " extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ 39475fd0b74Schristos " extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ 39575fd0b74Schristos " ldo 8(%0),%0 ; Yes. Perform add.\n" \ 39675fd0b74Schristos " extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ 39775fd0b74Schristos " extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ 39875fd0b74Schristos " ldo 4(%0),%0 ; Yes. Perform add.\n" \ 39975fd0b74Schristos " extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ 40075fd0b74Schristos " extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ 40175fd0b74Schristos " ldo 2(%0),%0 ; Yes. Perform add.\n" \ 40275fd0b74Schristos " extru %1,30,1,%1 ; Extract bit 1.\n" \ 40375fd0b74Schristos " sub %0,%1,%0 ; Subtract it.\n" \ 40475fd0b74Schristos : "=r" (count), "=r" (__tmp) : "1" (x)); \ 40575fd0b74Schristos } while (0) 40675fd0b74Schristos #endif 40775fd0b74Schristos 40875fd0b74Schristos #if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 40975fd0b74Schristos #if !defined (__zarch__) 41075fd0b74Schristos #define smul_ppmm(xh, xl, m0, m1) \ 41175fd0b74Schristos do { \ 41275fd0b74Schristos union {DItype __ll; \ 41375fd0b74Schristos struct {USItype __h, __l;} __i; \ 41475fd0b74Schristos } __x; \ 41575fd0b74Schristos __asm__ ("lr %N0,%1\n\tmr %0,%2" \ 41675fd0b74Schristos : "=&r" (__x.__ll) \ 41775fd0b74Schristos : "r" (m0), "r" (m1)); \ 41875fd0b74Schristos (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ 41975fd0b74Schristos } while (0) 42075fd0b74Schristos #define sdiv_qrnnd(q, r, n1, n0, d) \ 42175fd0b74Schristos do { \ 42275fd0b74Schristos union {DItype __ll; \ 42375fd0b74Schristos struct {USItype __h, __l;} __i; \ 42475fd0b74Schristos } __x; \ 42575fd0b74Schristos __x.__i.__h = n1; __x.__i.__l = n0; \ 42675fd0b74Schristos __asm__ ("dr %0,%2" \ 42775fd0b74Schristos : "=r" (__x.__ll) \ 42875fd0b74Schristos : "0" (__x.__ll), "r" (d)); \ 42975fd0b74Schristos (q) = __x.__i.__l; (r) = __x.__i.__h; \ 43075fd0b74Schristos } while (0) 43175fd0b74Schristos #else 43275fd0b74Schristos #define smul_ppmm(xh, xl, m0, m1) \ 43375fd0b74Schristos do { \ 43475fd0b74Schristos register SItype __r0 __asm__ ("0"); \ 43575fd0b74Schristos register SItype __r1 __asm__ ("1") = (m0); \ 43675fd0b74Schristos \ 43775fd0b74Schristos __asm__ ("mr\t%%r0,%3" \ 43875fd0b74Schristos : "=r" (__r0), "=r" (__r1) \ 43975fd0b74Schristos : "r" (__r1), "r" (m1)); \ 44075fd0b74Schristos (xh) = __r0; (xl) = __r1; \ 44175fd0b74Schristos } while (0) 44275fd0b74Schristos 44375fd0b74Schristos #define sdiv_qrnnd(q, r, n1, n0, d) \ 44475fd0b74Schristos do { \ 44575fd0b74Schristos register SItype __r0 __asm__ ("0") = (n1); \ 44675fd0b74Schristos register SItype __r1 __asm__ ("1") = (n0); \ 44775fd0b74Schristos \ 44875fd0b74Schristos __asm__ ("dr\t%%r0,%4" \ 44975fd0b74Schristos : "=r" (__r0), "=r" (__r1) \ 45075fd0b74Schristos : "r" (__r0), "r" (__r1), "r" (d)); \ 45175fd0b74Schristos (q) = __r1; (r) = __r0; \ 45275fd0b74Schristos } while (0) 45375fd0b74Schristos #endif /* __zarch__ */ 45475fd0b74Schristos #endif 45575fd0b74Schristos 45675fd0b74Schristos #if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 45775fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 45875fd0b74Schristos __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ 45975fd0b74Schristos : "=r" ((USItype) (sh)), \ 46075fd0b74Schristos "=&r" ((USItype) (sl)) \ 46175fd0b74Schristos : "%0" ((USItype) (ah)), \ 46275fd0b74Schristos "g" ((USItype) (bh)), \ 46375fd0b74Schristos "%1" ((USItype) (al)), \ 46475fd0b74Schristos "g" ((USItype) (bl))) 46575fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 46675fd0b74Schristos __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ 46775fd0b74Schristos : "=r" ((USItype) (sh)), \ 46875fd0b74Schristos "=&r" ((USItype) (sl)) \ 46975fd0b74Schristos : "0" ((USItype) (ah)), \ 47075fd0b74Schristos "g" ((USItype) (bh)), \ 47175fd0b74Schristos "1" ((USItype) (al)), \ 47275fd0b74Schristos "g" ((USItype) (bl))) 47375fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 47475fd0b74Schristos __asm__ ("mul{l} %3" \ 47575fd0b74Schristos : "=a" ((USItype) (w0)), \ 47675fd0b74Schristos "=d" ((USItype) (w1)) \ 47775fd0b74Schristos : "%0" ((USItype) (u)), \ 47875fd0b74Schristos "rm" ((USItype) (v))) 47975fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, dv) \ 48075fd0b74Schristos __asm__ ("div{l} %4" \ 48175fd0b74Schristos : "=a" ((USItype) (q)), \ 48275fd0b74Schristos "=d" ((USItype) (r)) \ 48375fd0b74Schristos : "0" ((USItype) (n0)), \ 48475fd0b74Schristos "1" ((USItype) (n1)), \ 48575fd0b74Schristos "rm" ((USItype) (dv))) 48675fd0b74Schristos #define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) 48775fd0b74Schristos #define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) 48875fd0b74Schristos #define UMUL_TIME 40 48975fd0b74Schristos #define UDIV_TIME 40 49075fd0b74Schristos #endif /* 80x86 */ 49175fd0b74Schristos 49275fd0b74Schristos #if defined (__x86_64__) && W_TYPE_SIZE == 64 49375fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 49475fd0b74Schristos __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}" \ 49575fd0b74Schristos : "=r" ((UDItype) (sh)), \ 49675fd0b74Schristos "=&r" ((UDItype) (sl)) \ 49775fd0b74Schristos : "%0" ((UDItype) (ah)), \ 49875fd0b74Schristos "rme" ((UDItype) (bh)), \ 49975fd0b74Schristos "%1" ((UDItype) (al)), \ 50075fd0b74Schristos "rme" ((UDItype) (bl))) 50175fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 50275fd0b74Schristos __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}" \ 50375fd0b74Schristos : "=r" ((UDItype) (sh)), \ 50475fd0b74Schristos "=&r" ((UDItype) (sl)) \ 50575fd0b74Schristos : "0" ((UDItype) (ah)), \ 50675fd0b74Schristos "rme" ((UDItype) (bh)), \ 50775fd0b74Schristos "1" ((UDItype) (al)), \ 50875fd0b74Schristos "rme" ((UDItype) (bl))) 50975fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 51075fd0b74Schristos __asm__ ("mul{q} %3" \ 51175fd0b74Schristos : "=a" ((UDItype) (w0)), \ 51275fd0b74Schristos "=d" ((UDItype) (w1)) \ 51375fd0b74Schristos : "%0" ((UDItype) (u)), \ 51475fd0b74Schristos "rm" ((UDItype) (v))) 51575fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, dv) \ 51675fd0b74Schristos __asm__ ("div{q} %4" \ 51775fd0b74Schristos : "=a" ((UDItype) (q)), \ 51875fd0b74Schristos "=d" ((UDItype) (r)) \ 51975fd0b74Schristos : "0" ((UDItype) (n0)), \ 52075fd0b74Schristos "1" ((UDItype) (n1)), \ 52175fd0b74Schristos "rm" ((UDItype) (dv))) 52275fd0b74Schristos #define count_leading_zeros(count, x) ((count) = __builtin_clzll (x)) 52375fd0b74Schristos #define count_trailing_zeros(count, x) ((count) = __builtin_ctzll (x)) 52475fd0b74Schristos #define UMUL_TIME 40 52575fd0b74Schristos #define UDIV_TIME 40 52675fd0b74Schristos #endif /* x86_64 */ 52775fd0b74Schristos 52875fd0b74Schristos #if defined (__i960__) && W_TYPE_SIZE == 32 52975fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 53075fd0b74Schristos ({union {UDItype __ll; \ 53175fd0b74Schristos struct {USItype __l, __h;} __i; \ 53275fd0b74Schristos } __xx; \ 53375fd0b74Schristos __asm__ ("emul %2,%1,%0" \ 53475fd0b74Schristos : "=d" (__xx.__ll) \ 53575fd0b74Schristos : "%dI" ((USItype) (u)), \ 53675fd0b74Schristos "dI" ((USItype) (v))); \ 53775fd0b74Schristos (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) 53875fd0b74Schristos #define __umulsidi3(u, v) \ 53975fd0b74Schristos ({UDItype __w; \ 54075fd0b74Schristos __asm__ ("emul %2,%1,%0" \ 54175fd0b74Schristos : "=d" (__w) \ 54275fd0b74Schristos : "%dI" ((USItype) (u)), \ 54375fd0b74Schristos "dI" ((USItype) (v))); \ 54475fd0b74Schristos __w; }) 54575fd0b74Schristos #endif /* __i960__ */ 54675fd0b74Schristos 54775fd0b74Schristos #if defined (__ia64) && W_TYPE_SIZE == 64 54875fd0b74Schristos /* This form encourages gcc (pre-release 3.4 at least) to emit predicated 54975fd0b74Schristos "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic 55075fd0b74Schristos code using "al<bl" arithmetically comes out making an actual 0 or 1 in a 55175fd0b74Schristos register, which takes an extra cycle. */ 55275fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 55375fd0b74Schristos do { \ 55475fd0b74Schristos UWtype __x; \ 55575fd0b74Schristos __x = (al) - (bl); \ 55675fd0b74Schristos if ((al) < (bl)) \ 55775fd0b74Schristos (sh) = (ah) - (bh) - 1; \ 55875fd0b74Schristos else \ 55975fd0b74Schristos (sh) = (ah) - (bh); \ 56075fd0b74Schristos (sl) = __x; \ 56175fd0b74Schristos } while (0) 56275fd0b74Schristos 56375fd0b74Schristos /* Do both product parts in assembly, since that gives better code with 56475fd0b74Schristos all gcc versions. Some callers will just use the upper part, and in 56575fd0b74Schristos that situation we waste an instruction, but not any cycles. */ 56675fd0b74Schristos #define umul_ppmm(ph, pl, m0, m1) \ 56775fd0b74Schristos __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" \ 56875fd0b74Schristos : "=&f" (ph), "=f" (pl) \ 56975fd0b74Schristos : "f" (m0), "f" (m1)) 57075fd0b74Schristos #define count_leading_zeros(count, x) \ 57175fd0b74Schristos do { \ 57275fd0b74Schristos UWtype _x = (x), _y, _a, _c; \ 57375fd0b74Schristos __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x)); \ 57475fd0b74Schristos __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y)); \ 57575fd0b74Schristos _c = (_a - 1) << 3; \ 57675fd0b74Schristos _x >>= _c; \ 57775fd0b74Schristos if (_x >= 1 << 4) \ 57875fd0b74Schristos _x >>= 4, _c += 4; \ 57975fd0b74Schristos if (_x >= 1 << 2) \ 58075fd0b74Schristos _x >>= 2, _c += 2; \ 58175fd0b74Schristos _c += _x >> 1; \ 58275fd0b74Schristos (count) = W_TYPE_SIZE - 1 - _c; \ 58375fd0b74Schristos } while (0) 58475fd0b74Schristos /* similar to what gcc does for __builtin_ffs, but 0 based rather than 1 58575fd0b74Schristos based, and we don't need a special case for x==0 here */ 58675fd0b74Schristos #define count_trailing_zeros(count, x) \ 58775fd0b74Schristos do { \ 58875fd0b74Schristos UWtype __ctz_x = (x); \ 58975fd0b74Schristos __asm__ ("popcnt %0 = %1" \ 59075fd0b74Schristos : "=r" (count) \ 59175fd0b74Schristos : "r" ((__ctz_x-1) & ~__ctz_x)); \ 59275fd0b74Schristos } while (0) 59375fd0b74Schristos #define UMUL_TIME 14 59475fd0b74Schristos #endif 59575fd0b74Schristos 59675fd0b74Schristos #if defined (__M32R__) && W_TYPE_SIZE == 32 59775fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 59875fd0b74Schristos /* The cmp clears the condition bit. */ \ 59975fd0b74Schristos __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ 60075fd0b74Schristos : "=r" ((USItype) (sh)), \ 60175fd0b74Schristos "=&r" ((USItype) (sl)) \ 60275fd0b74Schristos : "0" ((USItype) (ah)), \ 60375fd0b74Schristos "r" ((USItype) (bh)), \ 60475fd0b74Schristos "1" ((USItype) (al)), \ 60575fd0b74Schristos "r" ((USItype) (bl)) \ 60675fd0b74Schristos : "cbit") 60775fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 60875fd0b74Schristos /* The cmp clears the condition bit. */ \ 60975fd0b74Schristos __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ 61075fd0b74Schristos : "=r" ((USItype) (sh)), \ 61175fd0b74Schristos "=&r" ((USItype) (sl)) \ 61275fd0b74Schristos : "0" ((USItype) (ah)), \ 61375fd0b74Schristos "r" ((USItype) (bh)), \ 61475fd0b74Schristos "1" ((USItype) (al)), \ 61575fd0b74Schristos "r" ((USItype) (bl)) \ 61675fd0b74Schristos : "cbit") 61775fd0b74Schristos #endif /* __M32R__ */ 61875fd0b74Schristos 61975fd0b74Schristos #if defined (__mc68000__) && W_TYPE_SIZE == 32 62075fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 62175fd0b74Schristos __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ 62275fd0b74Schristos : "=d" ((USItype) (sh)), \ 62375fd0b74Schristos "=&d" ((USItype) (sl)) \ 62475fd0b74Schristos : "%0" ((USItype) (ah)), \ 62575fd0b74Schristos "d" ((USItype) (bh)), \ 62675fd0b74Schristos "%1" ((USItype) (al)), \ 62775fd0b74Schristos "g" ((USItype) (bl))) 62875fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 62975fd0b74Schristos __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ 63075fd0b74Schristos : "=d" ((USItype) (sh)), \ 63175fd0b74Schristos "=&d" ((USItype) (sl)) \ 63275fd0b74Schristos : "0" ((USItype) (ah)), \ 63375fd0b74Schristos "d" ((USItype) (bh)), \ 63475fd0b74Schristos "1" ((USItype) (al)), \ 63575fd0b74Schristos "g" ((USItype) (bl))) 63675fd0b74Schristos 63775fd0b74Schristos /* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ 63875fd0b74Schristos #if (defined (__mc68020__) && !defined (__mc68060__)) 63975fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 64075fd0b74Schristos __asm__ ("mulu%.l %3,%1:%0" \ 64175fd0b74Schristos : "=d" ((USItype) (w0)), \ 64275fd0b74Schristos "=d" ((USItype) (w1)) \ 64375fd0b74Schristos : "%0" ((USItype) (u)), \ 64475fd0b74Schristos "dmi" ((USItype) (v))) 64575fd0b74Schristos #define UMUL_TIME 45 64675fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, d) \ 64775fd0b74Schristos __asm__ ("divu%.l %4,%1:%0" \ 64875fd0b74Schristos : "=d" ((USItype) (q)), \ 64975fd0b74Schristos "=d" ((USItype) (r)) \ 65075fd0b74Schristos : "0" ((USItype) (n0)), \ 65175fd0b74Schristos "1" ((USItype) (n1)), \ 65275fd0b74Schristos "dmi" ((USItype) (d))) 65375fd0b74Schristos #define UDIV_TIME 90 65475fd0b74Schristos #define sdiv_qrnnd(q, r, n1, n0, d) \ 65575fd0b74Schristos __asm__ ("divs%.l %4,%1:%0" \ 65675fd0b74Schristos : "=d" ((USItype) (q)), \ 65775fd0b74Schristos "=d" ((USItype) (r)) \ 65875fd0b74Schristos : "0" ((USItype) (n0)), \ 65975fd0b74Schristos "1" ((USItype) (n1)), \ 66075fd0b74Schristos "dmi" ((USItype) (d))) 66175fd0b74Schristos 66275fd0b74Schristos #elif defined (__mcoldfire__) /* not mc68020 */ 66375fd0b74Schristos 66475fd0b74Schristos #define umul_ppmm(xh, xl, a, b) \ 66575fd0b74Schristos __asm__ ("| Inlined umul_ppmm\n" \ 66675fd0b74Schristos " move%.l %2,%/d0\n" \ 66775fd0b74Schristos " move%.l %3,%/d1\n" \ 66875fd0b74Schristos " move%.l %/d0,%/d2\n" \ 66975fd0b74Schristos " swap %/d0\n" \ 67075fd0b74Schristos " move%.l %/d1,%/d3\n" \ 67175fd0b74Schristos " swap %/d1\n" \ 67275fd0b74Schristos " move%.w %/d2,%/d4\n" \ 67375fd0b74Schristos " mulu %/d3,%/d4\n" \ 67475fd0b74Schristos " mulu %/d1,%/d2\n" \ 67575fd0b74Schristos " mulu %/d0,%/d3\n" \ 67675fd0b74Schristos " mulu %/d0,%/d1\n" \ 67775fd0b74Schristos " move%.l %/d4,%/d0\n" \ 67875fd0b74Schristos " clr%.w %/d0\n" \ 67975fd0b74Schristos " swap %/d0\n" \ 68075fd0b74Schristos " add%.l %/d0,%/d2\n" \ 68175fd0b74Schristos " add%.l %/d3,%/d2\n" \ 68275fd0b74Schristos " jcc 1f\n" \ 68375fd0b74Schristos " add%.l %#65536,%/d1\n" \ 68475fd0b74Schristos "1: swap %/d2\n" \ 68575fd0b74Schristos " moveq %#0,%/d0\n" \ 68675fd0b74Schristos " move%.w %/d2,%/d0\n" \ 68775fd0b74Schristos " move%.w %/d4,%/d2\n" \ 68875fd0b74Schristos " move%.l %/d2,%1\n" \ 68975fd0b74Schristos " add%.l %/d1,%/d0\n" \ 69075fd0b74Schristos " move%.l %/d0,%0" \ 69175fd0b74Schristos : "=g" ((USItype) (xh)), \ 69275fd0b74Schristos "=g" ((USItype) (xl)) \ 69375fd0b74Schristos : "g" ((USItype) (a)), \ 69475fd0b74Schristos "g" ((USItype) (b)) \ 69575fd0b74Schristos : "d0", "d1", "d2", "d3", "d4") 69675fd0b74Schristos #define UMUL_TIME 100 69775fd0b74Schristos #define UDIV_TIME 400 69875fd0b74Schristos #else /* not ColdFire */ 69975fd0b74Schristos /* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ 70075fd0b74Schristos #define umul_ppmm(xh, xl, a, b) \ 70175fd0b74Schristos __asm__ ("| Inlined umul_ppmm\n" \ 70275fd0b74Schristos " move%.l %2,%/d0\n" \ 70375fd0b74Schristos " move%.l %3,%/d1\n" \ 70475fd0b74Schristos " move%.l %/d0,%/d2\n" \ 70575fd0b74Schristos " swap %/d0\n" \ 70675fd0b74Schristos " move%.l %/d1,%/d3\n" \ 70775fd0b74Schristos " swap %/d1\n" \ 70875fd0b74Schristos " move%.w %/d2,%/d4\n" \ 70975fd0b74Schristos " mulu %/d3,%/d4\n" \ 71075fd0b74Schristos " mulu %/d1,%/d2\n" \ 71175fd0b74Schristos " mulu %/d0,%/d3\n" \ 71275fd0b74Schristos " mulu %/d0,%/d1\n" \ 71375fd0b74Schristos " move%.l %/d4,%/d0\n" \ 71475fd0b74Schristos " eor%.w %/d0,%/d0\n" \ 71575fd0b74Schristos " swap %/d0\n" \ 71675fd0b74Schristos " add%.l %/d0,%/d2\n" \ 71775fd0b74Schristos " add%.l %/d3,%/d2\n" \ 71875fd0b74Schristos " jcc 1f\n" \ 71975fd0b74Schristos " add%.l %#65536,%/d1\n" \ 72075fd0b74Schristos "1: swap %/d2\n" \ 72175fd0b74Schristos " moveq %#0,%/d0\n" \ 72275fd0b74Schristos " move%.w %/d2,%/d0\n" \ 72375fd0b74Schristos " move%.w %/d4,%/d2\n" \ 72475fd0b74Schristos " move%.l %/d2,%1\n" \ 72575fd0b74Schristos " add%.l %/d1,%/d0\n" \ 72675fd0b74Schristos " move%.l %/d0,%0" \ 72775fd0b74Schristos : "=g" ((USItype) (xh)), \ 72875fd0b74Schristos "=g" ((USItype) (xl)) \ 72975fd0b74Schristos : "g" ((USItype) (a)), \ 73075fd0b74Schristos "g" ((USItype) (b)) \ 73175fd0b74Schristos : "d0", "d1", "d2", "d3", "d4") 73275fd0b74Schristos #define UMUL_TIME 100 73375fd0b74Schristos #define UDIV_TIME 400 73475fd0b74Schristos 73575fd0b74Schristos #endif /* not mc68020 */ 73675fd0b74Schristos 73775fd0b74Schristos /* The '020, '030, '040 and '060 have bitfield insns. 73875fd0b74Schristos cpu32 disguises as a 68020, but lacks them. */ 73975fd0b74Schristos #if defined (__mc68020__) && !defined (__mcpu32__) 74075fd0b74Schristos #define count_leading_zeros(count, x) \ 74175fd0b74Schristos __asm__ ("bfffo %1{%b2:%b2},%0" \ 74275fd0b74Schristos : "=d" ((USItype) (count)) \ 74375fd0b74Schristos : "od" ((USItype) (x)), "n" (0)) 74475fd0b74Schristos /* Some ColdFire architectures have a ff1 instruction supported via 74575fd0b74Schristos __builtin_clz. */ 74675fd0b74Schristos #elif defined (__mcfisaaplus__) || defined (__mcfisac__) 74775fd0b74Schristos #define count_leading_zeros(count,x) ((count) = __builtin_clz (x)) 74875fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 74975fd0b74Schristos #endif 75075fd0b74Schristos #endif /* mc68000 */ 75175fd0b74Schristos 75275fd0b74Schristos #if defined (__m88000__) && W_TYPE_SIZE == 32 75375fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 75475fd0b74Schristos __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ 75575fd0b74Schristos : "=r" ((USItype) (sh)), \ 75675fd0b74Schristos "=&r" ((USItype) (sl)) \ 75775fd0b74Schristos : "%rJ" ((USItype) (ah)), \ 75875fd0b74Schristos "rJ" ((USItype) (bh)), \ 75975fd0b74Schristos "%rJ" ((USItype) (al)), \ 76075fd0b74Schristos "rJ" ((USItype) (bl))) 76175fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 76275fd0b74Schristos __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ 76375fd0b74Schristos : "=r" ((USItype) (sh)), \ 76475fd0b74Schristos "=&r" ((USItype) (sl)) \ 76575fd0b74Schristos : "rJ" ((USItype) (ah)), \ 76675fd0b74Schristos "rJ" ((USItype) (bh)), \ 76775fd0b74Schristos "rJ" ((USItype) (al)), \ 76875fd0b74Schristos "rJ" ((USItype) (bl))) 76975fd0b74Schristos #define count_leading_zeros(count, x) \ 77075fd0b74Schristos do { \ 77175fd0b74Schristos USItype __cbtmp; \ 77275fd0b74Schristos __asm__ ("ff1 %0,%1" \ 77375fd0b74Schristos : "=r" (__cbtmp) \ 77475fd0b74Schristos : "r" ((USItype) (x))); \ 77575fd0b74Schristos (count) = __cbtmp ^ 31; \ 77675fd0b74Schristos } while (0) 77775fd0b74Schristos #define COUNT_LEADING_ZEROS_0 63 /* sic */ 77875fd0b74Schristos #if defined (__mc88110__) 77975fd0b74Schristos #define umul_ppmm(wh, wl, u, v) \ 78075fd0b74Schristos do { \ 78175fd0b74Schristos union {UDItype __ll; \ 78275fd0b74Schristos struct {USItype __h, __l;} __i; \ 78375fd0b74Schristos } __xx; \ 78475fd0b74Schristos __asm__ ("mulu.d %0,%1,%2" \ 78575fd0b74Schristos : "=r" (__xx.__ll) \ 78675fd0b74Schristos : "r" ((USItype) (u)), \ 78775fd0b74Schristos "r" ((USItype) (v))); \ 78875fd0b74Schristos (wh) = __xx.__i.__h; \ 78975fd0b74Schristos (wl) = __xx.__i.__l; \ 79075fd0b74Schristos } while (0) 79175fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, d) \ 79275fd0b74Schristos ({union {UDItype __ll; \ 79375fd0b74Schristos struct {USItype __h, __l;} __i; \ 79475fd0b74Schristos } __xx; \ 79575fd0b74Schristos USItype __q; \ 79675fd0b74Schristos __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ 79775fd0b74Schristos __asm__ ("divu.d %0,%1,%2" \ 79875fd0b74Schristos : "=r" (__q) \ 79975fd0b74Schristos : "r" (__xx.__ll), \ 80075fd0b74Schristos "r" ((USItype) (d))); \ 80175fd0b74Schristos (r) = (n0) - __q * (d); (q) = __q; }) 80275fd0b74Schristos #define UMUL_TIME 5 80375fd0b74Schristos #define UDIV_TIME 25 80475fd0b74Schristos #else 80575fd0b74Schristos #define UMUL_TIME 17 80675fd0b74Schristos #define UDIV_TIME 150 80775fd0b74Schristos #endif /* __mc88110__ */ 80875fd0b74Schristos #endif /* __m88000__ */ 80975fd0b74Schristos 81075fd0b74Schristos #if defined (__mn10300__) 81175fd0b74Schristos # if defined (__AM33__) 81275fd0b74Schristos # define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) 81375fd0b74Schristos # define umul_ppmm(w1, w0, u, v) \ 81475fd0b74Schristos asm("mulu %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v)) 81575fd0b74Schristos # define smul_ppmm(w1, w0, u, v) \ 81675fd0b74Schristos asm("mul %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v)) 81775fd0b74Schristos # else 81875fd0b74Schristos # define umul_ppmm(w1, w0, u, v) \ 81975fd0b74Schristos asm("nop; nop; mulu %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v)) 82075fd0b74Schristos # define smul_ppmm(w1, w0, u, v) \ 82175fd0b74Schristos asm("nop; nop; mul %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v)) 82275fd0b74Schristos # endif 82375fd0b74Schristos # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 82475fd0b74Schristos do { \ 82575fd0b74Schristos DWunion __s, __a, __b; \ 82675fd0b74Schristos __a.s.low = (al); __a.s.high = (ah); \ 82775fd0b74Schristos __b.s.low = (bl); __b.s.high = (bh); \ 82875fd0b74Schristos __s.ll = __a.ll + __b.ll; \ 82975fd0b74Schristos (sl) = __s.s.low; (sh) = __s.s.high; \ 83075fd0b74Schristos } while (0) 83175fd0b74Schristos # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 83275fd0b74Schristos do { \ 83375fd0b74Schristos DWunion __s, __a, __b; \ 83475fd0b74Schristos __a.s.low = (al); __a.s.high = (ah); \ 83575fd0b74Schristos __b.s.low = (bl); __b.s.high = (bh); \ 83675fd0b74Schristos __s.ll = __a.ll - __b.ll; \ 83775fd0b74Schristos (sl) = __s.s.low; (sh) = __s.s.high; \ 83875fd0b74Schristos } while (0) 83975fd0b74Schristos # define udiv_qrnnd(q, r, nh, nl, d) \ 84075fd0b74Schristos asm("divu %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh)) 84175fd0b74Schristos # define sdiv_qrnnd(q, r, nh, nl, d) \ 84275fd0b74Schristos asm("div %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh)) 84375fd0b74Schristos # define UMUL_TIME 3 84475fd0b74Schristos # define UDIV_TIME 38 84575fd0b74Schristos #endif 84675fd0b74Schristos 84775fd0b74Schristos #if defined (__mips__) && W_TYPE_SIZE == 32 84875fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 84975fd0b74Schristos do { \ 85075fd0b74Schristos UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ 85175fd0b74Schristos (w1) = (USItype) (__x >> 32); \ 85275fd0b74Schristos (w0) = (USItype) (__x); \ 85375fd0b74Schristos } while (0) 85475fd0b74Schristos #define UMUL_TIME 10 85575fd0b74Schristos #define UDIV_TIME 100 85675fd0b74Schristos 85775fd0b74Schristos #if (__mips == 32 || __mips == 64) && ! defined (__mips16) 85875fd0b74Schristos #define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) 85975fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 86075fd0b74Schristos #endif 86175fd0b74Schristos #endif /* __mips__ */ 86275fd0b74Schristos 86375fd0b74Schristos /* FIXME: We should test _IBMR2 here when we add assembly support for the 86475fd0b74Schristos system vendor compilers. 86575fd0b74Schristos FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good 86675fd0b74Schristos enough, since that hits ARM and m68k too. */ 86775fd0b74Schristos #if (defined (_ARCH_PPC) /* AIX */ \ 86875fd0b74Schristos || defined (__powerpc__) /* gcc */ \ 86975fd0b74Schristos || defined (__POWERPC__) /* BEOS */ \ 87075fd0b74Schristos || defined (__ppc__) /* Darwin */ \ 87175fd0b74Schristos || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ 87275fd0b74Schristos || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ 87375fd0b74Schristos && CPU_FAMILY == PPC) \ 87475fd0b74Schristos ) && W_TYPE_SIZE == 32 87575fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 87675fd0b74Schristos do { \ 87775fd0b74Schristos if (__builtin_constant_p (bh) && (bh) == 0) \ 87875fd0b74Schristos __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \ 87975fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 88075fd0b74Schristos else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ 88175fd0b74Schristos __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \ 88275fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 88375fd0b74Schristos else \ 88475fd0b74Schristos __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \ 88575fd0b74Schristos : "=r" (sh), "=&r" (sl) \ 88675fd0b74Schristos : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ 88775fd0b74Schristos } while (0) 88875fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 88975fd0b74Schristos do { \ 89075fd0b74Schristos if (__builtin_constant_p (ah) && (ah) == 0) \ 89175fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \ 89275fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 89375fd0b74Schristos else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ 89475fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \ 89575fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 89675fd0b74Schristos else if (__builtin_constant_p (bh) && (bh) == 0) \ 89775fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \ 89875fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 89975fd0b74Schristos else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ 90075fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \ 90175fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 90275fd0b74Schristos else \ 90375fd0b74Schristos __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \ 90475fd0b74Schristos : "=r" (sh), "=&r" (sl) \ 90575fd0b74Schristos : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ 90675fd0b74Schristos } while (0) 90775fd0b74Schristos #define count_leading_zeros(count, x) \ 90875fd0b74Schristos __asm__ ("cntlzw %0,%1" : "=r" (count) : "r" (x)) 90975fd0b74Schristos #define COUNT_LEADING_ZEROS_0 32 91075fd0b74Schristos #if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ 91175fd0b74Schristos || defined (__ppc__) \ 91275fd0b74Schristos || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ 91375fd0b74Schristos || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ 91475fd0b74Schristos && CPU_FAMILY == PPC) 91575fd0b74Schristos #define umul_ppmm(ph, pl, m0, m1) \ 91675fd0b74Schristos do { \ 91775fd0b74Schristos USItype __m0 = (m0), __m1 = (m1); \ 91875fd0b74Schristos __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 91975fd0b74Schristos (pl) = __m0 * __m1; \ 92075fd0b74Schristos } while (0) 92175fd0b74Schristos #define UMUL_TIME 15 92275fd0b74Schristos #define smul_ppmm(ph, pl, m0, m1) \ 92375fd0b74Schristos do { \ 92475fd0b74Schristos SItype __m0 = (m0), __m1 = (m1); \ 92575fd0b74Schristos __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 92675fd0b74Schristos (pl) = __m0 * __m1; \ 92775fd0b74Schristos } while (0) 92875fd0b74Schristos #define SMUL_TIME 14 92975fd0b74Schristos #define UDIV_TIME 120 93075fd0b74Schristos #endif 93175fd0b74Schristos #endif /* 32-bit POWER architecture variants. */ 93275fd0b74Schristos 93375fd0b74Schristos /* We should test _IBMR2 here when we add assembly support for the system 93475fd0b74Schristos vendor compilers. */ 93575fd0b74Schristos #if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 93675fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 93775fd0b74Schristos do { \ 93875fd0b74Schristos if (__builtin_constant_p (bh) && (bh) == 0) \ 93975fd0b74Schristos __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \ 94075fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 94175fd0b74Schristos else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ 94275fd0b74Schristos __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \ 94375fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ 94475fd0b74Schristos else \ 94575fd0b74Schristos __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \ 94675fd0b74Schristos : "=r" (sh), "=&r" (sl) \ 94775fd0b74Schristos : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ 94875fd0b74Schristos } while (0) 94975fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 95075fd0b74Schristos do { \ 95175fd0b74Schristos if (__builtin_constant_p (ah) && (ah) == 0) \ 95275fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \ 95375fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 95475fd0b74Schristos else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ 95575fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \ 95675fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ 95775fd0b74Schristos else if (__builtin_constant_p (bh) && (bh) == 0) \ 95875fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \ 95975fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 96075fd0b74Schristos else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ 96175fd0b74Schristos __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \ 96275fd0b74Schristos : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ 96375fd0b74Schristos else \ 96475fd0b74Schristos __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \ 96575fd0b74Schristos : "=r" (sh), "=&r" (sl) \ 96675fd0b74Schristos : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ 96775fd0b74Schristos } while (0) 96875fd0b74Schristos #define count_leading_zeros(count, x) \ 96975fd0b74Schristos __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) 97075fd0b74Schristos #define COUNT_LEADING_ZEROS_0 64 97175fd0b74Schristos #define umul_ppmm(ph, pl, m0, m1) \ 97275fd0b74Schristos do { \ 97375fd0b74Schristos UDItype __m0 = (m0), __m1 = (m1); \ 97475fd0b74Schristos __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 97575fd0b74Schristos (pl) = __m0 * __m1; \ 97675fd0b74Schristos } while (0) 97775fd0b74Schristos #define UMUL_TIME 15 97875fd0b74Schristos #define smul_ppmm(ph, pl, m0, m1) \ 97975fd0b74Schristos do { \ 98075fd0b74Schristos DItype __m0 = (m0), __m1 = (m1); \ 98175fd0b74Schristos __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ 98275fd0b74Schristos (pl) = __m0 * __m1; \ 98375fd0b74Schristos } while (0) 98475fd0b74Schristos #define SMUL_TIME 14 /* ??? */ 98575fd0b74Schristos #define UDIV_TIME 120 /* ??? */ 98675fd0b74Schristos #endif /* 64-bit PowerPC. */ 98775fd0b74Schristos 98875fd0b74Schristos #if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 98975fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 99075fd0b74Schristos __asm__ ("a %1,%5\n\tae %0,%3" \ 99175fd0b74Schristos : "=r" ((USItype) (sh)), \ 99275fd0b74Schristos "=&r" ((USItype) (sl)) \ 99375fd0b74Schristos : "%0" ((USItype) (ah)), \ 99475fd0b74Schristos "r" ((USItype) (bh)), \ 99575fd0b74Schristos "%1" ((USItype) (al)), \ 99675fd0b74Schristos "r" ((USItype) (bl))) 99775fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 99875fd0b74Schristos __asm__ ("s %1,%5\n\tse %0,%3" \ 99975fd0b74Schristos : "=r" ((USItype) (sh)), \ 100075fd0b74Schristos "=&r" ((USItype) (sl)) \ 100175fd0b74Schristos : "0" ((USItype) (ah)), \ 100275fd0b74Schristos "r" ((USItype) (bh)), \ 100375fd0b74Schristos "1" ((USItype) (al)), \ 100475fd0b74Schristos "r" ((USItype) (bl))) 100575fd0b74Schristos #define umul_ppmm(ph, pl, m0, m1) \ 100675fd0b74Schristos do { \ 100775fd0b74Schristos USItype __m0 = (m0), __m1 = (m1); \ 100875fd0b74Schristos __asm__ ( \ 100975fd0b74Schristos "s r2,r2\n" \ 101075fd0b74Schristos " mts r10,%2\n" \ 101175fd0b74Schristos " m r2,%3\n" \ 101275fd0b74Schristos " m r2,%3\n" \ 101375fd0b74Schristos " m r2,%3\n" \ 101475fd0b74Schristos " m r2,%3\n" \ 101575fd0b74Schristos " m r2,%3\n" \ 101675fd0b74Schristos " m r2,%3\n" \ 101775fd0b74Schristos " m r2,%3\n" \ 101875fd0b74Schristos " m r2,%3\n" \ 101975fd0b74Schristos " m r2,%3\n" \ 102075fd0b74Schristos " m r2,%3\n" \ 102175fd0b74Schristos " m r2,%3\n" \ 102275fd0b74Schristos " m r2,%3\n" \ 102375fd0b74Schristos " m r2,%3\n" \ 102475fd0b74Schristos " m r2,%3\n" \ 102575fd0b74Schristos " m r2,%3\n" \ 102675fd0b74Schristos " m r2,%3\n" \ 102775fd0b74Schristos " cas %0,r2,r0\n" \ 102875fd0b74Schristos " mfs r10,%1" \ 102975fd0b74Schristos : "=r" ((USItype) (ph)), \ 103075fd0b74Schristos "=r" ((USItype) (pl)) \ 103175fd0b74Schristos : "%r" (__m0), \ 103275fd0b74Schristos "r" (__m1) \ 103375fd0b74Schristos : "r2"); \ 103475fd0b74Schristos (ph) += ((((SItype) __m0 >> 31) & __m1) \ 103575fd0b74Schristos + (((SItype) __m1 >> 31) & __m0)); \ 103675fd0b74Schristos } while (0) 103775fd0b74Schristos #define UMUL_TIME 20 103875fd0b74Schristos #define UDIV_TIME 200 103975fd0b74Schristos #define count_leading_zeros(count, x) \ 104075fd0b74Schristos do { \ 104175fd0b74Schristos if ((x) >= 0x10000) \ 104275fd0b74Schristos __asm__ ("clz %0,%1" \ 104375fd0b74Schristos : "=r" ((USItype) (count)) \ 104475fd0b74Schristos : "r" ((USItype) (x) >> 16)); \ 104575fd0b74Schristos else \ 104675fd0b74Schristos { \ 104775fd0b74Schristos __asm__ ("clz %0,%1" \ 104875fd0b74Schristos : "=r" ((USItype) (count)) \ 104975fd0b74Schristos : "r" ((USItype) (x))); \ 105075fd0b74Schristos (count) += 16; \ 105175fd0b74Schristos } \ 105275fd0b74Schristos } while (0) 105375fd0b74Schristos #endif 105475fd0b74Schristos 1055ede78133Schristos #if defined(__riscv) 1056ede78133Schristos #ifdef __riscv_mul 1057ede78133Schristos #define __umulsidi3(u,v) ((UDWtype)(UWtype)(u) * (UWtype)(v)) 1058ede78133Schristos #define __muluw3(a, b) ((UWtype)(a) * (UWtype)(b)) 1059ede78133Schristos #else 1060ede78133Schristos #if __riscv_xlen == 32 1061ede78133Schristos #define MULUW3 "call __mulsi3" 1062ede78133Schristos #elif __riscv_xlen == 64 1063ede78133Schristos #define MULUW3 "call __muldi3" 1064ede78133Schristos #else 1065ede78133Schristos #error unsupport xlen 1066ede78133Schristos #endif /* __riscv_xlen */ 1067ede78133Schristos /* We rely on the fact that MULUW3 doesn't clobber the t-registers. 1068ede78133Schristos It can get better register allocation result. */ 1069ede78133Schristos #define __muluw3(a, b) \ 1070ede78133Schristos ({ \ 1071ede78133Schristos register UWtype __op0 asm ("a0") = a; \ 1072ede78133Schristos register UWtype __op1 asm ("a1") = b; \ 1073ede78133Schristos asm volatile (MULUW3 \ 1074ede78133Schristos : "+r" (__op0), "+r" (__op1) \ 1075ede78133Schristos : \ 1076ede78133Schristos : "ra", "a2", "a3"); \ 1077ede78133Schristos __op0; \ 1078ede78133Schristos }) 1079ede78133Schristos #endif /* __riscv_mul */ 1080ede78133Schristos #define umul_ppmm(w1, w0, u, v) \ 1081ede78133Schristos do { \ 1082ede78133Schristos UWtype __x0, __x1, __x2, __x3; \ 1083ede78133Schristos UHWtype __ul, __vl, __uh, __vh; \ 1084ede78133Schristos \ 1085ede78133Schristos __ul = __ll_lowpart (u); \ 1086ede78133Schristos __uh = __ll_highpart (u); \ 1087ede78133Schristos __vl = __ll_lowpart (v); \ 1088ede78133Schristos __vh = __ll_highpart (v); \ 1089ede78133Schristos \ 1090ede78133Schristos __x0 = __muluw3 (__ul, __vl); \ 1091ede78133Schristos __x1 = __muluw3 (__ul, __vh); \ 1092ede78133Schristos __x2 = __muluw3 (__uh, __vl); \ 1093ede78133Schristos __x3 = __muluw3 (__uh, __vh); \ 1094ede78133Schristos \ 1095ede78133Schristos __x1 += __ll_highpart (__x0);/* this can't give carry */ \ 1096ede78133Schristos __x1 += __x2; /* but this indeed can */ \ 1097ede78133Schristos if (__x1 < __x2) /* did we get it? */ \ 1098ede78133Schristos __x3 += __ll_B; /* yes, add it in the proper pos. */ \ 1099ede78133Schristos \ 1100ede78133Schristos (w1) = __x3 + __ll_highpart (__x1); \ 1101ede78133Schristos (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ 1102ede78133Schristos } while (0) 1103ede78133Schristos #endif /* __riscv */ 1104ede78133Schristos 1105ede78133Schristos #if defined(__sh__) && W_TYPE_SIZE == 32 110675fd0b74Schristos #ifndef __sh1__ 110775fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 110875fd0b74Schristos __asm__ ( \ 110975fd0b74Schristos "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ 111075fd0b74Schristos : "=r<" ((USItype)(w1)), \ 111175fd0b74Schristos "=r<" ((USItype)(w0)) \ 111275fd0b74Schristos : "r" ((USItype)(u)), \ 111375fd0b74Schristos "r" ((USItype)(v)) \ 111475fd0b74Schristos : "macl", "mach") 111575fd0b74Schristos #define UMUL_TIME 5 111675fd0b74Schristos #endif 111775fd0b74Schristos 111875fd0b74Schristos /* This is the same algorithm as __udiv_qrnnd_c. */ 111975fd0b74Schristos #define UDIV_NEEDS_NORMALIZATION 1 112075fd0b74Schristos 112175fd0b74Schristos #ifdef __FDPIC__ 112275fd0b74Schristos /* FDPIC needs a special version of the asm fragment to extract the 112375fd0b74Schristos code address from the function descriptor. __udiv_qrnnd_16 is 112475fd0b74Schristos assumed to be local and not to use the GOT, so loading r12 is 112575fd0b74Schristos not needed. */ 112675fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, d) \ 112775fd0b74Schristos do { \ 112875fd0b74Schristos extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ 112975fd0b74Schristos __attribute__ ((visibility ("hidden"))); \ 113075fd0b74Schristos /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ 113175fd0b74Schristos __asm__ ( \ 113275fd0b74Schristos "mov%M4 %4,r5\n" \ 113375fd0b74Schristos " swap.w %3,r4\n" \ 113475fd0b74Schristos " swap.w r5,r6\n" \ 113575fd0b74Schristos " mov.l @%5,r2\n" \ 113675fd0b74Schristos " jsr @r2\n" \ 113775fd0b74Schristos " shll16 r6\n" \ 113875fd0b74Schristos " swap.w r4,r4\n" \ 113975fd0b74Schristos " mov.l @%5,r2\n" \ 114075fd0b74Schristos " jsr @r2\n" \ 114175fd0b74Schristos " swap.w r1,%0\n" \ 114275fd0b74Schristos " or r1,%0" \ 114375fd0b74Schristos : "=r" (q), "=&z" (r) \ 114475fd0b74Schristos : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ 114575fd0b74Schristos : "r1", "r2", "r4", "r5", "r6", "pr", "t"); \ 114675fd0b74Schristos } while (0) 114775fd0b74Schristos #else 114875fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, d) \ 114975fd0b74Schristos do { \ 115075fd0b74Schristos extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ 115175fd0b74Schristos __attribute__ ((visibility ("hidden"))); \ 115275fd0b74Schristos /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ 115375fd0b74Schristos __asm__ ( \ 115475fd0b74Schristos "mov%M4 %4,r5\n" \ 115575fd0b74Schristos " swap.w %3,r4\n" \ 115675fd0b74Schristos " swap.w r5,r6\n" \ 115775fd0b74Schristos " jsr @%5\n" \ 115875fd0b74Schristos " shll16 r6\n" \ 115975fd0b74Schristos " swap.w r4,r4\n" \ 116075fd0b74Schristos " jsr @%5\n" \ 116175fd0b74Schristos " swap.w r1,%0\n" \ 116275fd0b74Schristos " or r1,%0" \ 116375fd0b74Schristos : "=r" (q), "=&z" (r) \ 116475fd0b74Schristos : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ 116575fd0b74Schristos : "r1", "r2", "r4", "r5", "r6", "pr", "t"); \ 116675fd0b74Schristos } while (0) 116775fd0b74Schristos #endif /* __FDPIC__ */ 116875fd0b74Schristos 116975fd0b74Schristos #define UDIV_TIME 80 117075fd0b74Schristos 117175fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 117275fd0b74Schristos __asm__ ("clrt;subc %5,%1; subc %4,%0" \ 117375fd0b74Schristos : "=r" (sh), "=r" (sl) \ 117475fd0b74Schristos : "0" (ah), "1" (al), "r" (bh), "r" (bl) : "t") 117575fd0b74Schristos 117675fd0b74Schristos #endif /* __sh__ */ 117775fd0b74Schristos 117875fd0b74Schristos #if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ 117975fd0b74Schristos && W_TYPE_SIZE == 32 118075fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 118175fd0b74Schristos __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ 118275fd0b74Schristos : "=r" ((USItype) (sh)), \ 118375fd0b74Schristos "=&r" ((USItype) (sl)) \ 118475fd0b74Schristos : "%rJ" ((USItype) (ah)), \ 118575fd0b74Schristos "rI" ((USItype) (bh)), \ 118675fd0b74Schristos "%rJ" ((USItype) (al)), \ 118775fd0b74Schristos "rI" ((USItype) (bl)) \ 118875fd0b74Schristos __CLOBBER_CC) 118975fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 119075fd0b74Schristos __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ 119175fd0b74Schristos : "=r" ((USItype) (sh)), \ 119275fd0b74Schristos "=&r" ((USItype) (sl)) \ 119375fd0b74Schristos : "rJ" ((USItype) (ah)), \ 119475fd0b74Schristos "rI" ((USItype) (bh)), \ 119575fd0b74Schristos "rJ" ((USItype) (al)), \ 119675fd0b74Schristos "rI" ((USItype) (bl)) \ 119775fd0b74Schristos __CLOBBER_CC) 119875fd0b74Schristos #if defined (__sparc_v9__) 119975fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 120075fd0b74Schristos do { \ 120175fd0b74Schristos register USItype __g1 asm ("g1"); \ 120275fd0b74Schristos __asm__ ("umul\t%2,%3,%1\n\t" \ 120375fd0b74Schristos "srlx\t%1, 32, %0" \ 120475fd0b74Schristos : "=r" ((USItype) (w1)), \ 120575fd0b74Schristos "=r" (__g1) \ 120675fd0b74Schristos : "r" ((USItype) (u)), \ 120775fd0b74Schristos "r" ((USItype) (v))); \ 120875fd0b74Schristos (w0) = __g1; \ 120975fd0b74Schristos } while (0) 121075fd0b74Schristos #define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ 121175fd0b74Schristos __asm__ ("mov\t%2,%%y\n\t" \ 121275fd0b74Schristos "udiv\t%3,%4,%0\n\t" \ 121375fd0b74Schristos "umul\t%0,%4,%1\n\t" \ 121475fd0b74Schristos "sub\t%3,%1,%1" \ 121575fd0b74Schristos : "=&r" ((USItype) (__q)), \ 121675fd0b74Schristos "=&r" ((USItype) (__r)) \ 121775fd0b74Schristos : "r" ((USItype) (__n1)), \ 121875fd0b74Schristos "r" ((USItype) (__n0)), \ 121975fd0b74Schristos "r" ((USItype) (__d))) 122075fd0b74Schristos #else 122175fd0b74Schristos #if defined (__sparc_v8__) 122275fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 122375fd0b74Schristos __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 122475fd0b74Schristos : "=r" ((USItype) (w1)), \ 122575fd0b74Schristos "=r" ((USItype) (w0)) \ 122675fd0b74Schristos : "r" ((USItype) (u)), \ 122775fd0b74Schristos "r" ((USItype) (v))) 122875fd0b74Schristos #define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ 122975fd0b74Schristos __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ 123075fd0b74Schristos : "=&r" ((USItype) (__q)), \ 123175fd0b74Schristos "=&r" ((USItype) (__r)) \ 123275fd0b74Schristos : "r" ((USItype) (__n1)), \ 123375fd0b74Schristos "r" ((USItype) (__n0)), \ 123475fd0b74Schristos "r" ((USItype) (__d))) 123575fd0b74Schristos #else 123675fd0b74Schristos #if defined (__sparclite__) 123775fd0b74Schristos /* This has hardware multiply but not divide. It also has two additional 123875fd0b74Schristos instructions scan (ffs from high bit) and divscc. */ 123975fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 124075fd0b74Schristos __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 124175fd0b74Schristos : "=r" ((USItype) (w1)), \ 124275fd0b74Schristos "=r" ((USItype) (w0)) \ 124375fd0b74Schristos : "r" ((USItype) (u)), \ 124475fd0b74Schristos "r" ((USItype) (v))) 124575fd0b74Schristos #define udiv_qrnnd(q, r, n1, n0, d) \ 124675fd0b74Schristos __asm__ ("! Inlined udiv_qrnnd\n" \ 124775fd0b74Schristos " wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ 124875fd0b74Schristos " tst %%g0\n" \ 124975fd0b74Schristos " divscc %3,%4,%%g1\n" \ 125075fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125175fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125275fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125375fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125475fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125575fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125675fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125775fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125875fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 125975fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126075fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126175fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126275fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126375fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126475fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126575fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126675fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126775fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126875fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 126975fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127075fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127175fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127275fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127375fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127475fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127575fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127675fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127775fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127875fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 127975fd0b74Schristos " divscc %%g1,%4,%%g1\n" \ 128075fd0b74Schristos " divscc %%g1,%4,%0\n" \ 128175fd0b74Schristos " rd %%y,%1\n" \ 128275fd0b74Schristos " bl,a 1f\n" \ 128375fd0b74Schristos " add %1,%4,%1\n" \ 128475fd0b74Schristos "1: ! End of inline udiv_qrnnd" \ 128575fd0b74Schristos : "=r" ((USItype) (q)), \ 128675fd0b74Schristos "=r" ((USItype) (r)) \ 128775fd0b74Schristos : "r" ((USItype) (n1)), \ 128875fd0b74Schristos "r" ((USItype) (n0)), \ 128975fd0b74Schristos "rI" ((USItype) (d)) \ 129075fd0b74Schristos : "g1" __AND_CLOBBER_CC) 129175fd0b74Schristos #define UDIV_TIME 37 129275fd0b74Schristos #define count_leading_zeros(count, x) \ 129375fd0b74Schristos do { \ 129475fd0b74Schristos __asm__ ("scan %1,1,%0" \ 129575fd0b74Schristos : "=r" ((USItype) (count)) \ 129675fd0b74Schristos : "r" ((USItype) (x))); \ 129775fd0b74Schristos } while (0) 129875fd0b74Schristos /* Early sparclites return 63 for an argument of 0, but they warn that future 129975fd0b74Schristos implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 130075fd0b74Schristos undefined. */ 130175fd0b74Schristos #else 130275fd0b74Schristos /* SPARC without integer multiplication and divide instructions. 130375fd0b74Schristos (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ 130475fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 130575fd0b74Schristos __asm__ ("! Inlined umul_ppmm\n" \ 130675fd0b74Schristos " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ 130775fd0b74Schristos " sra %3,31,%%o5 ! Don't move this insn\n" \ 130875fd0b74Schristos " and %2,%%o5,%%o5 ! Don't move this insn\n" \ 130975fd0b74Schristos " andcc %%g0,0,%%g1 ! Don't move this insn\n" \ 131075fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131175fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131275fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131375fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131475fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131575fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131675fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131775fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131875fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 131975fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132075fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132175fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132275fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132375fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132475fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132575fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132675fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132775fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132875fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 132975fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133075fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133175fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133275fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133375fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133475fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133575fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133675fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133775fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133875fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 133975fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 134075fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 134175fd0b74Schristos " mulscc %%g1,%3,%%g1\n" \ 134275fd0b74Schristos " mulscc %%g1,0,%%g1\n" \ 134375fd0b74Schristos " add %%g1,%%o5,%0\n" \ 134475fd0b74Schristos " rd %%y,%1" \ 134575fd0b74Schristos : "=r" ((USItype) (w1)), \ 134675fd0b74Schristos "=r" ((USItype) (w0)) \ 134775fd0b74Schristos : "%rI" ((USItype) (u)), \ 134875fd0b74Schristos "r" ((USItype) (v)) \ 134975fd0b74Schristos : "g1", "o5" __AND_CLOBBER_CC) 135075fd0b74Schristos #define UMUL_TIME 39 /* 39 instructions */ 135175fd0b74Schristos /* It's quite necessary to add this much assembler for the sparc. 135275fd0b74Schristos The default udiv_qrnnd (in C) is more than 10 times slower! */ 135375fd0b74Schristos #define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ 135475fd0b74Schristos __asm__ ("! Inlined udiv_qrnnd\n" \ 135575fd0b74Schristos " mov 32,%%g1\n" \ 135675fd0b74Schristos " subcc %1,%2,%%g0\n" \ 135775fd0b74Schristos "1: bcs 5f\n" \ 135875fd0b74Schristos " addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ 135975fd0b74Schristos " sub %1,%2,%1 ! this kills msb of n\n" \ 136075fd0b74Schristos " addx %1,%1,%1 ! so this can't give carry\n" \ 136175fd0b74Schristos " subcc %%g1,1,%%g1\n" \ 136275fd0b74Schristos "2: bne 1b\n" \ 136375fd0b74Schristos " subcc %1,%2,%%g0\n" \ 136475fd0b74Schristos " bcs 3f\n" \ 136575fd0b74Schristos " addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ 136675fd0b74Schristos " b 3f\n" \ 136775fd0b74Schristos " sub %1,%2,%1 ! this kills msb of n\n" \ 136875fd0b74Schristos "4: sub %1,%2,%1\n" \ 136975fd0b74Schristos "5: addxcc %1,%1,%1\n" \ 137075fd0b74Schristos " bcc 2b\n" \ 137175fd0b74Schristos " subcc %%g1,1,%%g1\n" \ 137275fd0b74Schristos "! Got carry from n. Subtract next step to cancel this carry.\n" \ 137375fd0b74Schristos " bne 4b\n" \ 137475fd0b74Schristos " addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ 137575fd0b74Schristos " sub %1,%2,%1\n" \ 137675fd0b74Schristos "3: xnor %0,0,%0\n" \ 137775fd0b74Schristos " ! End of inline udiv_qrnnd" \ 137875fd0b74Schristos : "=&r" ((USItype) (__q)), \ 137975fd0b74Schristos "=&r" ((USItype) (__r)) \ 138075fd0b74Schristos : "r" ((USItype) (__d)), \ 138175fd0b74Schristos "1" ((USItype) (__n1)), \ 138275fd0b74Schristos "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) 138375fd0b74Schristos #define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ 138475fd0b74Schristos #endif /* __sparclite__ */ 138575fd0b74Schristos #endif /* __sparc_v8__ */ 138675fd0b74Schristos #endif /* __sparc_v9__ */ 138775fd0b74Schristos #endif /* sparc32 */ 138875fd0b74Schristos 138975fd0b74Schristos #if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ 139075fd0b74Schristos && W_TYPE_SIZE == 64 139175fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 139275fd0b74Schristos do { \ 139375fd0b74Schristos UDItype __carry = 0; \ 139475fd0b74Schristos __asm__ ("addcc\t%r5,%6,%1\n\t" \ 139575fd0b74Schristos "add\t%r3,%4,%0\n\t" \ 139675fd0b74Schristos "movcs\t%%xcc, 1, %2\n\t" \ 139775fd0b74Schristos "add\t%0, %2, %0" \ 139875fd0b74Schristos : "=r" ((UDItype)(sh)), \ 139975fd0b74Schristos "=&r" ((UDItype)(sl)), \ 140075fd0b74Schristos "+r" (__carry) \ 140175fd0b74Schristos : "%rJ" ((UDItype)(ah)), \ 140275fd0b74Schristos "rI" ((UDItype)(bh)), \ 140375fd0b74Schristos "%rJ" ((UDItype)(al)), \ 140475fd0b74Schristos "rI" ((UDItype)(bl)) \ 140575fd0b74Schristos __CLOBBER_CC); \ 140675fd0b74Schristos } while (0) 140775fd0b74Schristos 140875fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 140975fd0b74Schristos do { \ 141075fd0b74Schristos UDItype __carry = 0; \ 141175fd0b74Schristos __asm__ ("subcc\t%r5,%6,%1\n\t" \ 141275fd0b74Schristos "sub\t%r3,%4,%0\n\t" \ 141375fd0b74Schristos "movcs\t%%xcc, 1, %2\n\t" \ 141475fd0b74Schristos "sub\t%0, %2, %0" \ 141575fd0b74Schristos : "=r" ((UDItype)(sh)), \ 141675fd0b74Schristos "=&r" ((UDItype)(sl)), \ 141775fd0b74Schristos "+r" (__carry) \ 141875fd0b74Schristos : "%rJ" ((UDItype)(ah)), \ 141975fd0b74Schristos "rI" ((UDItype)(bh)), \ 142075fd0b74Schristos "%rJ" ((UDItype)(al)), \ 142175fd0b74Schristos "rI" ((UDItype)(bl)) \ 142275fd0b74Schristos __CLOBBER_CC); \ 142375fd0b74Schristos } while (0) 142475fd0b74Schristos 142575fd0b74Schristos #define umul_ppmm(wh, wl, u, v) \ 142675fd0b74Schristos do { \ 142775fd0b74Schristos UDItype tmp1, tmp2, tmp3, tmp4; \ 142875fd0b74Schristos __asm__ __volatile__ ( \ 142975fd0b74Schristos "srl %7,0,%3\n\t" \ 143075fd0b74Schristos "mulx %3,%6,%1\n\t" \ 143175fd0b74Schristos "srlx %6,32,%2\n\t" \ 143275fd0b74Schristos "mulx %2,%3,%4\n\t" \ 143375fd0b74Schristos "sllx %4,32,%5\n\t" \ 143475fd0b74Schristos "srl %6,0,%3\n\t" \ 143575fd0b74Schristos "sub %1,%5,%5\n\t" \ 143675fd0b74Schristos "srlx %5,32,%5\n\t" \ 143775fd0b74Schristos "addcc %4,%5,%4\n\t" \ 143875fd0b74Schristos "srlx %7,32,%5\n\t" \ 143975fd0b74Schristos "mulx %3,%5,%3\n\t" \ 144075fd0b74Schristos "mulx %2,%5,%5\n\t" \ 144175fd0b74Schristos "sethi %%hi(0x80000000),%2\n\t" \ 144275fd0b74Schristos "addcc %4,%3,%4\n\t" \ 144375fd0b74Schristos "srlx %4,32,%4\n\t" \ 144475fd0b74Schristos "add %2,%2,%2\n\t" \ 144575fd0b74Schristos "movcc %%xcc,%%g0,%2\n\t" \ 144675fd0b74Schristos "addcc %5,%4,%5\n\t" \ 144775fd0b74Schristos "sllx %3,32,%3\n\t" \ 144875fd0b74Schristos "add %1,%3,%1\n\t" \ 144975fd0b74Schristos "add %5,%2,%0" \ 145075fd0b74Schristos : "=r" ((UDItype)(wh)), \ 145175fd0b74Schristos "=&r" ((UDItype)(wl)), \ 145275fd0b74Schristos "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ 145375fd0b74Schristos : "r" ((UDItype)(u)), \ 145475fd0b74Schristos "r" ((UDItype)(v)) \ 145575fd0b74Schristos __CLOBBER_CC); \ 145675fd0b74Schristos } while (0) 145775fd0b74Schristos #define UMUL_TIME 96 145875fd0b74Schristos #define UDIV_TIME 230 145975fd0b74Schristos #endif /* sparc64 */ 146075fd0b74Schristos 146175fd0b74Schristos #if defined (__vax__) && W_TYPE_SIZE == 32 146275fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 146375fd0b74Schristos __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ 146475fd0b74Schristos : "=g" ((USItype) (sh)), \ 146575fd0b74Schristos "=&g" ((USItype) (sl)) \ 146675fd0b74Schristos : "%0" ((USItype) (ah)), \ 146775fd0b74Schristos "g" ((USItype) (bh)), \ 146875fd0b74Schristos "%1" ((USItype) (al)), \ 146975fd0b74Schristos "g" ((USItype) (bl))) 147075fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 147175fd0b74Schristos __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ 147275fd0b74Schristos : "=g" ((USItype) (sh)), \ 147375fd0b74Schristos "=&g" ((USItype) (sl)) \ 147475fd0b74Schristos : "0" ((USItype) (ah)), \ 147575fd0b74Schristos "g" ((USItype) (bh)), \ 147675fd0b74Schristos "1" ((USItype) (al)), \ 147775fd0b74Schristos "g" ((USItype) (bl))) 147875fd0b74Schristos #define umul_ppmm(xh, xl, m0, m1) \ 147975fd0b74Schristos do { \ 148075fd0b74Schristos union { \ 148175fd0b74Schristos UDItype __ll; \ 148275fd0b74Schristos struct {USItype __l, __h;} __i; \ 148375fd0b74Schristos } __xx; \ 148475fd0b74Schristos USItype __m0 = (m0), __m1 = (m1); \ 148575fd0b74Schristos __asm__ ("emul %1,%2,$0,%0" \ 148675fd0b74Schristos : "=r" (__xx.__ll) \ 148775fd0b74Schristos : "g" (__m0), \ 148875fd0b74Schristos "g" (__m1)); \ 148975fd0b74Schristos (xh) = __xx.__i.__h; \ 149075fd0b74Schristos (xl) = __xx.__i.__l; \ 149175fd0b74Schristos (xh) += ((((SItype) __m0 >> 31) & __m1) \ 149275fd0b74Schristos + (((SItype) __m1 >> 31) & __m0)); \ 149375fd0b74Schristos } while (0) 149475fd0b74Schristos #define sdiv_qrnnd(q, r, n1, n0, d) \ 149575fd0b74Schristos do { \ 149675fd0b74Schristos union {DItype __ll; \ 149775fd0b74Schristos struct {SItype __l, __h;} __i; \ 149875fd0b74Schristos } __xx; \ 149975fd0b74Schristos __xx.__i.__h = n1; __xx.__i.__l = n0; \ 150075fd0b74Schristos __asm__ ("ediv %3,%2,%0,%1" \ 150175fd0b74Schristos : "=g" (q), "=g" (r) \ 150275fd0b74Schristos : "g" (__xx.__ll), "g" (d)); \ 150375fd0b74Schristos } while (0) 150475fd0b74Schristos #endif /* __vax__ */ 150575fd0b74Schristos 150675fd0b74Schristos #ifdef _TMS320C6X 150775fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 150875fd0b74Schristos do \ 150975fd0b74Schristos { \ 151075fd0b74Schristos UDItype __ll; \ 151175fd0b74Schristos __asm__ ("addu .l1 %1, %2, %0" \ 151275fd0b74Schristos : "=a" (__ll) : "a" (al), "a" (bl)); \ 151375fd0b74Schristos (sl) = (USItype)__ll; \ 151475fd0b74Schristos (sh) = ((USItype)(__ll >> 32)) + (ah) + (bh); \ 151575fd0b74Schristos } \ 151675fd0b74Schristos while (0) 151775fd0b74Schristos 151875fd0b74Schristos #ifdef _TMS320C6400_PLUS 151975fd0b74Schristos #define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) 152075fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 152175fd0b74Schristos do { \ 152275fd0b74Schristos UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ 152375fd0b74Schristos (w1) = (USItype) (__x >> 32); \ 152475fd0b74Schristos (w0) = (USItype) (__x); \ 152575fd0b74Schristos } while (0) 152675fd0b74Schristos #endif /* _TMS320C6400_PLUS */ 152775fd0b74Schristos 152875fd0b74Schristos #define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) 152975fd0b74Schristos #ifdef _TMS320C6400 153075fd0b74Schristos #define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) 153175fd0b74Schristos #endif 153275fd0b74Schristos #define UMUL_TIME 4 153375fd0b74Schristos #define UDIV_TIME 40 153475fd0b74Schristos #endif /* _TMS320C6X */ 153575fd0b74Schristos 153675fd0b74Schristos #if defined (__xtensa__) && W_TYPE_SIZE == 32 153775fd0b74Schristos /* This code is not Xtensa-configuration-specific, so rely on the compiler 153875fd0b74Schristos to expand builtin functions depending on what configuration features 153975fd0b74Schristos are available. This avoids library calls when the operation can be 154075fd0b74Schristos performed in-line. */ 154175fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 154275fd0b74Schristos do { \ 154375fd0b74Schristos DWunion __w; \ 154475fd0b74Schristos __w.ll = __builtin_umulsidi3 (u, v); \ 154575fd0b74Schristos w1 = __w.s.high; \ 154675fd0b74Schristos w0 = __w.s.low; \ 154775fd0b74Schristos } while (0) 154875fd0b74Schristos #define __umulsidi3(u, v) __builtin_umulsidi3 (u, v) 154975fd0b74Schristos #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) 155075fd0b74Schristos #define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) 155175fd0b74Schristos #endif /* __xtensa__ */ 155275fd0b74Schristos 155375fd0b74Schristos #if defined xstormy16 155475fd0b74Schristos extern UHItype __stormy16_count_leading_zeros (UHItype); 155575fd0b74Schristos #define count_leading_zeros(count, x) \ 155675fd0b74Schristos do \ 155775fd0b74Schristos { \ 155875fd0b74Schristos UHItype size; \ 155975fd0b74Schristos \ 156075fd0b74Schristos /* We assume that W_TYPE_SIZE is a multiple of 16... */ \ 156175fd0b74Schristos for ((count) = 0, size = W_TYPE_SIZE; size; size -= 16) \ 156275fd0b74Schristos { \ 156375fd0b74Schristos UHItype c; \ 156475fd0b74Schristos \ 156575fd0b74Schristos c = __clzhi2 ((x) >> (size - 16)); \ 156675fd0b74Schristos (count) += c; \ 156775fd0b74Schristos if (c != 16) \ 156875fd0b74Schristos break; \ 156975fd0b74Schristos } \ 157075fd0b74Schristos } \ 157175fd0b74Schristos while (0) 157275fd0b74Schristos #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE 157375fd0b74Schristos #endif 157475fd0b74Schristos 157575fd0b74Schristos #if defined (__z8000__) && W_TYPE_SIZE == 16 157675fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 157775fd0b74Schristos __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ 157875fd0b74Schristos : "=r" ((unsigned int)(sh)), \ 157975fd0b74Schristos "=&r" ((unsigned int)(sl)) \ 158075fd0b74Schristos : "%0" ((unsigned int)(ah)), \ 158175fd0b74Schristos "r" ((unsigned int)(bh)), \ 158275fd0b74Schristos "%1" ((unsigned int)(al)), \ 158375fd0b74Schristos "rQR" ((unsigned int)(bl))) 158475fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 158575fd0b74Schristos __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ 158675fd0b74Schristos : "=r" ((unsigned int)(sh)), \ 158775fd0b74Schristos "=&r" ((unsigned int)(sl)) \ 158875fd0b74Schristos : "0" ((unsigned int)(ah)), \ 158975fd0b74Schristos "r" ((unsigned int)(bh)), \ 159075fd0b74Schristos "1" ((unsigned int)(al)), \ 159175fd0b74Schristos "rQR" ((unsigned int)(bl))) 159275fd0b74Schristos #define umul_ppmm(xh, xl, m0, m1) \ 159375fd0b74Schristos do { \ 159475fd0b74Schristos union {long int __ll; \ 159575fd0b74Schristos struct {unsigned int __h, __l;} __i; \ 159675fd0b74Schristos } __xx; \ 159775fd0b74Schristos unsigned int __m0 = (m0), __m1 = (m1); \ 159875fd0b74Schristos __asm__ ("mult %S0,%H3" \ 159975fd0b74Schristos : "=r" (__xx.__i.__h), \ 160075fd0b74Schristos "=r" (__xx.__i.__l) \ 160175fd0b74Schristos : "%1" (__m0), \ 160275fd0b74Schristos "rQR" (__m1)); \ 160375fd0b74Schristos (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ 160475fd0b74Schristos (xh) += ((((signed int) __m0 >> 15) & __m1) \ 160575fd0b74Schristos + (((signed int) __m1 >> 15) & __m0)); \ 160675fd0b74Schristos } while (0) 160775fd0b74Schristos #endif /* __z8000__ */ 160875fd0b74Schristos 160975fd0b74Schristos #endif /* __GNUC__ */ 161075fd0b74Schristos 161175fd0b74Schristos /* If this machine has no inline assembler, use C macros. */ 161275fd0b74Schristos 161375fd0b74Schristos #if !defined (add_ssaaaa) 161475fd0b74Schristos #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 161575fd0b74Schristos do { \ 161675fd0b74Schristos UWtype __x; \ 161775fd0b74Schristos __x = (al) + (bl); \ 161875fd0b74Schristos (sh) = (ah) + (bh) + (__x < (al)); \ 161975fd0b74Schristos (sl) = __x; \ 162075fd0b74Schristos } while (0) 162175fd0b74Schristos #endif 162275fd0b74Schristos 162375fd0b74Schristos #if !defined (sub_ddmmss) 162475fd0b74Schristos #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 162575fd0b74Schristos do { \ 162675fd0b74Schristos UWtype __x; \ 162775fd0b74Schristos __x = (al) - (bl); \ 162875fd0b74Schristos (sh) = (ah) - (bh) - (__x > (al)); \ 162975fd0b74Schristos (sl) = __x; \ 163075fd0b74Schristos } while (0) 163175fd0b74Schristos #endif 163275fd0b74Schristos 163375fd0b74Schristos /* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of 163475fd0b74Schristos smul_ppmm. */ 163575fd0b74Schristos #if !defined (umul_ppmm) && defined (smul_ppmm) 163675fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 163775fd0b74Schristos do { \ 163875fd0b74Schristos UWtype __w1; \ 163975fd0b74Schristos UWtype __xm0 = (u), __xm1 = (v); \ 164075fd0b74Schristos smul_ppmm (__w1, w0, __xm0, __xm1); \ 164175fd0b74Schristos (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ 164275fd0b74Schristos + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ 164375fd0b74Schristos } while (0) 164475fd0b74Schristos #endif 164575fd0b74Schristos 164675fd0b74Schristos /* If we still don't have umul_ppmm, define it using plain C. */ 164775fd0b74Schristos #if !defined (umul_ppmm) 164875fd0b74Schristos #define umul_ppmm(w1, w0, u, v) \ 164975fd0b74Schristos do { \ 165075fd0b74Schristos UWtype __x0, __x1, __x2, __x3; \ 165175fd0b74Schristos UHWtype __ul, __vl, __uh, __vh; \ 165275fd0b74Schristos \ 165375fd0b74Schristos __ul = __ll_lowpart (u); \ 165475fd0b74Schristos __uh = __ll_highpart (u); \ 165575fd0b74Schristos __vl = __ll_lowpart (v); \ 165675fd0b74Schristos __vh = __ll_highpart (v); \ 165775fd0b74Schristos \ 165875fd0b74Schristos __x0 = (UWtype) __ul * __vl; \ 165975fd0b74Schristos __x1 = (UWtype) __ul * __vh; \ 166075fd0b74Schristos __x2 = (UWtype) __uh * __vl; \ 166175fd0b74Schristos __x3 = (UWtype) __uh * __vh; \ 166275fd0b74Schristos \ 166375fd0b74Schristos __x1 += __ll_highpart (__x0);/* this can't give carry */ \ 166475fd0b74Schristos __x1 += __x2; /* but this indeed can */ \ 166575fd0b74Schristos if (__x1 < __x2) /* did we get it? */ \ 166675fd0b74Schristos __x3 += __ll_B; /* yes, add it in the proper pos. */ \ 166775fd0b74Schristos \ 166875fd0b74Schristos (w1) = __x3 + __ll_highpart (__x1); \ 166975fd0b74Schristos (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ 167075fd0b74Schristos } while (0) 167175fd0b74Schristos #endif 167275fd0b74Schristos 167375fd0b74Schristos #if !defined (__umulsidi3) 167475fd0b74Schristos #define __umulsidi3(u, v) \ 167575fd0b74Schristos ({DWunion __w; \ 167675fd0b74Schristos umul_ppmm (__w.s.high, __w.s.low, u, v); \ 167775fd0b74Schristos __w.ll; }) 167875fd0b74Schristos #endif 167975fd0b74Schristos 168075fd0b74Schristos /* Define this unconditionally, so it can be used for debugging. */ 168175fd0b74Schristos #define __udiv_qrnnd_c(q, r, n1, n0, d) \ 168275fd0b74Schristos do { \ 168375fd0b74Schristos UWtype __d1, __d0, __q1, __q0; \ 168475fd0b74Schristos UWtype __r1, __r0, __m; \ 168575fd0b74Schristos __d1 = __ll_highpart (d); \ 168675fd0b74Schristos __d0 = __ll_lowpart (d); \ 168775fd0b74Schristos \ 168875fd0b74Schristos __r1 = (n1) % __d1; \ 168975fd0b74Schristos __q1 = (n1) / __d1; \ 169075fd0b74Schristos __m = (UWtype) __q1 * __d0; \ 169175fd0b74Schristos __r1 = __r1 * __ll_B | __ll_highpart (n0); \ 169275fd0b74Schristos if (__r1 < __m) \ 169375fd0b74Schristos { \ 169475fd0b74Schristos __q1--, __r1 += (d); \ 169575fd0b74Schristos if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ 169675fd0b74Schristos if (__r1 < __m) \ 169775fd0b74Schristos __q1--, __r1 += (d); \ 169875fd0b74Schristos } \ 169975fd0b74Schristos __r1 -= __m; \ 170075fd0b74Schristos \ 170175fd0b74Schristos __r0 = __r1 % __d1; \ 170275fd0b74Schristos __q0 = __r1 / __d1; \ 170375fd0b74Schristos __m = (UWtype) __q0 * __d0; \ 170475fd0b74Schristos __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ 170575fd0b74Schristos if (__r0 < __m) \ 170675fd0b74Schristos { \ 170775fd0b74Schristos __q0--, __r0 += (d); \ 170875fd0b74Schristos if (__r0 >= (d)) \ 170975fd0b74Schristos if (__r0 < __m) \ 171075fd0b74Schristos __q0--, __r0 += (d); \ 171175fd0b74Schristos } \ 171275fd0b74Schristos __r0 -= __m; \ 171375fd0b74Schristos \ 171475fd0b74Schristos (q) = (UWtype) __q1 * __ll_B | __q0; \ 171575fd0b74Schristos (r) = __r0; \ 171675fd0b74Schristos } while (0) 171775fd0b74Schristos 171875fd0b74Schristos /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through 171975fd0b74Schristos __udiv_w_sdiv (defined in libgcc or elsewhere). */ 172075fd0b74Schristos #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) 172175fd0b74Schristos #define udiv_qrnnd(q, r, nh, nl, d) \ 172275fd0b74Schristos do { \ 172375fd0b74Schristos extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype); \ 172475fd0b74Schristos UWtype __r; \ 172575fd0b74Schristos (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ 172675fd0b74Schristos (r) = __r; \ 172775fd0b74Schristos } while (0) 172875fd0b74Schristos #endif 172975fd0b74Schristos 173075fd0b74Schristos /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ 173175fd0b74Schristos #if !defined (udiv_qrnnd) 173275fd0b74Schristos #define UDIV_NEEDS_NORMALIZATION 1 173375fd0b74Schristos #define udiv_qrnnd __udiv_qrnnd_c 173475fd0b74Schristos #endif 173575fd0b74Schristos 173675fd0b74Schristos #if !defined (count_leading_zeros) 173775fd0b74Schristos #define count_leading_zeros(count, x) \ 173875fd0b74Schristos do { \ 173975fd0b74Schristos UWtype __xr = (x); \ 174075fd0b74Schristos UWtype __a; \ 174175fd0b74Schristos \ 174275fd0b74Schristos if (W_TYPE_SIZE <= 32) \ 174375fd0b74Schristos { \ 174475fd0b74Schristos __a = __xr < ((UWtype)1<<2*__BITS4) \ 174575fd0b74Schristos ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ 174675fd0b74Schristos : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ 174775fd0b74Schristos } \ 174875fd0b74Schristos else \ 174975fd0b74Schristos { \ 175075fd0b74Schristos for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ 175175fd0b74Schristos if (((__xr >> __a) & 0xff) != 0) \ 175275fd0b74Schristos break; \ 175375fd0b74Schristos } \ 175475fd0b74Schristos \ 175575fd0b74Schristos (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ 175675fd0b74Schristos } while (0) 175775fd0b74Schristos #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE 175875fd0b74Schristos #endif 175975fd0b74Schristos 176075fd0b74Schristos #if !defined (count_trailing_zeros) 176175fd0b74Schristos /* Define count_trailing_zeros using count_leading_zeros. The latter might be 176275fd0b74Schristos defined in asm, but if it is not, the C version above is good enough. */ 176375fd0b74Schristos #define count_trailing_zeros(count, x) \ 176475fd0b74Schristos do { \ 176575fd0b74Schristos UWtype __ctz_x = (x); \ 176675fd0b74Schristos UWtype __ctz_c; \ 176775fd0b74Schristos count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ 176875fd0b74Schristos (count) = W_TYPE_SIZE - 1 - __ctz_c; \ 176975fd0b74Schristos } while (0) 177075fd0b74Schristos #endif 177175fd0b74Schristos 177275fd0b74Schristos #ifndef UDIV_NEEDS_NORMALIZATION 177375fd0b74Schristos #define UDIV_NEEDS_NORMALIZATION 0 177475fd0b74Schristos #endif 1775