/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
/* Last modified_on Fri Aug 17 17:19:01 GMT+2:00 1990 by shand */
/*      modified_on Wed Jul  5 10:19:33 GMT+2:00 1989 by bertin */
/*      modified_on Fri Apr 28 20:03:23 GMT+2:00 1989 by herve */
/*      modified_on Jul 29, 1991 by sudarshan */


/* BigN.h - Types and structures for clients of BigNum */



		/******** representation of a bignum ******/
/*
**  <--------------------------- nl ---------------------------->
**  |   Least                                           Most    |
**  |Significant|           |           |           |Significant|
**  |BigNumDigit|           |           |           |BigNumDigit|
**  |___________|___________|___________|___________|___________|
**        ^                                          (sometimes
**        |                                            is zero)
**       nn
*/

#include "../../includes/config.h" 
#ifndef CONFIG_H

#ifdef c_plusplus
#undef __GNUG__ /* In case we're using gcc-cpp with ATT's CC. */
#undef __GNUC__
#endif
#if defined(__STDC__) || defined(__cplusplus)
/* The following macro helps define argument lists for fns: the arg lists are
	eaten up when not allowed (as in C).
        e.g. extern int foo ARGS((int, int));
*/
#define ARGS(args) args
#define CONST const
typedef void *Pointer;
typedef const void *ConstPointer;
#else
#define ARGS(args) ()
#define CONST
typedef char *Pointer;
typedef char *ConstPointer;
#define void int
#endif

#ifdef __cplusplus
#define CPLUS
#define EXTERN extern "C"
#else
#define EXTERN extern
#endif
#ifdef __GNUC__
#define alloca(size) __builtin_alloca(size)
#endif

#endif	/* CONFIG_H*/


/* signals BigNum.h already included */
#define BIGNUM

		/*************** sizes ********************/

#define BN_BYTE_SIZE			8
#define BN_WORD_SIZE			(sizeof (int) * BN_BYTE_SIZE)
#define BN_DIGIT_SIZE			(sizeof (BigNumDigit) * BN_BYTE_SIZE)

/* notes: */
/* BN_BYTE_SIZE: number of bits in a byte */
/* BN_WORD_SIZE: number of bits in an "int" in the target language */
/* BN_DIGIT_SIZE: number of bits in a digit of a BigNum */


		/****** results of compare functions ******/

 /* Note: we don't use "enum" to interface with Modula2+, Lisp, ... */
#define BN_LT				-1
#define BN_EQ				0
#define BN_GT				1

		/*************** boolean ******************/

#define TRUE				1
#define FALSE				0


		/* if DIGITon16BITS is defined, a single digit is on 16 bits */
		/* otherwise (by default) a single digit is on 32 bits *****/
		/* Note: on 32 bit machine it makes little sense to mix */
		/* longs and short, so we define Boolean & BigNumCmp to be */
		/* int usually */

#ifdef DIGITon16BITS
typedef unsigned short			BigNumDigit;
typedef short				Boolean;
#else
typedef unsigned int 			BigNumDigit;
typedef int				Boolean;
#endif


		/* bignum types: digits, big numbers, carries ... */

typedef BigNumDigit * 	BigNum;		/* A big number is a digit pointer */
typedef BigNumDigit	BigNumCarry;	/* Either 0 or 1 */
typedef unsigned long 	BigNumProduct;	/* The product of two digits */
typedef unsigned long	BigNumLength;	/* The length of a bignum */
#ifdef DIGITon16BITS
typedef short		BigNumCmp;	/* result of comparison */
#else
typedef int		BigNumCmp;	/* result of comparison */
#endif


/**/


		/************ functions of bn.c ***********/

EXTERN void 		BnnInit 	ARGS(( ));
EXTERN void             BnnClose	ARGS(());

EXTERN Boolean		BnnIsZero 	ARGS((BigNum, BigNumLength));
EXTERN BigNumCarry 	BnnMultiply	ARGS((BigNum, BigNumLength, BigNum, 
					  BigNumLength, BigNum, BigNumLength));
EXTERN void		BnnDivide	ARGS((BigNum, BigNumLength, BigNum, 
						BigNumLength));
EXTERN BigNumCmp	BnnCompare	ARGS((BigNum, BigNumLength, BigNum, 
						BigNumLength));


		/*********** functions of KerN.c **********/

EXTERN void 		BnnSetToZero	ARGS((BigNum, int));
EXTERN void 		BnnAssign	ARGS((BigNum,BigNum,int));
EXTERN void 		BnnSetDigit	ARGS((BigNum,int));
EXTERN BigNumDigit 	BnnGetDigit	ARGS((BigNum));
EXTERN BigNumLength	BnnNumDigits	ARGS((BigNum,int));
EXTERN BigNumDigit	BnnNumLeadingZeroBitsInDigit	ARGS((BigNumDigit));
EXTERN Boolean 		BnnDoesDigitFitInWord 	ARGS((BigNumDigit));
EXTERN Boolean		BnnIsDigitZero 		ARGS((BigNumDigit));
EXTERN Boolean		BnnIsDigitNormalized 	ARGS((BigNumDigit));
EXTERN Boolean 		BnnIsDigitOdd		ARGS((BigNumDigit));
EXTERN BigNumCmp	BnnCompareDigits	ARGS((BigNumDigit, 
							BigNumDigit));
EXTERN void 		BnnComplement	ARGS((BigNum, int));
EXTERN void 		BnnAndDigits	ARGS((BigNum, BigNumDigit));
EXTERN void		BnnOrDigits	ARGS((BigNum, BigNumDigit));
EXTERN void		BnnXorDigits	ARGS((BigNum, BigNumDigit));
EXTERN BigNumDigit	BnnShiftLeft	ARGS((BigNum, int, int));
EXTERN BigNumDigit	BnnShiftRight	ARGS((BigNum, int, int));
EXTERN BigNumCarry 	BnnAddCarry	ARGS((BigNum, int, BigNumCarry));
EXTERN BigNumCarry 	BnnAdd		ARGS((BigNum, int, BigNum, int, 
							BigNumCarry));
EXTERN BigNumCarry 	BnnSubtractBorrow	ARGS((BigNum, int,
							BigNumCarry));
EXTERN BigNumCarry 	BnnSubtract		ARGS((BigNum, int, BigNum, 
							int, BigNumCarry));
EXTERN BigNumCarry 	BnnMultiplyDigit	ARGS((BigNum, int, BigNum,
							int, BigNumDigit));
EXTERN BigNumDigit	BnnDivideDigit		ARGS((BigNum, BigNum, int,
							BigNumDigit));

/**/

		/* some functions can be written with macro-procedures */


#ifndef BNNMACROS_OFF
/* the functions BnnIsZero and BnnCompareDigits are not macro procedures
since they use parameters twice, and that can produce some bugs if
you pass a parameter like x++, the increment will be executed twice ! */
#define BnnSetDigit(nn,d) 		(*(nn) = (d))
#define BnnGetDigit(nn)			((unsigned)(*(nn)))
#define BnnDoesDigitFitInWord(d)	(BN_DIGIT_SIZE > BN_WORD_SIZE ? ((d) >= 1 << BN_WORD_SIZE ? FALSE : TRUE) : TRUE)
#define BnnIsDigitZero(d)		((d) == 0)
#define BnnIsDigitNormalized(d)		((d) & (1 << (BN_DIGIT_SIZE - 1)) ? TRUE : FALSE)
#define BnnIsDigitOdd(d) 		((d) & 1 ? TRUE : FALSE)
#define BnnAndDigits(nn, d)		(*(nn) &= (d))
#define BnnOrDigits(nn, d)		(*(nn) |= (d))
#define BnnXorDigits(nn, d)		(*(nn) ^= (d))

#endif


