Blame include/longlong.h

Packit bbfece
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
Packit bbfece
   Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit bbfece
Packit bbfece
   This file is part of the GNU C Library.
Packit bbfece
Packit bbfece
   The GNU C Library is free software; you can redistribute it and/or
Packit bbfece
   modify it under the terms of the GNU Lesser General Public
Packit bbfece
   License as published by the Free Software Foundation; either
Packit bbfece
   version 2.1 of the License, or (at your option) any later version.
Packit bbfece
Packit bbfece
   In addition to the permissions in the GNU Lesser General Public
Packit bbfece
   License, the Free Software Foundation gives you unlimited
Packit bbfece
   permission to link the compiled version of this file into
Packit bbfece
   combinations with other programs, and to distribute those
Packit bbfece
   combinations without any restriction coming from the use of this
Packit bbfece
   file.  (The Lesser General Public License restrictions do apply in
Packit bbfece
   other respects; for example, they cover modification of the file,
Packit bbfece
   and distribution when not linked into a combine executable.)
Packit bbfece
Packit bbfece
   The GNU C Library is distributed in the hope that it will be useful,
Packit bbfece
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bbfece
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit bbfece
   Lesser General Public License for more details.
Packit bbfece
Packit bbfece
   You should have received a copy of the GNU Lesser General Public
Packit bbfece
   License along with the GNU C Library; if not, see
Packit bbfece
   <http://www.gnu.org/licenses/>.  */
Packit bbfece
Packit bbfece
/* You have to define the following before including this file:
Packit bbfece
Packit bbfece
   UWtype -- An unsigned type, default type for operations (typically a "word")
Packit bbfece
   UHWtype -- An unsigned type, at least half the size of UWtype.
Packit bbfece
   UDWtype -- An unsigned type, at least twice as large a UWtype
Packit bbfece
   W_TYPE_SIZE -- size in bits of UWtype
Packit bbfece
Packit bbfece
   UQItype -- Unsigned 8 bit type.
Packit bbfece
   SItype, USItype -- Signed and unsigned 32 bit types.
Packit bbfece
   DItype, UDItype -- Signed and unsigned 64 bit types.
Packit bbfece
Packit bbfece
   On a 32 bit machine UWtype should typically be USItype;
Packit bbfece
   on a 64 bit machine, UWtype should typically be UDItype.  */
Packit bbfece
Packit bbfece
#define __BITS4 (W_TYPE_SIZE / 4)
Packit bbfece
#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
Packit bbfece
#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
Packit bbfece
#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
Packit bbfece
Packit bbfece
#ifndef W_TYPE_SIZE
Packit bbfece
#define W_TYPE_SIZE	32
Packit bbfece
#define UWtype		USItype
Packit bbfece
#define UHWtype		USItype
Packit bbfece
#define UDWtype		UDItype
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* Used in glibc only.  */
Packit bbfece
#ifndef attribute_hidden
Packit bbfece
#define attribute_hidden
Packit bbfece
#endif
Packit bbfece
Packit bbfece
extern const UQItype __clz_tab[256] attribute_hidden;
Packit bbfece
Packit bbfece
/* Define auxiliary asm macros.
Packit bbfece
Packit bbfece
   1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
Packit bbfece
   UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
Packit bbfece
   word product in HIGH_PROD and LOW_PROD.
Packit bbfece
Packit bbfece
   2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
Packit bbfece
   UDWtype product.  This is just a variant of umul_ppmm.
Packit bbfece
Packit bbfece
   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
Packit bbfece
   denominator) divides a UDWtype, composed by the UWtype integers
Packit bbfece
   HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
Packit bbfece
   in QUOTIENT and the remainder in REMAINDER.  HIGH_NUMERATOR must be less
Packit bbfece
   than DENOMINATOR for correct operation.  If, in addition, the most
Packit bbfece
   significant bit of DENOMINATOR must be 1, then the pre-processor symbol
Packit bbfece
   UDIV_NEEDS_NORMALIZATION is defined to 1.
Packit bbfece
Packit bbfece
   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
Packit bbfece
   denominator).  Like udiv_qrnnd but the numbers are signed.  The quotient
Packit bbfece
   is rounded towards 0.
Packit bbfece
Packit bbfece
   5) count_leading_zeros(count, x) counts the number of zero-bits from the
Packit bbfece
   msb to the first nonzero bit in the UWtype X.  This is the number of
Packit bbfece
   steps X needs to be shifted left to set the msb.  Undefined for X == 0,
Packit bbfece
   unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
Packit bbfece
Packit bbfece
   6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
Packit bbfece
   from the least significant end.
Packit bbfece
Packit bbfece
   7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
Packit bbfece
   high_addend_2, low_addend_2) adds two UWtype integers, composed by
Packit bbfece
   HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
Packit bbfece
   respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
Packit bbfece
   (i.e. carry out) is not stored anywhere, and is lost.
Packit bbfece
Packit bbfece
   8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
Packit bbfece
   high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
Packit bbfece
   composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
Packit bbfece
   LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
Packit bbfece
   and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
Packit bbfece
   and is lost.
Packit bbfece
Packit bbfece
   If any of these macros are left undefined for a particular CPU,
Packit bbfece
   C macros are used.  */
Packit bbfece
Packit bbfece
/* The CPUs come in alphabetical order below.
Packit bbfece
Packit bbfece
   Please add support for more CPUs here, or improve the current support
Packit bbfece
   for the CPUs below!
Packit bbfece
   (E.g. WE32100, IBM360.)  */
Packit bbfece
Packit bbfece
#if defined (__GNUC__) && !defined (NO_ASM)
Packit bbfece
Packit bbfece
/* We sometimes need to clobber "cc" with gcc2, but that would not be
Packit bbfece
   understood by gcc1.  Use cpp to avoid major code duplication.  */
Packit bbfece
#if __GNUC__ < 2
Packit bbfece
#define __CLOBBER_CC
Packit bbfece
#define __AND_CLOBBER_CC
Packit bbfece
#else /* __GNUC__ >= 2 */
Packit bbfece
#define __CLOBBER_CC : "cc"
Packit bbfece
#define __AND_CLOBBER_CC , "cc"
Packit bbfece
#endif /* __GNUC__ < 2 */
Packit bbfece
Packit bbfece
#if defined (__aarch64__)
Packit bbfece
Packit bbfece
#if W_TYPE_SIZE == 32
Packit bbfece
#define count_leading_zeros(COUNT, X)	((COUNT) = __builtin_clz (X))
Packit bbfece
#define count_trailing_zeros(COUNT, X)   ((COUNT) = __builtin_ctz (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif /* W_TYPE_SIZE == 32 */
Packit bbfece
Packit bbfece
#if W_TYPE_SIZE == 64
Packit bbfece
#define count_leading_zeros(COUNT, X)	((COUNT) = __builtin_clzll (X))
Packit bbfece
#define count_trailing_zeros(COUNT, X)   ((COUNT) = __builtin_ctzll (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 64
Packit bbfece
#endif /* W_TYPE_SIZE == 64 */
Packit bbfece
Packit bbfece
#endif /* __aarch64__ */
Packit bbfece
Packit bbfece
#if defined (__alpha) && W_TYPE_SIZE == 64
Packit bbfece
/* There is a bug in g++ before version 5 that
Packit bbfece
   errors on __builtin_alpha_umulh.  */
Packit bbfece
#if !defined(__cplusplus) || __GNUC__ >= 5
Packit bbfece
#define umul_ppmm(ph, pl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    UDItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    (ph) = __builtin_alpha_umulh (__m0, __m1);				\
Packit bbfece
    (pl) = __m0 * __m1;							\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 46
Packit bbfece
#endif /* !c++ */
Packit bbfece
#ifndef LONGLONG_STANDALONE
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  do { UDItype __r;							\
Packit bbfece
    (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));				\
Packit bbfece
    (r) = __r;								\
Packit bbfece
  } while (0)
Packit bbfece
extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
Packit bbfece
#define UDIV_TIME 220
Packit bbfece
#endif /* LONGLONG_STANDALONE */
Packit bbfece
#ifdef __alpha_cix__
Packit bbfece
#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clzl (X))
Packit bbfece
#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctzl (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 64
Packit bbfece
#else
Packit bbfece
#define count_leading_zeros(COUNT,X) \
Packit bbfece
  do {									\
Packit bbfece
    UDItype __xr = (X), __t, __a;					\
Packit bbfece
    __t = __builtin_alpha_cmpbge (0, __xr);				\
Packit bbfece
    __a = __clz_tab[__t ^ 0xff] - 1;					\
Packit bbfece
    __t = __builtin_alpha_extbl (__xr, __a);				\
Packit bbfece
    (COUNT) = 64 - (__clz_tab[__t] + __a*8);				\
Packit bbfece
  } while (0)
Packit bbfece
#define count_trailing_zeros(COUNT,X) \
Packit bbfece
  do {									\
Packit bbfece
    UDItype __xr = (X), __t, __a;					\
Packit bbfece
    __t = __builtin_alpha_cmpbge (0, __xr);				\
Packit bbfece
    __t = ~__t & -~__t;							\
Packit bbfece
    __a = ((__t & 0xCC) != 0) * 2;					\
Packit bbfece
    __a += ((__t & 0xF0) != 0) * 4;					\
Packit bbfece
    __a += ((__t & 0xAA) != 0);						\
Packit bbfece
    __t = __builtin_alpha_extbl (__xr, __a);				\
Packit bbfece
    __a <<= 3;								\
Packit bbfece
    __t &= -__t;							\
Packit bbfece
    __a += ((__t & 0xCC) != 0) * 2;					\
Packit bbfece
    __a += ((__t & 0xF0) != 0) * 4;					\
Packit bbfece
    __a += ((__t & 0xAA) != 0);						\
Packit bbfece
    (COUNT) = __a;							\
Packit bbfece
  } while (0)
Packit bbfece
#endif /* __alpha_cix__ */
Packit bbfece
#endif /* __alpha */
Packit bbfece
Packit bbfece
#if defined (__arc__) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("add.f	%1, %4, %5\n\tadc	%0, %2, %3"		\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%r" ((USItype) (ah)),					\
Packit bbfece
	     "rICal" ((USItype) (bh)),					\
Packit bbfece
	     "%r" ((USItype) (al)),					\
Packit bbfece
	     "rICal" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("sub.f	%1, %4, %5\n\tsbc	%0, %2, %3"		\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "r" ((USItype) (ah)),					\
Packit bbfece
	     "rICal" ((USItype) (bh)),					\
Packit bbfece
	     "r" ((USItype) (al)),					\
Packit bbfece
	     "rICal" ((USItype) (bl)))
Packit bbfece
Packit bbfece
#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
Packit bbfece
#ifdef __ARC_NORM__
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  do									\
Packit bbfece
    {									\
Packit bbfece
      SItype c_;							\
Packit bbfece
									\
Packit bbfece
      __asm__ ("norm.f\t%0,%1\n\tmov.mi\t%0,-1" : "=r" (c_) : "r" (x) : "cc");\
Packit bbfece
      (count) = c_ + 1;							\
Packit bbfece
    }									\
Packit bbfece
  while (0)
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif /* __ARC_NORM__ */
Packit bbfece
#endif /* __arc__ */
Packit bbfece
Packit bbfece
#if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \
Packit bbfece
 && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("adds	%1, %4, %5\n\tadc	%0, %2, %3"		\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%r" ((USItype) (ah)),					\
Packit bbfece
	     "rI" ((USItype) (bh)),					\
Packit bbfece
	     "%r" ((USItype) (al)),					\
Packit bbfece
	     "rI" ((USItype) (bl)) __CLOBBER_CC)
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("subs	%1, %4, %5\n\tsbc	%0, %2, %3"		\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "r" ((USItype) (ah)),					\
Packit bbfece
	     "rI" ((USItype) (bh)),					\
Packit bbfece
	     "r" ((USItype) (al)),					\
Packit bbfece
	     "rI" ((USItype) (bl)) __CLOBBER_CC)
Packit bbfece
# if defined(__ARM_ARCH_2__) || defined(__ARM_ARCH_2A__) \
Packit bbfece
     || defined(__ARM_ARCH_3__)
Packit bbfece
#  define umul_ppmm(xh, xl, a, b)					\
Packit bbfece
  do {									\
Packit bbfece
    register USItype __t0, __t1, __t2;					\
Packit bbfece
    __asm__ ("%@ Inlined umul_ppmm\n"					\
Packit bbfece
	   "	mov	%2, %5, lsr #16\n"				\
Packit bbfece
	   "	mov	%0, %6, lsr #16\n"				\
Packit bbfece
	   "	bic	%3, %5, %2, lsl #16\n"				\
Packit bbfece
	   "	bic	%4, %6, %0, lsl #16\n"				\
Packit bbfece
	   "	mul	%1, %3, %4\n"					\
Packit bbfece
	   "	mul	%4, %2, %4\n"					\
Packit bbfece
	   "	mul	%3, %0, %3\n"					\
Packit bbfece
	   "	mul	%0, %2, %0\n"					\
Packit bbfece
	   "	adds	%3, %4, %3\n"					\
Packit bbfece
	   "	addcs	%0, %0, #65536\n"				\
Packit bbfece
	   "	adds	%1, %1, %3, lsl #16\n"				\
Packit bbfece
	   "	adc	%0, %0, %3, lsr #16"				\
Packit bbfece
	   : "=&r" ((USItype) (xh)),					\
Packit bbfece
	     "=r" ((USItype) (xl)),					\
Packit bbfece
	     "=&r" (__t0), "=&r" (__t1), "=r" (__t2)			\
Packit bbfece
	   : "r" ((USItype) (a)),					\
Packit bbfece
	     "r" ((USItype) (b)) __CLOBBER_CC );			\
Packit bbfece
  } while (0)
Packit bbfece
#  define UMUL_TIME 20
Packit bbfece
# else
Packit bbfece
#  define umul_ppmm(xh, xl, a, b)					\
Packit bbfece
  do {									\
Packit bbfece
    /* Generate umull, under compiler control.  */			\
Packit bbfece
    register UDItype __t0 = (UDItype)(USItype)(a) * (USItype)(b);	\
Packit bbfece
    (xl) = (USItype)__t0;						\
Packit bbfece
    (xh) = (USItype)(__t0 >> 32);					\
Packit bbfece
  } while (0)
Packit bbfece
#  define UMUL_TIME 3
Packit bbfece
# endif
Packit bbfece
# define UDIV_TIME 100
Packit bbfece
#endif /* __arm__ */
Packit bbfece
Packit bbfece
#if defined(__arm__)
Packit bbfece
/* Let gcc decide how best to implement count_leading_zeros.  */
Packit bbfece
#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
Packit bbfece
#define count_trailing_zeros(COUNT,X)   ((COUNT) = __builtin_ctz (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if defined (__AVR__)
Packit bbfece
Packit bbfece
#if W_TYPE_SIZE == 16
Packit bbfece
#define count_leading_zeros(COUNT,X)  ((COUNT) = __builtin_clz (X))
Packit bbfece
#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 16
Packit bbfece
#endif /* W_TYPE_SIZE == 16 */
Packit bbfece
Packit bbfece
#if W_TYPE_SIZE == 32
Packit bbfece
#define count_leading_zeros(COUNT,X)  ((COUNT) = __builtin_clzl (X))
Packit bbfece
#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif /* W_TYPE_SIZE == 32 */
Packit bbfece
Packit bbfece
#if W_TYPE_SIZE == 64
Packit bbfece
#define count_leading_zeros(COUNT,X)  ((COUNT) = __builtin_clzll (X))
Packit bbfece
#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzll (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 64
Packit bbfece
#endif /* W_TYPE_SIZE == 64 */
Packit bbfece
Packit bbfece
#endif /* defined (__AVR__) */
Packit bbfece
Packit bbfece
#if defined (__CRIS__)
Packit bbfece
Packit bbfece
#if __CRIS_arch_version >= 3
Packit bbfece
#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif /* __CRIS_arch_version >= 3 */
Packit bbfece
Packit bbfece
#if __CRIS_arch_version >= 8
Packit bbfece
#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X))
Packit bbfece
#endif /* __CRIS_arch_version >= 8 */
Packit bbfece
Packit bbfece
#if __CRIS_arch_version >= 10
Packit bbfece
#define __umulsidi3(u,v) ((UDItype)(USItype) (u) * (UDItype)(USItype) (v))
Packit bbfece
#else
Packit bbfece
#define __umulsidi3 __umulsidi3
Packit bbfece
extern UDItype __umulsidi3 (USItype, USItype);
Packit bbfece
#endif /* __CRIS_arch_version >= 10 */
Packit bbfece
Packit bbfece
#define umul_ppmm(w1, w0, u, v)		\
Packit bbfece
  do {					\
Packit bbfece
    UDItype __x = __umulsidi3 (u, v);	\
Packit bbfece
    (w0) = (USItype) (__x);		\
Packit bbfece
    (w1) = (USItype) (__x >> 32);	\
Packit bbfece
  } while (0)
Packit bbfece
Packit bbfece
/* FIXME: defining add_ssaaaa and sub_ddmmss should be advantageous for
Packit bbfece
   DFmode ("double" intrinsics, avoiding two of the three insns handling
Packit bbfece
   carry), but defining them as open-code C composing and doing the
Packit bbfece
   operation in DImode (UDImode) shows that the DImode needs work:
Packit bbfece
   register pressure from requiring neighboring registers and the
Packit bbfece
   traffic to and from them come to dominate, in the 4.7 series.  */
Packit bbfece
Packit bbfece
#endif /* defined (__CRIS__) */
Packit bbfece
Packit bbfece
#if defined (__hppa) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0"				\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%rM" ((USItype) (ah)),					\
Packit bbfece
	     "rM" ((USItype) (bh)),					\
Packit bbfece
	     "%rM" ((USItype) (al)),					\
Packit bbfece
	     "rM" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0"				\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "rM" ((USItype) (ah)),					\
Packit bbfece
	     "rM" ((USItype) (bh)),					\
Packit bbfece
	     "rM" ((USItype) (al)),					\
Packit bbfece
	     "rM" ((USItype) (bl)))
Packit bbfece
#if defined (_PA_RISC1_1)
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  do {									\
Packit bbfece
    union								\
Packit bbfece
      {									\
Packit bbfece
	UDItype __f;							\
Packit bbfece
	struct {USItype __w1, __w0;} __w1w0;				\
Packit bbfece
      } __t;								\
Packit bbfece
    __asm__ ("xmpyu %1,%2,%0"						\
Packit bbfece
	     : "=x" (__t.__f)						\
Packit bbfece
	     : "x" ((USItype) (u)),					\
Packit bbfece
	       "x" ((USItype) (v)));					\
Packit bbfece
    (w1) = __t.__w1w0.__w1;						\
Packit bbfece
    (w0) = __t.__w1w0.__w0;						\
Packit bbfece
     } while (0)
Packit bbfece
#define UMUL_TIME 8
Packit bbfece
#else
Packit bbfece
#define UMUL_TIME 30
Packit bbfece
#endif
Packit bbfece
#define UDIV_TIME 40
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  do {									\
Packit bbfece
    USItype __tmp;							\
Packit bbfece
    __asm__ (								\
Packit bbfece
       "ldi		1,%0\n"						\
Packit bbfece
"	extru,=		%1,15,16,%%r0		; Bits 31..16 zero?\n"	\
Packit bbfece
"	extru,tr	%1,15,16,%1		; No.  Shift down, skip add.\n"\
Packit bbfece
"	ldo		16(%0),%0		; Yes.  Perform add.\n"	\
Packit bbfece
"	extru,=		%1,23,8,%%r0		; Bits 15..8 zero?\n"	\
Packit bbfece
"	extru,tr	%1,23,8,%1		; No.  Shift down, skip add.\n"\
Packit bbfece
"	ldo		8(%0),%0		; Yes.  Perform add.\n"	\
Packit bbfece
"	extru,=		%1,27,4,%%r0		; Bits 7..4 zero?\n"	\
Packit bbfece
"	extru,tr	%1,27,4,%1		; No.  Shift down, skip add.\n"\
Packit bbfece
"	ldo		4(%0),%0		; Yes.  Perform add.\n"	\
Packit bbfece
"	extru,=		%1,29,2,%%r0		; Bits 3..2 zero?\n"	\
Packit bbfece
"	extru,tr	%1,29,2,%1		; No.  Shift down, skip add.\n"\
Packit bbfece
"	ldo		2(%0),%0		; Yes.  Perform add.\n"	\
Packit bbfece
"	extru		%1,30,1,%1		; Extract bit 1.\n"	\
Packit bbfece
"	sub		%0,%1,%0		; Subtract it.\n"	\
Packit bbfece
	: "=r" (count), "=r" (__tmp) : "1" (x));			\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
Packit bbfece
#if !defined (__zarch__)
Packit bbfece
#define smul_ppmm(xh, xl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    union {DItype __ll;							\
Packit bbfece
	   struct {USItype __h, __l;} __i;				\
Packit bbfece
	  } __x;							\
Packit bbfece
    __asm__ ("lr %N0,%1\n\tmr %0,%2"					\
Packit bbfece
	     : "=&r" (__x.__ll)						\
Packit bbfece
	     : "r" (m0), "r" (m1));					\
Packit bbfece
    (xh) = __x.__i.__h; (xl) = __x.__i.__l;				\
Packit bbfece
  } while (0)
Packit bbfece
#define sdiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  do {									\
Packit bbfece
    union {DItype __ll;							\
Packit bbfece
	   struct {USItype __h, __l;} __i;				\
Packit bbfece
	  } __x;							\
Packit bbfece
    __x.__i.__h = n1; __x.__i.__l = n0;					\
Packit bbfece
    __asm__ ("dr %0,%2"							\
Packit bbfece
	     : "=r" (__x.__ll)						\
Packit bbfece
	     : "0" (__x.__ll), "r" (d));				\
Packit bbfece
    (q) = __x.__i.__l; (r) = __x.__i.__h;				\
Packit bbfece
  } while (0)
Packit bbfece
#else
Packit bbfece
#define smul_ppmm(xh, xl, m0, m1) \
Packit bbfece
  do {                                                                  \
Packit bbfece
    register SItype __r0 __asm__ ("0");					\
Packit bbfece
    register SItype __r1 __asm__ ("1") = (m0);				\
Packit bbfece
									\
Packit bbfece
    __asm__ ("mr\t%%r0,%3"                                              \
Packit bbfece
	     : "=r" (__r0), "=r" (__r1)					\
Packit bbfece
	     : "r"  (__r1),  "r" (m1));					\
Packit bbfece
    (xh) = __r0; (xl) = __r1;						\
Packit bbfece
  } while (0)
Packit bbfece
Packit bbfece
#define sdiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  do {									\
Packit bbfece
    register SItype __r0 __asm__ ("0") = (n1);				\
Packit bbfece
    register SItype __r1 __asm__ ("1") = (n0);				\
Packit bbfece
									\
Packit bbfece
    __asm__ ("dr\t%%r0,%4"                                              \
Packit bbfece
	     : "=r" (__r0), "=r" (__r1)					\
Packit bbfece
	     : "r" (__r0), "r" (__r1), "r" (d));			\
Packit bbfece
    (q) = __r1; (r) = __r0;						\
Packit bbfece
  } while (0)
Packit bbfece
#endif /* __zarch__ */
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}"		\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%0" ((USItype) (ah)),					\
Packit bbfece
	     "g" ((USItype) (bh)),					\
Packit bbfece
	     "%1" ((USItype) (al)),					\
Packit bbfece
	     "g" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}"		\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "0" ((USItype) (ah)),					\
Packit bbfece
	     "g" ((USItype) (bh)),					\
Packit bbfece
	     "1" ((USItype) (al)),					\
Packit bbfece
	     "g" ((USItype) (bl)))
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ ("mul{l} %3"							\
Packit bbfece
	   : "=a" ((USItype) (w0)),					\
Packit bbfece
	     "=d" ((USItype) (w1))					\
Packit bbfece
	   : "%0" ((USItype) (u)),					\
Packit bbfece
	     "rm" ((USItype) (v)))
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, dv) \
Packit bbfece
  __asm__ ("div{l} %4"							\
Packit bbfece
	   : "=a" ((USItype) (q)),					\
Packit bbfece
	     "=d" ((USItype) (r))					\
Packit bbfece
	   : "0" ((USItype) (n0)),					\
Packit bbfece
	     "1" ((USItype) (n1)),					\
Packit bbfece
	     "rm" ((USItype) (dv)))
Packit bbfece
#define count_leading_zeros(count, x)	((count) = __builtin_clz (x))
Packit bbfece
#define count_trailing_zeros(count, x)	((count) = __builtin_ctz (x))
Packit bbfece
#define UMUL_TIME 40
Packit bbfece
#define UDIV_TIME 40
Packit bbfece
#endif /* 80x86 */
Packit bbfece
Packit bbfece
#if defined (__x86_64__) && W_TYPE_SIZE == 64
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}"		\
Packit bbfece
	   : "=r" ((UDItype) (sh)),					\
Packit bbfece
	     "=&r" ((UDItype) (sl))					\
Packit bbfece
	   : "%0" ((UDItype) (ah)),					\
Packit bbfece
	     "rme" ((UDItype) (bh)),					\
Packit bbfece
	     "%1" ((UDItype) (al)),					\
Packit bbfece
	     "rme" ((UDItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}"		\
Packit bbfece
	   : "=r" ((UDItype) (sh)),					\
Packit bbfece
	     "=&r" ((UDItype) (sl))					\
Packit bbfece
	   : "0" ((UDItype) (ah)),					\
Packit bbfece
	     "rme" ((UDItype) (bh)),					\
Packit bbfece
	     "1" ((UDItype) (al)),					\
Packit bbfece
	     "rme" ((UDItype) (bl)))
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ ("mul{q} %3"							\
Packit bbfece
	   : "=a" ((UDItype) (w0)),					\
Packit bbfece
	     "=d" ((UDItype) (w1))					\
Packit bbfece
	   : "%0" ((UDItype) (u)),					\
Packit bbfece
	     "rm" ((UDItype) (v)))
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, dv) \
Packit bbfece
  __asm__ ("div{q} %4"							\
Packit bbfece
	   : "=a" ((UDItype) (q)),					\
Packit bbfece
	     "=d" ((UDItype) (r))					\
Packit bbfece
	   : "0" ((UDItype) (n0)),					\
Packit bbfece
	     "1" ((UDItype) (n1)),					\
Packit bbfece
	     "rm" ((UDItype) (dv)))
Packit bbfece
#define count_leading_zeros(count, x)	((count) = __builtin_clzll (x))
Packit bbfece
#define count_trailing_zeros(count, x)	((count) = __builtin_ctzll (x))
Packit bbfece
#define UMUL_TIME 40
Packit bbfece
#define UDIV_TIME 40
Packit bbfece
#endif /* x86_64 */
Packit bbfece
Packit bbfece
#if defined (__i960__) && W_TYPE_SIZE == 32
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  ({union {UDItype __ll;						\
Packit bbfece
	   struct {USItype __l, __h;} __i;				\
Packit bbfece
	  } __xx;							\
Packit bbfece
  __asm__ ("emul	%2,%1,%0"					\
Packit bbfece
	   : "=d" (__xx.__ll)						\
Packit bbfece
	   : "%dI" ((USItype) (u)),					\
Packit bbfece
	     "dI" ((USItype) (v)));					\
Packit bbfece
  (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
Packit bbfece
#define __umulsidi3(u, v) \
Packit bbfece
  ({UDItype __w;							\
Packit bbfece
    __asm__ ("emul	%2,%1,%0"					\
Packit bbfece
	     : "=d" (__w)						\
Packit bbfece
	     : "%dI" ((USItype) (u)),					\
Packit bbfece
	       "dI" ((USItype) (v)));					\
Packit bbfece
    __w; })
Packit bbfece
#endif /* __i960__ */
Packit bbfece
Packit bbfece
#if defined (__ia64) && W_TYPE_SIZE == 64
Packit bbfece
/* This form encourages gcc (pre-release 3.4 at least) to emit predicated
Packit bbfece
   "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency.  The generic
Packit bbfece
   code using "al
Packit bbfece
   register, which takes an extra cycle.  */
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl)				\
Packit bbfece
  do {									\
Packit bbfece
    UWtype __x;								\
Packit bbfece
    __x = (al) - (bl);							\
Packit bbfece
    if ((al) < (bl))							\
Packit bbfece
      (sh) = (ah) - (bh) - 1;						\
Packit bbfece
    else								\
Packit bbfece
      (sh) = (ah) - (bh);						\
Packit bbfece
    (sl) = __x;								\
Packit bbfece
  } while (0)
Packit bbfece
Packit bbfece
/* Do both product parts in assembly, since that gives better code with
Packit bbfece
   all gcc versions.  Some callers will just use the upper part, and in
Packit bbfece
   that situation we waste an instruction, but not any cycles.  */
Packit bbfece
#define umul_ppmm(ph, pl, m0, m1)					\
Packit bbfece
  __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0"		\
Packit bbfece
	   : "=&f" (ph), "=f" (pl)					\
Packit bbfece
	   : "f" (m0), "f" (m1))
Packit bbfece
#define count_leading_zeros(count, x)					\
Packit bbfece
  do {									\
Packit bbfece
    UWtype _x = (x), _y, _a, _c;					\
Packit bbfece
    __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x));		\
Packit bbfece
    __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y));		\
Packit bbfece
    _c = (_a - 1) << 3;							\
Packit bbfece
    _x >>= _c;								\
Packit bbfece
    if (_x >= 1 << 4)							\
Packit bbfece
      _x >>= 4, _c += 4;						\
Packit bbfece
    if (_x >= 1 << 2)							\
Packit bbfece
      _x >>= 2, _c += 2;						\
Packit bbfece
    _c += _x >> 1;							\
Packit bbfece
    (count) =  W_TYPE_SIZE - 1 - _c;					\
Packit bbfece
  } while (0)
Packit bbfece
/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1
Packit bbfece
   based, and we don't need a special case for x==0 here */
Packit bbfece
#define count_trailing_zeros(count, x)					\
Packit bbfece
  do {									\
Packit bbfece
    UWtype __ctz_x = (x);						\
Packit bbfece
    __asm__ ("popcnt %0 = %1"						\
Packit bbfece
	     : "=r" (count)						\
Packit bbfece
	     : "r" ((__ctz_x-1) & ~__ctz_x));				\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 14
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if defined (__M32R__) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  /* The cmp clears the condition bit.  */ \
Packit bbfece
  __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3"			\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "0" ((USItype) (ah)),					\
Packit bbfece
	     "r" ((USItype) (bh)),					\
Packit bbfece
	     "1" ((USItype) (al)),					\
Packit bbfece
	     "r" ((USItype) (bl))					\
Packit bbfece
	   : "cbit")
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  /* The cmp clears the condition bit.  */ \
Packit bbfece
  __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3"			\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "0" ((USItype) (ah)),					\
Packit bbfece
	     "r" ((USItype) (bh)),					\
Packit bbfece
	     "1" ((USItype) (al)),					\
Packit bbfece
	     "r" ((USItype) (bl))					\
Packit bbfece
	   : "cbit")
Packit bbfece
#endif /* __M32R__ */
Packit bbfece
Packit bbfece
#if defined (__mc68000__) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
Packit bbfece
	   : "=d" ((USItype) (sh)),					\
Packit bbfece
	     "=&d" ((USItype) (sl))					\
Packit bbfece
	   : "%0" ((USItype) (ah)),					\
Packit bbfece
	     "d" ((USItype) (bh)),					\
Packit bbfece
	     "%1" ((USItype) (al)),					\
Packit bbfece
	     "g" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0"				\
Packit bbfece
	   : "=d" ((USItype) (sh)),					\
Packit bbfece
	     "=&d" ((USItype) (sl))					\
Packit bbfece
	   : "0" ((USItype) (ah)),					\
Packit bbfece
	     "d" ((USItype) (bh)),					\
Packit bbfece
	     "1" ((USItype) (al)),					\
Packit bbfece
	     "g" ((USItype) (bl)))
Packit bbfece
Packit bbfece
/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r.  */
Packit bbfece
#if (defined (__mc68020__) && !defined (__mc68060__))
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ ("mulu%.l %3,%1:%0"						\
Packit bbfece
	   : "=d" ((USItype) (w0)),					\
Packit bbfece
	     "=d" ((USItype) (w1))					\
Packit bbfece
	   : "%0" ((USItype) (u)),					\
Packit bbfece
	     "dmi" ((USItype) (v)))
Packit bbfece
#define UMUL_TIME 45
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  __asm__ ("divu%.l %4,%1:%0"						\
Packit bbfece
	   : "=d" ((USItype) (q)),					\
Packit bbfece
	     "=d" ((USItype) (r))					\
Packit bbfece
	   : "0" ((USItype) (n0)),					\
Packit bbfece
	     "1" ((USItype) (n1)),					\
Packit bbfece
	     "dmi" ((USItype) (d)))
Packit bbfece
#define UDIV_TIME 90
Packit bbfece
#define sdiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  __asm__ ("divs%.l %4,%1:%0"						\
Packit bbfece
	   : "=d" ((USItype) (q)),					\
Packit bbfece
	     "=d" ((USItype) (r))					\
Packit bbfece
	   : "0" ((USItype) (n0)),					\
Packit bbfece
	     "1" ((USItype) (n1)),					\
Packit bbfece
	     "dmi" ((USItype) (d)))
Packit bbfece
Packit bbfece
#elif defined (__mcoldfire__) /* not mc68020 */
Packit bbfece
Packit bbfece
#define umul_ppmm(xh, xl, a, b) \
Packit bbfece
  __asm__ ("| Inlined umul_ppmm\n"					\
Packit bbfece
	   "	move%.l	%2,%/d0\n"					\
Packit bbfece
	   "	move%.l	%3,%/d1\n"					\
Packit bbfece
	   "	move%.l	%/d0,%/d2\n"					\
Packit bbfece
	   "	swap	%/d0\n"						\
Packit bbfece
	   "	move%.l	%/d1,%/d3\n"					\
Packit bbfece
	   "	swap	%/d1\n"						\
Packit bbfece
	   "	move%.w	%/d2,%/d4\n"					\
Packit bbfece
	   "	mulu	%/d3,%/d4\n"					\
Packit bbfece
	   "	mulu	%/d1,%/d2\n"					\
Packit bbfece
	   "	mulu	%/d0,%/d3\n"					\
Packit bbfece
	   "	mulu	%/d0,%/d1\n"					\
Packit bbfece
	   "	move%.l	%/d4,%/d0\n"					\
Packit bbfece
	   "	clr%.w	%/d0\n"						\
Packit bbfece
	   "	swap	%/d0\n"						\
Packit bbfece
	   "	add%.l	%/d0,%/d2\n"					\
Packit bbfece
	   "	add%.l	%/d3,%/d2\n"					\
Packit bbfece
	   "	jcc	1f\n"						\
Packit bbfece
	   "	add%.l	%#65536,%/d1\n"					\
Packit bbfece
	   "1:	swap	%/d2\n"						\
Packit bbfece
	   "	moveq	%#0,%/d0\n"					\
Packit bbfece
	   "	move%.w	%/d2,%/d0\n"					\
Packit bbfece
	   "	move%.w	%/d4,%/d2\n"					\
Packit bbfece
	   "	move%.l	%/d2,%1\n"					\
Packit bbfece
	   "	add%.l	%/d1,%/d0\n"					\
Packit bbfece
	   "	move%.l	%/d0,%0"					\
Packit bbfece
	   : "=g" ((USItype) (xh)),					\
Packit bbfece
	     "=g" ((USItype) (xl))					\
Packit bbfece
	   : "g" ((USItype) (a)),					\
Packit bbfece
	     "g" ((USItype) (b))					\
Packit bbfece
	   : "d0", "d1", "d2", "d3", "d4")
Packit bbfece
#define UMUL_TIME 100
Packit bbfece
#define UDIV_TIME 400
Packit bbfece
#else /* not ColdFire */
Packit bbfece
/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX.  */
Packit bbfece
#define umul_ppmm(xh, xl, a, b) \
Packit bbfece
  __asm__ ("| Inlined umul_ppmm\n"					\
Packit bbfece
	   "	move%.l	%2,%/d0\n"					\
Packit bbfece
	   "	move%.l	%3,%/d1\n"					\
Packit bbfece
	   "	move%.l	%/d0,%/d2\n"					\
Packit bbfece
	   "	swap	%/d0\n"						\
Packit bbfece
	   "	move%.l	%/d1,%/d3\n"					\
Packit bbfece
	   "	swap	%/d1\n"						\
Packit bbfece
	   "	move%.w	%/d2,%/d4\n"					\
Packit bbfece
	   "	mulu	%/d3,%/d4\n"					\
Packit bbfece
	   "	mulu	%/d1,%/d2\n"					\
Packit bbfece
	   "	mulu	%/d0,%/d3\n"					\
Packit bbfece
	   "	mulu	%/d0,%/d1\n"					\
Packit bbfece
	   "	move%.l	%/d4,%/d0\n"					\
Packit bbfece
	   "	eor%.w	%/d0,%/d0\n"					\
Packit bbfece
	   "	swap	%/d0\n"						\
Packit bbfece
	   "	add%.l	%/d0,%/d2\n"					\
Packit bbfece
	   "	add%.l	%/d3,%/d2\n"					\
Packit bbfece
	   "	jcc	1f\n"						\
Packit bbfece
	   "	add%.l	%#65536,%/d1\n"					\
Packit bbfece
	   "1:	swap	%/d2\n"						\
Packit bbfece
	   "	moveq	%#0,%/d0\n"					\
Packit bbfece
	   "	move%.w	%/d2,%/d0\n"					\
Packit bbfece
	   "	move%.w	%/d4,%/d2\n"					\
Packit bbfece
	   "	move%.l	%/d2,%1\n"					\
Packit bbfece
	   "	add%.l	%/d1,%/d0\n"					\
Packit bbfece
	   "	move%.l	%/d0,%0"					\
Packit bbfece
	   : "=g" ((USItype) (xh)),					\
Packit bbfece
	     "=g" ((USItype) (xl))					\
Packit bbfece
	   : "g" ((USItype) (a)),					\
Packit bbfece
	     "g" ((USItype) (b))					\
Packit bbfece
	   : "d0", "d1", "d2", "d3", "d4")
Packit bbfece
#define UMUL_TIME 100
Packit bbfece
#define UDIV_TIME 400
Packit bbfece
Packit bbfece
#endif /* not mc68020 */
Packit bbfece
Packit bbfece
/* The '020, '030, '040 and '060 have bitfield insns.
Packit bbfece
   cpu32 disguises as a 68020, but lacks them.  */
Packit bbfece
#if defined (__mc68020__) && !defined (__mcpu32__)
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  __asm__ ("bfffo %1{%b2:%b2},%0"					\
Packit bbfece
	   : "=d" ((USItype) (count))					\
Packit bbfece
	   : "od" ((USItype) (x)), "n" (0))
Packit bbfece
/* Some ColdFire architectures have a ff1 instruction supported via
Packit bbfece
   __builtin_clz. */
Packit bbfece
#elif defined (__mcfisaaplus__) || defined (__mcfisac__)
Packit bbfece
#define count_leading_zeros(count,x) ((count) = __builtin_clz (x))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif
Packit bbfece
#endif /* mc68000 */
Packit bbfece
Packit bbfece
#if defined (__m88000__) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3"			\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%rJ" ((USItype) (ah)),					\
Packit bbfece
	     "rJ" ((USItype) (bh)),					\
Packit bbfece
	     "%rJ" ((USItype) (al)),					\
Packit bbfece
	     "rJ" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3"			\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "rJ" ((USItype) (ah)),					\
Packit bbfece
	     "rJ" ((USItype) (bh)),					\
Packit bbfece
	     "rJ" ((USItype) (al)),					\
Packit bbfece
	     "rJ" ((USItype) (bl)))
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  do {									\
Packit bbfece
    USItype __cbtmp;							\
Packit bbfece
    __asm__ ("ff1 %0,%1"						\
Packit bbfece
	     : "=r" (__cbtmp)						\
Packit bbfece
	     : "r" ((USItype) (x)));					\
Packit bbfece
    (count) = __cbtmp ^ 31;						\
Packit bbfece
  } while (0)
Packit bbfece
#define COUNT_LEADING_ZEROS_0 63 /* sic */
Packit bbfece
#if defined (__mc88110__)
Packit bbfece
#define umul_ppmm(wh, wl, u, v) \
Packit bbfece
  do {									\
Packit bbfece
    union {UDItype __ll;						\
Packit bbfece
	   struct {USItype __h, __l;} __i;				\
Packit bbfece
	  } __xx;							\
Packit bbfece
    __asm__ ("mulu.d	%0,%1,%2"					\
Packit bbfece
	     : "=r" (__xx.__ll)						\
Packit bbfece
	     : "r" ((USItype) (u)),					\
Packit bbfece
	       "r" ((USItype) (v)));					\
Packit bbfece
    (wh) = __xx.__i.__h;						\
Packit bbfece
    (wl) = __xx.__i.__l;						\
Packit bbfece
  } while (0)
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  ({union {UDItype __ll;						\
Packit bbfece
	   struct {USItype __h, __l;} __i;				\
Packit bbfece
	  } __xx;							\
Packit bbfece
  USItype __q;								\
Packit bbfece
  __xx.__i.__h = (n1); __xx.__i.__l = (n0);				\
Packit bbfece
  __asm__ ("divu.d %0,%1,%2"						\
Packit bbfece
	   : "=r" (__q)							\
Packit bbfece
	   : "r" (__xx.__ll),						\
Packit bbfece
	     "r" ((USItype) (d)));					\
Packit bbfece
  (r) = (n0) - __q * (d); (q) = __q; })
Packit bbfece
#define UMUL_TIME 5
Packit bbfece
#define UDIV_TIME 25
Packit bbfece
#else
Packit bbfece
#define UMUL_TIME 17
Packit bbfece
#define UDIV_TIME 150
Packit bbfece
#endif /* __mc88110__ */
Packit bbfece
#endif /* __m88000__ */
Packit bbfece
Packit bbfece
#if defined (__mn10300__)
Packit bbfece
# if defined (__AM33__)
Packit bbfece
#  define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
Packit bbfece
#  define umul_ppmm(w1, w0, u, v)		\
Packit bbfece
    asm("mulu %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v))
Packit bbfece
#  define smul_ppmm(w1, w0, u, v)		\
Packit bbfece
    asm("mul %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v))
Packit bbfece
# else
Packit bbfece
#  define umul_ppmm(w1, w0, u, v)		\
Packit bbfece
    asm("nop; nop; mulu %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v))
Packit bbfece
#  define smul_ppmm(w1, w0, u, v)		\
Packit bbfece
    asm("nop; nop; mul %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v))
Packit bbfece
# endif
Packit bbfece
# define add_ssaaaa(sh, sl, ah, al, bh, bl)	\
Packit bbfece
  do {						\
Packit bbfece
    DWunion __s, __a, __b;			\
Packit bbfece
    __a.s.low = (al); __a.s.high = (ah);	\
Packit bbfece
    __b.s.low = (bl); __b.s.high = (bh);	\
Packit bbfece
    __s.ll = __a.ll + __b.ll;			\
Packit bbfece
    (sl) = __s.s.low; (sh) = __s.s.high;	\
Packit bbfece
  } while (0)
Packit bbfece
# define sub_ddmmss(sh, sl, ah, al, bh, bl)	\
Packit bbfece
  do {						\
Packit bbfece
    DWunion __s, __a, __b;			\
Packit bbfece
    __a.s.low = (al); __a.s.high = (ah);	\
Packit bbfece
    __b.s.low = (bl); __b.s.high = (bh);	\
Packit bbfece
    __s.ll = __a.ll - __b.ll;			\
Packit bbfece
    (sl) = __s.s.low; (sh) = __s.s.high;	\
Packit bbfece
  } while (0)
Packit bbfece
# define udiv_qrnnd(q, r, nh, nl, d)		\
Packit bbfece
  asm("divu %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh))
Packit bbfece
# define sdiv_qrnnd(q, r, nh, nl, d)		\
Packit bbfece
  asm("div %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh))
Packit bbfece
# define UMUL_TIME 3
Packit bbfece
# define UDIV_TIME 38
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if defined (__mips__) && W_TYPE_SIZE == 32
Packit bbfece
#define umul_ppmm(w1, w0, u, v)						\
Packit bbfece
  do {									\
Packit bbfece
    UDItype __x = (UDItype) (USItype) (u) * (USItype) (v);		\
Packit bbfece
    (w1) = (USItype) (__x >> 32);					\
Packit bbfece
    (w0) = (USItype) (__x);						\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 10
Packit bbfece
#define UDIV_TIME 100
Packit bbfece
Packit bbfece
#if (__mips == 32 || __mips == 64) && ! defined (__mips16)
Packit bbfece
#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#endif
Packit bbfece
#endif /* __mips__ */
Packit bbfece
Packit bbfece
/* FIXME: We should test _IBMR2 here when we add assembly support for the
Packit bbfece
   system vendor compilers.
Packit bbfece
   FIXME: What's needed for gcc PowerPC VxWorks?  __vxworks__ is not good
Packit bbfece
   enough, since that hits ARM and m68k too.  */
Packit bbfece
#if (defined (_ARCH_PPC)	/* AIX */				\
Packit bbfece
     || defined (__powerpc__)	/* gcc */				\
Packit bbfece
     || defined (__POWERPC__)	/* BEOS */				\
Packit bbfece
     || defined (__ppc__)	/* Darwin */				\
Packit bbfece
     || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */    \
Packit bbfece
     || (defined (PPC) && defined (CPU_FAMILY)    /* VxWorks */               \
Packit bbfece
	 && CPU_FAMILY == PPC)                                                \
Packit bbfece
     ) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do {									\
Packit bbfece
    if (__builtin_constant_p (bh) && (bh) == 0)				\
Packit bbfece
      __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2"		\
Packit bbfece
	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
Packit bbfece
    else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
Packit bbfece
      __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2"		\
Packit bbfece
	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
Packit bbfece
    else								\
Packit bbfece
      __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3"		\
Packit bbfece
	     : "=r" (sh), "=&r" (sl)					\
Packit bbfece
	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
Packit bbfece
  } while (0)
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do {									\
Packit bbfece
    if (__builtin_constant_p (ah) && (ah) == 0)				\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2"	\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
Packit bbfece
    else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0)		\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2"	\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
Packit bbfece
    else if (__builtin_constant_p (bh) && (bh) == 0)			\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2"		\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
Packit bbfece
    else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2"		\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
Packit bbfece
    else								\
Packit bbfece
      __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2"	\
Packit bbfece
	       : "=r" (sh), "=&r" (sl)					\
Packit bbfece
	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
Packit bbfece
  } while (0)
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  __asm__ ("cntlzw %0,%1" : "=r" (count) : "r" (x))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 32
Packit bbfece
#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \
Packit bbfece
  || defined (__ppc__)                                                    \
Packit bbfece
  || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */       \
Packit bbfece
  || (defined (PPC) && defined (CPU_FAMILY)    /* VxWorks */                  \
Packit bbfece
	 && CPU_FAMILY == PPC)
Packit bbfece
#define umul_ppmm(ph, pl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    USItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
Packit bbfece
    (pl) = __m0 * __m1;							\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 15
Packit bbfece
#define smul_ppmm(ph, pl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    SItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
Packit bbfece
    (pl) = __m0 * __m1;							\
Packit bbfece
  } while (0)
Packit bbfece
#define SMUL_TIME 14
Packit bbfece
#define UDIV_TIME 120
Packit bbfece
#endif
Packit bbfece
#endif /* 32-bit POWER architecture variants.  */
Packit bbfece
Packit bbfece
/* We should test _IBMR2 here when we add assembly support for the system
Packit bbfece
   vendor compilers.  */
Packit bbfece
#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do {									\
Packit bbfece
    if (__builtin_constant_p (bh) && (bh) == 0)				\
Packit bbfece
      __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2"		\
Packit bbfece
	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
Packit bbfece
    else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0)		\
Packit bbfece
      __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2"		\
Packit bbfece
	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
Packit bbfece
    else								\
Packit bbfece
      __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3"		\
Packit bbfece
	     : "=r" (sh), "=&r" (sl)					\
Packit bbfece
	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
Packit bbfece
  } while (0)
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do {									\
Packit bbfece
    if (__builtin_constant_p (ah) && (ah) == 0)				\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2"	\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
Packit bbfece
    else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0)		\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2"	\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
Packit bbfece
    else if (__builtin_constant_p (bh) && (bh) == 0)			\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2"		\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
Packit bbfece
    else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0)		\
Packit bbfece
      __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2"		\
Packit bbfece
	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
Packit bbfece
    else								\
Packit bbfece
      __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2"	\
Packit bbfece
	       : "=r" (sh), "=&r" (sl)					\
Packit bbfece
	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
Packit bbfece
  } while (0)
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
Packit bbfece
#define COUNT_LEADING_ZEROS_0 64
Packit bbfece
#define umul_ppmm(ph, pl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    UDItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
Packit bbfece
    (pl) = __m0 * __m1;							\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 15
Packit bbfece
#define smul_ppmm(ph, pl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    DItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
Packit bbfece
    (pl) = __m0 * __m1;							\
Packit bbfece
  } while (0)
Packit bbfece
#define SMUL_TIME 14  /* ??? */
Packit bbfece
#define UDIV_TIME 120 /* ??? */
Packit bbfece
#endif /* 64-bit PowerPC.  */
Packit bbfece
Packit bbfece
#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("a %1,%5\n\tae %0,%3"					\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%0" ((USItype) (ah)),					\
Packit bbfece
	     "r" ((USItype) (bh)),					\
Packit bbfece
	     "%1" ((USItype) (al)),					\
Packit bbfece
	     "r" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("s %1,%5\n\tse %0,%3"					\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "0" ((USItype) (ah)),					\
Packit bbfece
	     "r" ((USItype) (bh)),					\
Packit bbfece
	     "1" ((USItype) (al)),					\
Packit bbfece
	     "r" ((USItype) (bl)))
Packit bbfece
#define umul_ppmm(ph, pl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    USItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    __asm__ (								\
Packit bbfece
       "s	r2,r2\n"						\
Packit bbfece
"	mts	r10,%2\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	m	r2,%3\n"						\
Packit bbfece
"	cas	%0,r2,r0\n"						\
Packit bbfece
"	mfs	r10,%1"							\
Packit bbfece
	     : "=r" ((USItype) (ph)),					\
Packit bbfece
	       "=r" ((USItype) (pl))					\
Packit bbfece
	     : "%r" (__m0),						\
Packit bbfece
		"r" (__m1)						\
Packit bbfece
	     : "r2");							\
Packit bbfece
    (ph) += ((((SItype) __m0 >> 31) & __m1)				\
Packit bbfece
	     + (((SItype) __m1 >> 31) & __m0));				\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 20
Packit bbfece
#define UDIV_TIME 200
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  do {									\
Packit bbfece
    if ((x) >= 0x10000)							\
Packit bbfece
      __asm__ ("clz	%0,%1"						\
Packit bbfece
	       : "=r" ((USItype) (count))				\
Packit bbfece
	       : "r" ((USItype) (x) >> 16));				\
Packit bbfece
    else								\
Packit bbfece
      {									\
Packit bbfece
	__asm__ ("clz	%0,%1"						\
Packit bbfece
		 : "=r" ((USItype) (count))				\
Packit bbfece
		 : "r" ((USItype) (x)));					\
Packit bbfece
	(count) += 16;							\
Packit bbfece
      }									\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if defined(__sh__) && W_TYPE_SIZE == 32
Packit bbfece
#ifndef __sh1__
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ (								\
Packit bbfece
       "dmulu.l	%2,%3\n\tsts%M1	macl,%1\n\tsts%M0	mach,%0"	\
Packit bbfece
	   : "=r<" ((USItype)(w1)),					\
Packit bbfece
	     "=r<" ((USItype)(w0))					\
Packit bbfece
	   : "r" ((USItype)(u)),					\
Packit bbfece
	     "r" ((USItype)(v))						\
Packit bbfece
	   : "macl", "mach")
Packit bbfece
#define UMUL_TIME 5
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* This is the same algorithm as __udiv_qrnnd_c.  */
Packit bbfece
#define UDIV_NEEDS_NORMALIZATION 1
Packit bbfece
Packit bbfece
#ifdef __FDPIC__
Packit bbfece
/* FDPIC needs a special version of the asm fragment to extract the
Packit bbfece
   code address from the function descriptor. __udiv_qrnnd_16 is
Packit bbfece
   assumed to be local and not to use the GOT, so loading r12 is
Packit bbfece
   not needed. */
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  do {									\
Packit bbfece
    extern UWtype __udiv_qrnnd_16 (UWtype, UWtype)			\
Packit bbfece
			__attribute__ ((visibility ("hidden")));	\
Packit bbfece
    /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */	\
Packit bbfece
    __asm__ (								\
Packit bbfece
	"mov%M4	%4,r5\n"						\
Packit bbfece
"	swap.w	%3,r4\n"						\
Packit bbfece
"	swap.w	r5,r6\n"						\
Packit bbfece
"	mov.l	@%5,r2\n"						\
Packit bbfece
"	jsr	@r2\n"							\
Packit bbfece
"	shll16	r6\n"							\
Packit bbfece
"	swap.w	r4,r4\n"						\
Packit bbfece
"	mov.l	@%5,r2\n"						\
Packit bbfece
"	jsr	@r2\n"							\
Packit bbfece
"	swap.w	r1,%0\n"						\
Packit bbfece
"	or	r1,%0"							\
Packit bbfece
	: "=r" (q), "=&z" (r)						\
Packit bbfece
	: "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16)		\
Packit bbfece
	: "r1", "r2", "r4", "r5", "r6", "pr", "t");			\
Packit bbfece
  } while (0)
Packit bbfece
#else
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  do {									\
Packit bbfece
    extern UWtype __udiv_qrnnd_16 (UWtype, UWtype)			\
Packit bbfece
			__attribute__ ((visibility ("hidden")));	\
Packit bbfece
    /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */	\
Packit bbfece
    __asm__ (								\
Packit bbfece
	"mov%M4 %4,r5\n"						\
Packit bbfece
"	swap.w %3,r4\n"							\
Packit bbfece
"	swap.w r5,r6\n"							\
Packit bbfece
"	jsr @%5\n"							\
Packit bbfece
"	shll16 r6\n"							\
Packit bbfece
"	swap.w r4,r4\n"							\
Packit bbfece
"	jsr @%5\n"							\
Packit bbfece
"	swap.w r1,%0\n"							\
Packit bbfece
"	or r1,%0"							\
Packit bbfece
	: "=r" (q), "=&z" (r)						\
Packit bbfece
	: "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16)		\
Packit bbfece
	: "r1", "r2", "r4", "r5", "r6", "pr", "t");			\
Packit bbfece
  } while (0)
Packit bbfece
#endif /* __FDPIC__  */
Packit bbfece
Packit bbfece
#define UDIV_TIME 80
Packit bbfece
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl)				\
Packit bbfece
  __asm__ ("clrt;subc %5,%1; subc %4,%0"				\
Packit bbfece
	   : "=r" (sh), "=r" (sl)					\
Packit bbfece
	   : "0" (ah), "1" (al), "r" (bh), "r" (bl) : "t")
Packit bbfece
Packit bbfece
#endif /* __sh__ */
Packit bbfece
Packit bbfece
#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \
Packit bbfece
    && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0"				\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "%rJ" ((USItype) (ah)),					\
Packit bbfece
	     "rI" ((USItype) (bh)),					\
Packit bbfece
	     "%rJ" ((USItype) (al)),					\
Packit bbfece
	     "rI" ((USItype) (bl))					\
Packit bbfece
	   __CLOBBER_CC)
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0"				\
Packit bbfece
	   : "=r" ((USItype) (sh)),					\
Packit bbfece
	     "=&r" ((USItype) (sl))					\
Packit bbfece
	   : "rJ" ((USItype) (ah)),					\
Packit bbfece
	     "rI" ((USItype) (bh)),					\
Packit bbfece
	     "rJ" ((USItype) (al)),					\
Packit bbfece
	     "rI" ((USItype) (bl))					\
Packit bbfece
	   __CLOBBER_CC)
Packit bbfece
#if defined (__sparc_v9__)
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  do {									\
Packit bbfece
    register USItype __g1 asm ("g1");					\
Packit bbfece
    __asm__ ("umul\t%2,%3,%1\n\t"					\
Packit bbfece
	     "srlx\t%1, 32, %0"						\
Packit bbfece
	     : "=r" ((USItype) (w1)),					\
Packit bbfece
	       "=r" (__g1)						\
Packit bbfece
	     : "r" ((USItype) (u)),					\
Packit bbfece
	       "r" ((USItype) (v)));					\
Packit bbfece
    (w0) = __g1;							\
Packit bbfece
  } while (0)
Packit bbfece
#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
Packit bbfece
  __asm__ ("mov\t%2,%%y\n\t"						\
Packit bbfece
	   "udiv\t%3,%4,%0\n\t"						\
Packit bbfece
	   "umul\t%0,%4,%1\n\t"						\
Packit bbfece
	   "sub\t%3,%1,%1"						\
Packit bbfece
	   : "=&r" ((USItype) (__q)),					\
Packit bbfece
	     "=&r" ((USItype) (__r))					\
Packit bbfece
	   : "r" ((USItype) (__n1)),					\
Packit bbfece
	     "r" ((USItype) (__n0)),					\
Packit bbfece
	     "r" ((USItype) (__d)))
Packit bbfece
#else
Packit bbfece
#if defined (__sparc_v8__)
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
Packit bbfece
	   : "=r" ((USItype) (w1)),					\
Packit bbfece
	     "=r" ((USItype) (w0))					\
Packit bbfece
	   : "r" ((USItype) (u)),					\
Packit bbfece
	     "r" ((USItype) (v)))
Packit bbfece
#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
Packit bbfece
  __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
Packit bbfece
	   : "=&r" ((USItype) (__q)),					\
Packit bbfece
	     "=&r" ((USItype) (__r))					\
Packit bbfece
	   : "r" ((USItype) (__n1)),					\
Packit bbfece
	     "r" ((USItype) (__n0)),					\
Packit bbfece
	     "r" ((USItype) (__d)))
Packit bbfece
#else
Packit bbfece
#if defined (__sparclite__)
Packit bbfece
/* This has hardware multiply but not divide.  It also has two additional
Packit bbfece
   instructions scan (ffs from high bit) and divscc.  */
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
Packit bbfece
	   : "=r" ((USItype) (w1)),					\
Packit bbfece
	     "=r" ((USItype) (w0))					\
Packit bbfece
	   : "r" ((USItype) (u)),					\
Packit bbfece
	     "r" ((USItype) (v)))
Packit bbfece
#define udiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  __asm__ ("! Inlined udiv_qrnnd\n"					\
Packit bbfece
"	wr	%%g0,%2,%%y	! Not a delayed write for sparclite\n"	\
Packit bbfece
"	tst	%%g0\n"							\
Packit bbfece
"	divscc	%3,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%%g1\n"						\
Packit bbfece
"	divscc	%%g1,%4,%0\n"						\
Packit bbfece
"	rd	%%y,%1\n"						\
Packit bbfece
"	bl,a 1f\n"							\
Packit bbfece
"	add	%1,%4,%1\n"						\
Packit bbfece
"1:	! End of inline udiv_qrnnd"					\
Packit bbfece
	   : "=r" ((USItype) (q)),					\
Packit bbfece
	     "=r" ((USItype) (r))					\
Packit bbfece
	   : "r" ((USItype) (n1)),					\
Packit bbfece
	     "r" ((USItype) (n0)),					\
Packit bbfece
	     "rI" ((USItype) (d))					\
Packit bbfece
	   : "g1" __AND_CLOBBER_CC)
Packit bbfece
#define UDIV_TIME 37
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  do {                                                                  \
Packit bbfece
  __asm__ ("scan %1,1,%0"                                               \
Packit bbfece
	   : "=r" ((USItype) (count))                                   \
Packit bbfece
	   : "r" ((USItype) (x)));					\
Packit bbfece
  } while (0)
Packit bbfece
/* Early sparclites return 63 for an argument of 0, but they warn that future
Packit bbfece
   implementations might change this.  Therefore, leave COUNT_LEADING_ZEROS_0
Packit bbfece
   undefined.  */
Packit bbfece
#else
Packit bbfece
/* SPARC without integer multiplication and divide instructions.
Packit bbfece
   (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
Packit bbfece
#define umul_ppmm(w1, w0, u, v) \
Packit bbfece
  __asm__ ("! Inlined umul_ppmm\n"					\
Packit bbfece
"	wr	%%g0,%2,%%y	! SPARC has 0-3 delay insn after a wr\n"\
Packit bbfece
"	sra	%3,31,%%o5	! Don't move this insn\n"		\
Packit bbfece
"	and	%2,%%o5,%%o5	! Don't move this insn\n"		\
Packit bbfece
"	andcc	%%g0,0,%%g1	! Don't move this insn\n"		\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,%3,%%g1\n"						\
Packit bbfece
"	mulscc	%%g1,0,%%g1\n"						\
Packit bbfece
"	add	%%g1,%%o5,%0\n"						\
Packit bbfece
"	rd	%%y,%1"							\
Packit bbfece
	   : "=r" ((USItype) (w1)),					\
Packit bbfece
	     "=r" ((USItype) (w0))					\
Packit bbfece
	   : "%rI" ((USItype) (u)),					\
Packit bbfece
	     "r" ((USItype) (v))						\
Packit bbfece
	   : "g1", "o5" __AND_CLOBBER_CC)
Packit bbfece
#define UMUL_TIME 39		/* 39 instructions */
Packit bbfece
/* It's quite necessary to add this much assembler for the sparc.
Packit bbfece
   The default udiv_qrnnd (in C) is more than 10 times slower!  */
Packit bbfece
#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
Packit bbfece
  __asm__ ("! Inlined udiv_qrnnd\n"					\
Packit bbfece
"	mov	32,%%g1\n"						\
Packit bbfece
"	subcc	%1,%2,%%g0\n"						\
Packit bbfece
"1:	bcs	5f\n"							\
Packit bbfece
"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
Packit bbfece
"	sub	%1,%2,%1	! this kills msb of n\n"		\
Packit bbfece
"	addx	%1,%1,%1	! so this can't give carry\n"		\
Packit bbfece
"	subcc	%%g1,1,%%g1\n"						\
Packit bbfece
"2:	bne	1b\n"							\
Packit bbfece
"	 subcc	%1,%2,%%g0\n"						\
Packit bbfece
"	bcs	3f\n"							\
Packit bbfece
"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
Packit bbfece
"	b	3f\n"							\
Packit bbfece
"	 sub	%1,%2,%1	! this kills msb of n\n"		\
Packit bbfece
"4:	sub	%1,%2,%1\n"						\
Packit bbfece
"5:	addxcc	%1,%1,%1\n"						\
Packit bbfece
"	bcc	2b\n"							\
Packit bbfece
"	 subcc	%%g1,1,%%g1\n"						\
Packit bbfece
"! Got carry from n.  Subtract next step to cancel this carry.\n"	\
Packit bbfece
"	bne	4b\n"							\
Packit bbfece
"	 addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb\n"	\
Packit bbfece
"	sub	%1,%2,%1\n"						\
Packit bbfece
"3:	xnor	%0,0,%0\n"						\
Packit bbfece
"	! End of inline udiv_qrnnd"					\
Packit bbfece
	   : "=&r" ((USItype) (__q)),					\
Packit bbfece
	     "=&r" ((USItype) (__r))					\
Packit bbfece
	   : "r" ((USItype) (__d)),					\
Packit bbfece
	     "1" ((USItype) (__n1)),					\
Packit bbfece
	     "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC)
Packit bbfece
#define UDIV_TIME (3+7*32)	/* 7 instructions/iteration. 32 iterations.  */
Packit bbfece
#endif /* __sparclite__ */
Packit bbfece
#endif /* __sparc_v8__ */
Packit bbfece
#endif /* __sparc_v9__ */
Packit bbfece
#endif /* sparc32 */
Packit bbfece
Packit bbfece
#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \
Packit bbfece
    && W_TYPE_SIZE == 64
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl)				\
Packit bbfece
  do {									\
Packit bbfece
    UDItype __carry = 0;						\
Packit bbfece
    __asm__ ("addcc\t%r5,%6,%1\n\t"					\
Packit bbfece
	     "add\t%r3,%4,%0\n\t"					\
Packit bbfece
	     "movcs\t%%xcc, 1, %2\n\t"					\
Packit bbfece
	     "add\t%0, %2, %0"						\
Packit bbfece
	     : "=r" ((UDItype)(sh)),				      	\
Packit bbfece
	       "=&r" ((UDItype)(sl)),				      	\
Packit bbfece
	       "+r" (__carry)				      		\
Packit bbfece
	     : "%rJ" ((UDItype)(ah)),				     	\
Packit bbfece
	       "rI" ((UDItype)(bh)),				      	\
Packit bbfece
	       "%rJ" ((UDItype)(al)),				     	\
Packit bbfece
	       "rI" ((UDItype)(bl))				       	\
Packit bbfece
	     __CLOBBER_CC);						\
Packit bbfece
  } while (0)
Packit bbfece
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl)				\
Packit bbfece
  do {									\
Packit bbfece
    UDItype __carry = 0;						\
Packit bbfece
    __asm__ ("subcc\t%r5,%6,%1\n\t"					\
Packit bbfece
	     "sub\t%r3,%4,%0\n\t"					\
Packit bbfece
	     "movcs\t%%xcc, 1, %2\n\t"					\
Packit bbfece
	     "sub\t%0, %2, %0"						\
Packit bbfece
	     : "=r" ((UDItype)(sh)),				      	\
Packit bbfece
	       "=&r" ((UDItype)(sl)),				      	\
Packit bbfece
	       "+r" (__carry)				      		\
Packit bbfece
	     : "%rJ" ((UDItype)(ah)),				     	\
Packit bbfece
	       "rI" ((UDItype)(bh)),				      	\
Packit bbfece
	       "%rJ" ((UDItype)(al)),				     	\
Packit bbfece
	       "rI" ((UDItype)(bl))				       	\
Packit bbfece
	     __CLOBBER_CC);						\
Packit bbfece
  } while (0)
Packit bbfece
Packit bbfece
#define umul_ppmm(wh, wl, u, v)						\
Packit bbfece
  do {									\
Packit bbfece
	  UDItype tmp1, tmp2, tmp3, tmp4;				\
Packit bbfece
	  __asm__ __volatile__ (					\
Packit bbfece
		   "srl %7,0,%3\n\t"					\
Packit bbfece
		   "mulx %3,%6,%1\n\t"					\
Packit bbfece
		   "srlx %6,32,%2\n\t"					\
Packit bbfece
		   "mulx %2,%3,%4\n\t"					\
Packit bbfece
		   "sllx %4,32,%5\n\t"					\
Packit bbfece
		   "srl %6,0,%3\n\t"					\
Packit bbfece
		   "sub %1,%5,%5\n\t"					\
Packit bbfece
		   "srlx %5,32,%5\n\t"					\
Packit bbfece
		   "addcc %4,%5,%4\n\t"					\
Packit bbfece
		   "srlx %7,32,%5\n\t"					\
Packit bbfece
		   "mulx %3,%5,%3\n\t"					\
Packit bbfece
		   "mulx %2,%5,%5\n\t"					\
Packit bbfece
		   "sethi %%hi(0x80000000),%2\n\t"			\
Packit bbfece
		   "addcc %4,%3,%4\n\t"					\
Packit bbfece
		   "srlx %4,32,%4\n\t"					\
Packit bbfece
		   "add %2,%2,%2\n\t"					\
Packit bbfece
		   "movcc %%xcc,%%g0,%2\n\t"				\
Packit bbfece
		   "addcc %5,%4,%5\n\t"					\
Packit bbfece
		   "sllx %3,32,%3\n\t"					\
Packit bbfece
		   "add %1,%3,%1\n\t"					\
Packit bbfece
		   "add %5,%2,%0"					\
Packit bbfece
	   : "=r" ((UDItype)(wh)),					\
Packit bbfece
	     "=&r" ((UDItype)(wl)),					\
Packit bbfece
	     "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4)	\
Packit bbfece
	   : "r" ((UDItype)(u)),					\
Packit bbfece
	     "r" ((UDItype)(v))						\
Packit bbfece
	   __CLOBBER_CC);						\
Packit bbfece
  } while (0)
Packit bbfece
#define UMUL_TIME 96
Packit bbfece
#define UDIV_TIME 230
Packit bbfece
#endif /* sparc64 */
Packit bbfece
Packit bbfece
#if defined (__vax__) && W_TYPE_SIZE == 32
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("addl2 %5,%1\n\tadwc %3,%0"					\
Packit bbfece
	   : "=g" ((USItype) (sh)),					\
Packit bbfece
	     "=&g" ((USItype) (sl))					\
Packit bbfece
	   : "%0" ((USItype) (ah)),					\
Packit bbfece
	     "g" ((USItype) (bh)),					\
Packit bbfece
	     "%1" ((USItype) (al)),					\
Packit bbfece
	     "g" ((USItype) (bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("subl2 %5,%1\n\tsbwc %3,%0"					\
Packit bbfece
	   : "=g" ((USItype) (sh)),					\
Packit bbfece
	     "=&g" ((USItype) (sl))					\
Packit bbfece
	   : "0" ((USItype) (ah)),					\
Packit bbfece
	     "g" ((USItype) (bh)),					\
Packit bbfece
	     "1" ((USItype) (al)),					\
Packit bbfece
	     "g" ((USItype) (bl)))
Packit bbfece
#define umul_ppmm(xh, xl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    union {								\
Packit bbfece
	UDItype __ll;							\
Packit bbfece
	struct {USItype __l, __h;} __i;					\
Packit bbfece
      } __xx;								\
Packit bbfece
    USItype __m0 = (m0), __m1 = (m1);					\
Packit bbfece
    __asm__ ("emul %1,%2,$0,%0"						\
Packit bbfece
	     : "=r" (__xx.__ll)						\
Packit bbfece
	     : "g" (__m0),						\
Packit bbfece
	       "g" (__m1));						\
Packit bbfece
    (xh) = __xx.__i.__h;						\
Packit bbfece
    (xl) = __xx.__i.__l;						\
Packit bbfece
    (xh) += ((((SItype) __m0 >> 31) & __m1)				\
Packit bbfece
	     + (((SItype) __m1 >> 31) & __m0));				\
Packit bbfece
  } while (0)
Packit bbfece
#define sdiv_qrnnd(q, r, n1, n0, d) \
Packit bbfece
  do {									\
Packit bbfece
    union {DItype __ll;							\
Packit bbfece
	   struct {SItype __l, __h;} __i;				\
Packit bbfece
	  } __xx;							\
Packit bbfece
    __xx.__i.__h = n1; __xx.__i.__l = n0;				\
Packit bbfece
    __asm__ ("ediv %3,%2,%0,%1"						\
Packit bbfece
	     : "=g" (q), "=g" (r)					\
Packit bbfece
	     : "g" (__xx.__ll), "g" (d));				\
Packit bbfece
  } while (0)
Packit bbfece
#endif /* __vax__ */
Packit bbfece
Packit bbfece
#ifdef _TMS320C6X
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do									\
Packit bbfece
    {									\
Packit bbfece
      UDItype __ll;							\
Packit bbfece
      __asm__ ("addu .l1 %1, %2, %0"					\
Packit bbfece
	       : "=a" (__ll) : "a" (al), "a" (bl));			\
Packit bbfece
      (sl) = (USItype)__ll;						\
Packit bbfece
      (sh) = ((USItype)(__ll >> 32)) + (ah) + (bh);			\
Packit bbfece
    }									\
Packit bbfece
  while (0)
Packit bbfece
Packit bbfece
#ifdef _TMS320C6400_PLUS
Packit bbfece
#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
Packit bbfece
#define umul_ppmm(w1, w0, u, v)						\
Packit bbfece
  do {									\
Packit bbfece
    UDItype __x = (UDItype) (USItype) (u) * (USItype) (v);		\
Packit bbfece
    (w1) = (USItype) (__x >> 32);					\
Packit bbfece
    (w0) = (USItype) (__x);						\
Packit bbfece
  } while (0)
Packit bbfece
#endif  /* _TMS320C6400_PLUS */
Packit bbfece
Packit bbfece
#define count_leading_zeros(count, x)	((count) = __builtin_clz (x))
Packit bbfece
#ifdef _TMS320C6400
Packit bbfece
#define count_trailing_zeros(count, x)	((count) = __builtin_ctz (x))
Packit bbfece
#endif
Packit bbfece
#define UMUL_TIME 4
Packit bbfece
#define UDIV_TIME 40
Packit bbfece
#endif /* _TMS320C6X */
Packit bbfece
Packit bbfece
#if defined (__xtensa__) && W_TYPE_SIZE == 32
Packit bbfece
/* This code is not Xtensa-configuration-specific, so rely on the compiler
Packit bbfece
   to expand builtin functions depending on what configuration features
Packit bbfece
   are available.  This avoids library calls when the operation can be
Packit bbfece
   performed in-line.  */
Packit bbfece
#define umul_ppmm(w1, w0, u, v)						\
Packit bbfece
  do {									\
Packit bbfece
    DWunion __w;							\
Packit bbfece
    __w.ll = __builtin_umulsidi3 (u, v);				\
Packit bbfece
    w1 = __w.s.high;							\
Packit bbfece
    w0 = __w.s.low;							\
Packit bbfece
  } while (0)
Packit bbfece
#define __umulsidi3(u, v)		__builtin_umulsidi3 (u, v)
Packit bbfece
#define count_leading_zeros(COUNT, X)	((COUNT) = __builtin_clz (X))
Packit bbfece
#define count_trailing_zeros(COUNT, X)	((COUNT) = __builtin_ctz (X))
Packit bbfece
#endif /* __xtensa__ */
Packit bbfece
Packit bbfece
#if defined xstormy16
Packit bbfece
extern UHItype __stormy16_count_leading_zeros (UHItype);
Packit bbfece
#define count_leading_zeros(count, x)					\
Packit bbfece
  do									\
Packit bbfece
    {									\
Packit bbfece
      UHItype size;							\
Packit bbfece
									\
Packit bbfece
      /* We assume that W_TYPE_SIZE is a multiple of 16...  */		\
Packit bbfece
      for ((count) = 0, size = W_TYPE_SIZE; size; size -= 16)		\
Packit bbfece
	{								\
Packit bbfece
	  UHItype c;							\
Packit bbfece
									\
Packit bbfece
	  c = __clzhi2 ((x) >> (size - 16));				\
Packit bbfece
	  (count) += c;							\
Packit bbfece
	  if (c != 16)							\
Packit bbfece
	    break;							\
Packit bbfece
	}								\
Packit bbfece
    }									\
Packit bbfece
  while (0)
Packit bbfece
#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if defined (__z8000__) && W_TYPE_SIZE == 16
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("add	%H1,%H5\n\tadc	%H0,%H3"				\
Packit bbfece
	   : "=r" ((unsigned int)(sh)),					\
Packit bbfece
	     "=&r" ((unsigned int)(sl))					\
Packit bbfece
	   : "%0" ((unsigned int)(ah)),					\
Packit bbfece
	     "r" ((unsigned int)(bh)),					\
Packit bbfece
	     "%1" ((unsigned int)(al)),					\
Packit bbfece
	     "rQR" ((unsigned int)(bl)))
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  __asm__ ("sub	%H1,%H5\n\tsbc	%H0,%H3"				\
Packit bbfece
	   : "=r" ((unsigned int)(sh)),					\
Packit bbfece
	     "=&r" ((unsigned int)(sl))					\
Packit bbfece
	   : "0" ((unsigned int)(ah)),					\
Packit bbfece
	     "r" ((unsigned int)(bh)),					\
Packit bbfece
	     "1" ((unsigned int)(al)),					\
Packit bbfece
	     "rQR" ((unsigned int)(bl)))
Packit bbfece
#define umul_ppmm(xh, xl, m0, m1) \
Packit bbfece
  do {									\
Packit bbfece
    union {long int __ll;						\
Packit bbfece
	   struct {unsigned int __h, __l;} __i;				\
Packit bbfece
	  } __xx;							\
Packit bbfece
    unsigned int __m0 = (m0), __m1 = (m1);				\
Packit bbfece
    __asm__ ("mult	%S0,%H3"					\
Packit bbfece
	     : "=r" (__xx.__i.__h),					\
Packit bbfece
	       "=r" (__xx.__i.__l)					\
Packit bbfece
	     : "%1" (__m0),						\
Packit bbfece
	       "rQR" (__m1));						\
Packit bbfece
    (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;				\
Packit bbfece
    (xh) += ((((signed int) __m0 >> 15) & __m1)				\
Packit bbfece
	     + (((signed int) __m1 >> 15) & __m0));			\
Packit bbfece
  } while (0)
Packit bbfece
#endif /* __z8000__ */
Packit bbfece
Packit bbfece
#endif /* __GNUC__ */
Packit bbfece
Packit bbfece
/* If this machine has no inline assembler, use C macros.  */
Packit bbfece
Packit bbfece
#if !defined (add_ssaaaa)
Packit bbfece
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do {									\
Packit bbfece
    UWtype __x;								\
Packit bbfece
    __x = (al) + (bl);							\
Packit bbfece
    (sh) = (ah) + (bh) + (__x < (al));					\
Packit bbfece
    (sl) = __x;								\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if !defined (sub_ddmmss)
Packit bbfece
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
Packit bbfece
  do {									\
Packit bbfece
    UWtype __x;								\
Packit bbfece
    __x = (al) - (bl);							\
Packit bbfece
    (sh) = (ah) - (bh) - (__x > (al));					\
Packit bbfece
    (sl) = __x;								\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
Packit bbfece
   smul_ppmm.  */
Packit bbfece
#if !defined (umul_ppmm) && defined (smul_ppmm)
Packit bbfece
#define umul_ppmm(w1, w0, u, v)						\
Packit bbfece
  do {									\
Packit bbfece
    UWtype __w1;							\
Packit bbfece
    UWtype __xm0 = (u), __xm1 = (v);					\
Packit bbfece
    smul_ppmm (__w1, w0, __xm0, __xm1);					\
Packit bbfece
    (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1)		\
Packit bbfece
		+ (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0);		\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* If we still don't have umul_ppmm, define it using plain C.  */
Packit bbfece
#if !defined (umul_ppmm)
Packit bbfece
#define umul_ppmm(w1, w0, u, v)						\
Packit bbfece
  do {									\
Packit bbfece
    UWtype __x0, __x1, __x2, __x3;					\
Packit bbfece
    UHWtype __ul, __vl, __uh, __vh;					\
Packit bbfece
									\
Packit bbfece
    __ul = __ll_lowpart (u);						\
Packit bbfece
    __uh = __ll_highpart (u);						\
Packit bbfece
    __vl = __ll_lowpart (v);						\
Packit bbfece
    __vh = __ll_highpart (v);						\
Packit bbfece
									\
Packit bbfece
    __x0 = (UWtype) __ul * __vl;					\
Packit bbfece
    __x1 = (UWtype) __ul * __vh;					\
Packit bbfece
    __x2 = (UWtype) __uh * __vl;					\
Packit bbfece
    __x3 = (UWtype) __uh * __vh;					\
Packit bbfece
									\
Packit bbfece
    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
Packit bbfece
    __x1 += __x2;		/* but this indeed can */		\
Packit bbfece
    if (__x1 < __x2)		/* did we get it? */			\
Packit bbfece
      __x3 += __ll_B;		/* yes, add it in the proper pos.  */	\
Packit bbfece
									\
Packit bbfece
    (w1) = __x3 + __ll_highpart (__x1);					\
Packit bbfece
    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if !defined (__umulsidi3)
Packit bbfece
#define __umulsidi3(u, v) \
Packit bbfece
  ({DWunion __w;							\
Packit bbfece
    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
Packit bbfece
    __w.ll; })
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* Define this unconditionally, so it can be used for debugging.  */
Packit bbfece
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
Packit bbfece
  do {									\
Packit bbfece
    UWtype __d1, __d0, __q1, __q0;					\
Packit bbfece
    UWtype __r1, __r0, __m;						\
Packit bbfece
    __d1 = __ll_highpart (d);						\
Packit bbfece
    __d0 = __ll_lowpart (d);						\
Packit bbfece
									\
Packit bbfece
    __r1 = (n1) % __d1;							\
Packit bbfece
    __q1 = (n1) / __d1;							\
Packit bbfece
    __m = (UWtype) __q1 * __d0;						\
Packit bbfece
    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
Packit bbfece
    if (__r1 < __m)							\
Packit bbfece
      {									\
Packit bbfece
	__q1--, __r1 += (d);						\
Packit bbfece
	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
Packit bbfece
	  if (__r1 < __m)						\
Packit bbfece
	    __q1--, __r1 += (d);					\
Packit bbfece
      }									\
Packit bbfece
    __r1 -= __m;							\
Packit bbfece
									\
Packit bbfece
    __r0 = __r1 % __d1;							\
Packit bbfece
    __q0 = __r1 / __d1;							\
Packit bbfece
    __m = (UWtype) __q0 * __d0;						\
Packit bbfece
    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
Packit bbfece
    if (__r0 < __m)							\
Packit bbfece
      {									\
Packit bbfece
	__q0--, __r0 += (d);						\
Packit bbfece
	if (__r0 >= (d))						\
Packit bbfece
	  if (__r0 < __m)						\
Packit bbfece
	    __q0--, __r0 += (d);					\
Packit bbfece
      }									\
Packit bbfece
    __r0 -= __m;							\
Packit bbfece
									\
Packit bbfece
    (q) = (UWtype) __q1 * __ll_B | __q0;				\
Packit bbfece
    (r) = __r0;								\
Packit bbfece
  } while (0)
Packit bbfece
Packit bbfece
/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
Packit bbfece
   __udiv_w_sdiv (defined in libgcc or elsewhere).  */
Packit bbfece
#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
Packit bbfece
#define udiv_qrnnd(q, r, nh, nl, d) \
Packit bbfece
  do {									\
Packit bbfece
    extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);	\
Packit bbfece
    UWtype __r;								\
Packit bbfece
    (q) = __udiv_w_sdiv (&__r, nh, nl, d);				\
Packit bbfece
    (r) = __r;								\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
Packit bbfece
#if !defined (udiv_qrnnd)
Packit bbfece
#define UDIV_NEEDS_NORMALIZATION 1
Packit bbfece
#define udiv_qrnnd __udiv_qrnnd_c
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if !defined (count_leading_zeros)
Packit bbfece
#define count_leading_zeros(count, x) \
Packit bbfece
  do {									\
Packit bbfece
    UWtype __xr = (x);							\
Packit bbfece
    UWtype __a;								\
Packit bbfece
									\
Packit bbfece
    if (W_TYPE_SIZE <= 32)						\
Packit bbfece
      {									\
Packit bbfece
	__a = __xr < ((UWtype)1<<2*__BITS4)				\
Packit bbfece
	  ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4)			\
Packit bbfece
	  : (__xr < ((UWtype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
Packit bbfece
      }									\
Packit bbfece
    else								\
Packit bbfece
      {									\
Packit bbfece
	for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
Packit bbfece
	  if (((__xr >> __a) & 0xff) != 0)				\
Packit bbfece
	    break;							\
Packit bbfece
      }									\
Packit bbfece
									\
Packit bbfece
    (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
Packit bbfece
  } while (0)
Packit bbfece
#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if !defined (count_trailing_zeros)
Packit bbfece
/* Define count_trailing_zeros using count_leading_zeros.  The latter might be
Packit bbfece
   defined in asm, but if it is not, the C version above is good enough.  */
Packit bbfece
#define count_trailing_zeros(count, x) \
Packit bbfece
  do {									\
Packit bbfece
    UWtype __ctz_x = (x);						\
Packit bbfece
    UWtype __ctz_c;							\
Packit bbfece
    count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x);			\
Packit bbfece
    (count) = W_TYPE_SIZE - 1 - __ctz_c;				\
Packit bbfece
  } while (0)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#ifndef UDIV_NEEDS_NORMALIZATION
Packit bbfece
#define UDIV_NEEDS_NORMALIZATION 0
Packit bbfece
#endif