/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. * Note: I added some stuff for use with gnupg * * Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998, * 2000, 2001, 2002, 2003 Free Software Foundation, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this file; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ #include <linux/count_zeros.h> /* You have to define the following before including this file: * * UWtype -- An unsigned type, default type for operations (typically a "word") * UHWtype -- An unsigned type, at least half the size of UWtype. * UDWtype -- An unsigned type, at least twice as large a UWtype * W_TYPE_SIZE -- size in bits of UWtype * * SItype, USItype -- Signed and unsigned 32 bit types. * DItype, UDItype -- Signed and unsigned 64 bit types. * * On a 32 bit machine UWtype should typically be USItype; * on a 64 bit machine, UWtype should typically be UDItype. */ #define __BITS4 … #define __ll_B … #define __ll_lowpart(t) … #define __ll_highpart(t) … /* This is used to make sure no undesirable sharing between different libraries that use this file takes place. */ #ifndef __MPN #define __MPN(x) … #endif /* Define auxiliary asm macros. * * 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two * UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype * word product in HIGH_PROD and LOW_PROD. * * 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a * UDWtype product. This is just a variant of umul_ppmm. * 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, * denominator) divides a UDWtype, composed by the UWtype integers * HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient * in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less * than DENOMINATOR for correct operation. If, in addition, the most * significant bit of DENOMINATOR must be 1, then the pre-processor symbol * UDIV_NEEDS_NORMALIZATION is defined to 1. * 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, * denominator). Like udiv_qrnnd but the numbers are signed. The quotient * is rounded towards 0. * * 5) count_leading_zeros(count, x) counts the number of zero-bits from the * msb to the first non-zero bit in the UWtype X. This is the number of * steps X needs to be shifted left to set the msb. Undefined for X == 0, * unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. * * 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts * from the least significant end. * * 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, * high_addend_2, low_addend_2) adds two UWtype integers, composed by * HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 * respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow * (i.e. carry out) is not stored anywhere, and is lost. * * 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, * high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, * composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and * LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE * and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, * and is lost. * * If any of these macros are left undefined for a particular CPU, * C macros are used. */ /* The CPUs come in alphabetical order below. * * Please add support for more CPUs here, or improve the current support * for the CPUs below! */ #if defined(__GNUC__) && !defined(NO_ASM) /* We sometimes need to clobber "cc" with gcc2, but that would not be understood by gcc1. Use cpp to avoid major code duplication. */ #if __GNUC__ < 2 #define __CLOBBER_CC #define __AND_CLOBBER_CC #else /* __GNUC__ >= 2 */ #define __CLOBBER_CC … #define __AND_CLOBBER_CC … #endif /* __GNUC__ < 2 */ /*************************************** ************** A29K ***************** ***************************************/ #if (defined(__a29k__) || defined(_AM29K)) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #define udiv_qrnnd … #endif /* __a29k__ */ #if defined(__alpha) && W_TYPE_SIZE == 64 #define umul_ppmm … #define UMUL_TIME … #ifndef LONGLONG_STANDALONE #define udiv_qrnnd … extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); #define UDIV_TIME … #endif /* LONGLONG_STANDALONE */ #endif /* __alpha */ /*************************************** ************** ARM ****************** ***************************************/ #if defined(__arm__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__ #define umul_ppmm … #else #define umul_ppmm … #endif #define UMUL_TIME … #define UDIV_TIME … #endif /* __arm__ */ /*************************************** ************** CLIPPER ************** ***************************************/ #if defined(__clipper__) && W_TYPE_SIZE == 32 #define umul_ppmm … #define smul_ppmm … #define __umulsidi3 … #endif /* __clipper__ */ /*************************************** ************** GMICRO *************** ***************************************/ #if defined(__gmicro__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #define udiv_qrnnd … #endif /*************************************** ************** HPPA ***************** ***************************************/ #if defined(__hppa) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #if 0 && defined(_PA_RISC1_1) /* xmpyu uses floating point register which is not allowed in Linux kernel. */ #define umul_ppmm … #define UMUL_TIME … #define UDIV_TIME … #else #define UMUL_TIME … #define UDIV_TIME … #endif #if 0 /* #ifndef LONGLONG_STANDALONE */ #define udiv_qrnnd … extern USItype __udiv_qrnnd(); #endif /* LONGLONG_STANDALONE */ #endif /* hppa */ /*************************************** ************** I370 ***************** ***************************************/ #if (defined(__i370__) || defined(__mvs__)) && W_TYPE_SIZE == 32 #define umul_ppmm … #define smul_ppmm … #define sdiv_qrnnd … #endif /*************************************** ************** I386 ***************** ***************************************/ #undef __i386__ #if (defined(__i386__) || defined(__i486__)) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #define udiv_qrnnd … #ifndef UMUL_TIME #define UMUL_TIME … #endif #ifndef UDIV_TIME #define UDIV_TIME … #endif #endif /* 80x86 */ /*************************************** ************** I860 ***************** ***************************************/ #if defined(__i860__) && W_TYPE_SIZE == 32 #define rshift_rhlc … #endif /* i860 */ /*************************************** ************** I960 ***************** ***************************************/ #if defined(__i960__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #define __umulsidi3 … #define udiv_qrnnd … #if defined(__i960mx) /* what is the proper symbol to test??? */ #define rshift_rhlc … #endif /* i960mx */ #endif /* i960 */ /*************************************** ************** 68000 **************** ***************************************/ #if (defined(__mc68000__) || defined(__mc68020__) || defined(__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #if (defined(__mc68020__) || defined(__NeXT__) || defined(mc68020)) #define umul_ppmm … #define UMUL_TIME … #define udiv_qrnnd … #define UDIV_TIME … #define sdiv_qrnnd … #else /* not mc68020 */ #define umul_ppmm … #define UMUL_TIME … #define UDIV_TIME … #endif /* not mc68020 */ #endif /* mc68000 */ /*************************************** ************** 88000 **************** ***************************************/ #if defined(__m88000__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #if defined(__m88110__) #define umul_ppmm … #define udiv_qrnnd … #define UMUL_TIME … #define UDIV_TIME … #else #define UMUL_TIME … #define UDIV_TIME … #endif /* __m88110__ */ #endif /* __m88000__ */ /*************************************** ************** MIPS ***************** ***************************************/ #if defined(__mips__) && W_TYPE_SIZE == 32 #define umul_ppmm … #define UMUL_TIME … #define UDIV_TIME … #endif /* __mips__ */ /*************************************** ************** MIPS/64 ************** ***************************************/ #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 #if defined(__mips_isa_rev) && __mips_isa_rev >= 6 && defined(CONFIG_CC_IS_GCC) /* * GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C * code below, so we special case MIPS64r6 until the compiler can do better. */ #define umul_ppmm … #else #define umul_ppmm … #endif #define UMUL_TIME … #define UDIV_TIME … #endif /* __mips__ */ /*************************************** ************** 32000 **************** ***************************************/ #if defined(__ns32000__) && W_TYPE_SIZE == 32 #define umul_ppmm … #define __umulsidi3 … #define udiv_qrnnd … #endif /* __ns32000__ */ /*************************************** ************** PPC ****************** ***************************************/ #if (defined(_ARCH_PPC) || defined(_IBMR2)) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #if defined(_ARCH_PPC) #define umul_ppmm … #define UMUL_TIME … #define smul_ppmm … #define SMUL_TIME … #define UDIV_TIME … #else #define umul_ppmm … #define UMUL_TIME … #define smul_ppmm … #define SMUL_TIME … #define sdiv_qrnnd … #define UDIV_TIME … #endif #endif /* Power architecture variants. */ /*************************************** ************** PYR ****************** ***************************************/ #if defined(__pyr__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … /* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */ #define umul_ppmm … #endif /* __pyr__ */ /*************************************** ************** RT/ROMP ************** ***************************************/ #if defined(__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #define UMUL_TIME … #define UDIV_TIME … #endif /* RT/ROMP */ /*************************************** ************** SH2 ****************** ***************************************/ #if (defined(__sh2__) || defined(__sh3__) || defined(__SH4__)) \ && W_TYPE_SIZE == 32 #define umul_ppmm … #define UMUL_TIME … #endif /*************************************** ************** SPARC **************** ***************************************/ #if defined(__sparc__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #if defined(__sparc_v8__) /* Don't match immediate range because, 1) it is not often useful, 2) the 'I' flag thinks of the range as a 13 bit signed interval, while we want to match a 13 bit interval, sign extended to 32 bits, but INTERPRETED AS UNSIGNED. */ #define umul_ppmm … #define UMUL_TIME … #ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */ #define udiv_qrnnd … #define UDIV_TIME … #endif /* SUPERSPARC */ #else /* ! __sparc_v8__ */ #if defined(__sparclite__) /* This has hardware multiply but not divide. It also has two additional instructions scan (ffs from high bit) and divscc. */ #define umul_ppmm … #define UMUL_TIME … #define udiv_qrnnd … #define UDIV_TIME … #endif /* __sparclite__ */ #endif /* __sparc_v8__ */ /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ #ifndef umul_ppmm #define umul_ppmm … #define UMUL_TIME … /* It's quite necessary to add this much assembler for the sparc. The default udiv_qrnnd (in C) is more than 10 times slower! */ #define udiv_qrnnd … #define UDIV_TIME … #endif #endif /* __sparc__ */ /*************************************** ************** VAX ****************** ***************************************/ #if defined(__vax__) && W_TYPE_SIZE == 32 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #define sdiv_qrnnd … #endif /* __vax__ */ /*************************************** ************** Z8000 **************** ***************************************/ #if defined(__z8000__) && W_TYPE_SIZE == 16 #define add_ssaaaa … #define sub_ddmmss … #define umul_ppmm … #endif /* __z8000__ */ #endif /* __GNUC__ */ /*************************************** *********** Generic Versions ******** ***************************************/ #if !defined(umul_ppmm) && defined(__umulsidi3) #define umul_ppmm … #endif #if !defined(__umulsidi3) #define __umulsidi3(u, v) … #endif /* If this machine has no inline assembler, use C macros. */ #if !defined(add_ssaaaa) #define add_ssaaaa(sh, sl, ah, al, bh, bl) … #endif #if !defined(sub_ddmmss) #define sub_ddmmss(sh, sl, ah, al, bh, bl) … #endif #if !defined(umul_ppmm) #define umul_ppmm(w1, w0, u, v) … #endif #if !defined(umul_ppmm) #define smul_ppmm … #endif /* Define this unconditionally, so it can be used for debugging. */ #define __udiv_qrnnd_c(q, r, n1, n0, d) … /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through __udiv_w_sdiv (defined in libgcc or elsewhere). */ #if !defined(udiv_qrnnd) && defined(sdiv_qrnnd) #define udiv_qrnnd … #endif /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ #if !defined(udiv_qrnnd) #define UDIV_NEEDS_NORMALIZATION … #define udiv_qrnnd … #endif #ifndef UDIV_NEEDS_NORMALIZATION #define UDIV_NEEDS_NORMALIZATION … #endif