linux/lib/crypto/mpi/longlong.h

/* 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