Blame stdlib/gmp-impl.h

Packit Service 82fcde
/* Include file for internal GNU MP types and definitions.
Packit Service 82fcde
Packit Service 82fcde
Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit Service 82fcde
Packit Service 82fcde
This file is part of the GNU MP Library.
Packit Service 82fcde
Packit Service 82fcde
The GNU MP Library is free software; you can redistribute it and/or modify
Packit Service 82fcde
it under the terms of the GNU Lesser General Public License as published by
Packit Service 82fcde
the Free Software Foundation; either version 2.1 of the License, or (at your
Packit Service 82fcde
option) any later version.
Packit Service 82fcde
Packit Service 82fcde
The GNU MP Library is distributed in the hope that it will be useful, but
Packit Service 82fcde
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service 82fcde
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit Service 82fcde
License for more details.
Packit Service 82fcde
Packit Service 82fcde
You should have received a copy of the GNU Lesser General Public License
Packit Service 82fcde
along with the GNU MP Library; see the file COPYING.LIB.  If not, see
Packit Service 82fcde
<http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/* When using gcc, make sure to use its builtin alloca.  */
Packit Service 82fcde
#if ! defined (alloca) && defined (__GNUC__)
Packit Service 82fcde
#define alloca __builtin_alloca
Packit Service 82fcde
#define HAVE_ALLOCA
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* When using cc, do whatever necessary to allow use of alloca.  For many
Packit Service 82fcde
   machines, this means including alloca.h.  IBM's compilers need a #pragma
Packit Service 82fcde
   in "each module that needs to use alloca".  */
Packit Service 82fcde
#if ! defined (alloca)
Packit Service 82fcde
/* We need lots of variants for MIPS, to cover all versions and perversions
Packit Service 82fcde
   of OSes for MIPS.  */
Packit Service 82fcde
#if defined (__mips) || defined (MIPSEL) || defined (MIPSEB) \
Packit Service 82fcde
 || defined (_MIPSEL) || defined (_MIPSEB) || defined (__sgi) \
Packit Service 82fcde
 || defined (__alpha) || defined (__sparc) || defined (sparc) \
Packit Service 82fcde
 || defined (__ksr__)
Packit Service 82fcde
#include <alloca.h>
Packit Service 82fcde
#define HAVE_ALLOCA
Packit Service 82fcde
#endif
Packit Service 82fcde
#if defined (_IBMR2)
Packit Service 82fcde
#pragma alloca
Packit Service 82fcde
#define HAVE_ALLOCA
Packit Service 82fcde
#endif
Packit Service 82fcde
#if defined (__DECC)
Packit Service 82fcde
#define alloca(x) __ALLOCA(x)
Packit Service 82fcde
#define HAVE_ALLOCA
Packit Service 82fcde
#endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if (! defined (alloca) && ! defined (HAVE_ALLOCA)) \
Packit Service 82fcde
    || defined (USE_STACK_ALLOC)
Packit Service 82fcde
#include "stack-alloc.h"
Packit Service 82fcde
#else
Packit Service 82fcde
#define TMP_DECL(m)
Packit Service 82fcde
#define TMP_ALLOC(x) alloca(x)
Packit Service 82fcde
#define TMP_MARK(m)
Packit Service 82fcde
#define TMP_FREE(m)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef NULL
Packit Service 82fcde
#define NULL ((void *) 0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if ! defined (__GNUC__)
Packit Service 82fcde
#define inline			/* Empty */
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Get MAX/MIN macros.  */
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
Packit Service 82fcde
/* Field access macros.  */
Packit Service 82fcde
#define SIZ(x) ((x)->_mp_size)
Packit Service 82fcde
#define PTR(x) ((x)->_mp_d)
Packit Service 82fcde
#define EXP(x) ((x)->_mp_exp)
Packit Service 82fcde
#define PREC(x) ((x)->_mp_prec)
Packit Service 82fcde
#define ALLOC(x) ((x)->_mp_alloc)
Packit Service 82fcde
Packit Service 82fcde
#include "gmp-mparam.h"
Packit Service 82fcde
/* #include "longlong.h" */
Packit Service 82fcde
Packit Service 82fcde
#if defined (__STDC__)  || defined (__cplusplus)
Packit Service 82fcde
void *malloc (size_t);
Packit Service 82fcde
void *realloc (void *, size_t);
Packit Service 82fcde
void free (void *);
Packit Service 82fcde
Packit Service 82fcde
extern void *	(*_mp_allocate_func) (size_t);
Packit Service 82fcde
extern void *	(*_mp_reallocate_func) (void *, size_t, size_t);
Packit Service 82fcde
extern void	(*_mp_free_func) (void *, size_t);
Packit Service 82fcde
Packit Service 82fcde
void *_mp_default_allocate (size_t);
Packit Service 82fcde
void *_mp_default_reallocate (void *, size_t, size_t);
Packit Service 82fcde
void _mp_default_free (void *, size_t);
Packit Service 82fcde
Packit Service 82fcde
#else
Packit Service 82fcde
Packit Service 82fcde
#define const			/* Empty */
Packit Service 82fcde
#define signed			/* Empty */
Packit Service 82fcde
Packit Service 82fcde
void *malloc ();
Packit Service 82fcde
void *realloc ();
Packit Service 82fcde
void free ();
Packit Service 82fcde
Packit Service 82fcde
extern void *	(*_mp_allocate_func) ();
Packit Service 82fcde
extern void *	(*_mp_reallocate_func) ();
Packit Service 82fcde
extern void	(*_mp_free_func) ();
Packit Service 82fcde
Packit Service 82fcde
void *_mp_default_allocate ();
Packit Service 82fcde
void *_mp_default_reallocate ();
Packit Service 82fcde
void _mp_default_free ();
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Copy NLIMBS *limbs* from SRC to DST.  */
Packit Service 82fcde
#define MPN_COPY_INCR(DST, SRC, NLIMBS) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mp_size_t __i;							\
Packit Service 82fcde
    for (__i = 0; __i < (NLIMBS); __i++)				\
Packit Service 82fcde
      (DST)[__i] = (SRC)[__i];						\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
#define MPN_COPY_DECR(DST, SRC, NLIMBS) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mp_size_t __i;							\
Packit Service 82fcde
    for (__i = (NLIMBS) - 1; __i >= 0; __i--)				\
Packit Service 82fcde
      (DST)[__i] = (SRC)[__i];						\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
#define MPN_COPY MPN_COPY_INCR
Packit Service 82fcde
Packit Service 82fcde
/* Zero NLIMBS *limbs* AT DST.  */
Packit Service 82fcde
#define MPN_ZERO(DST, NLIMBS) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mp_size_t __i;							\
Packit Service 82fcde
    for (__i = 0; __i < (NLIMBS); __i++)				\
Packit Service 82fcde
      (DST)[__i] = 0;							\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
Packit Service 82fcde
#define MPN_NORMALIZE(DST, NLIMBS) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    while (NLIMBS > 0)							\
Packit Service 82fcde
      {									\
Packit Service 82fcde
	if ((DST)[(NLIMBS) - 1] != 0)					\
Packit Service 82fcde
	  break;							\
Packit Service 82fcde
	NLIMBS--;							\
Packit Service 82fcde
      }									\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
#define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    while (1)								\
Packit Service 82fcde
      {									\
Packit Service 82fcde
	if ((DST)[(NLIMBS) - 1] != 0)					\
Packit Service 82fcde
	  break;							\
Packit Service 82fcde
	NLIMBS--;							\
Packit Service 82fcde
      }									\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
Packit Service 82fcde
/* Initialize the MP_INT X with space for NLIMBS limbs.
Packit Service 82fcde
   X should be a temporary variable, and it will be automatically
Packit Service 82fcde
   cleared out when the running function returns.
Packit Service 82fcde
   We use __x here to make it possible to accept both mpz_ptr and mpz_t
Packit Service 82fcde
   arguments.  */
Packit Service 82fcde
#define MPZ_TMP_INIT(X, NLIMBS) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mpz_ptr __x = (X);							\
Packit Service 82fcde
    __x->_mp_alloc = (NLIMBS);						\
Packit Service 82fcde
    __x->_mp_d = (mp_ptr) TMP_ALLOC ((NLIMBS) * BYTES_PER_MP_LIMB);	\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
Packit Service 82fcde
#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    if ((size) < KARATSUBA_THRESHOLD)					\
Packit Service 82fcde
      impn_mul_n_basecase (prodp, up, vp, size);			\
Packit Service 82fcde
    else								\
Packit Service 82fcde
      impn_mul_n (prodp, up, vp, size, tspace);			\
Packit Service 82fcde
  } while (0);
Packit Service 82fcde
#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    if ((size) < KARATSUBA_THRESHOLD)					\
Packit Service 82fcde
      impn_sqr_n_basecase (prodp, up, size);				\
Packit Service 82fcde
    else								\
Packit Service 82fcde
      impn_sqr_n (prodp, up, size, tspace);				\
Packit Service 82fcde
  } while (0);
Packit Service 82fcde
Packit Service 82fcde
/* Structure for conversion between internal binary format and
Packit Service 82fcde
   strings in base 2..36.  */
Packit Service 82fcde
struct bases
Packit Service 82fcde
{
Packit Service 82fcde
  /* Number of digits in the conversion base that always fits in an mp_limb_t.
Packit Service 82fcde
     For example, for base 10 on a machine where a mp_limb_t has 32 bits this
Packit Service 82fcde
     is 9, since 10**9 is the largest number that fits into a mp_limb_t.  */
Packit Service 82fcde
  int chars_per_limb;
Packit Service 82fcde
Packit Service 82fcde
  /* log(2)/log(conversion_base) */
Packit Service 82fcde
  float chars_per_bit_exactly;
Packit Service 82fcde
Packit Service 82fcde
  /* base**chars_per_limb, i.e. the biggest number that fits a word, built by
Packit Service 82fcde
     factors of base.  Exception: For 2, 4, 8, etc, big_base is log2(base),
Packit Service 82fcde
     i.e. the number of bits used to represent each digit in the base.  */
Packit Service 82fcde
  mp_limb_t big_base;
Packit Service 82fcde
Packit Service 82fcde
  /* A BITS_PER_MP_LIMB bit approximation to 1/big_base, represented as a
Packit Service 82fcde
     fixed-point number.  Instead of dividing by big_base an application can
Packit Service 82fcde
     choose to multiply by big_base_inverted.  */
Packit Service 82fcde
  mp_limb_t big_base_inverted;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
extern const struct bases __mp_bases[];
Packit Service 82fcde
extern mp_size_t __gmp_default_fp_limb_precision;
Packit Service 82fcde
Packit Service 82fcde
/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
Packit Service 82fcde
   limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
Packit Service 82fcde
   If this would yield overflow, DI should be the largest possible number
Packit Service 82fcde
   (i.e., only ones).  For correct operation, the most significant bit of D
Packit Service 82fcde
   has to be set.  Put the quotient in Q and the remainder in R.  */
Packit Service 82fcde
#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mp_limb_t _ql __attribute__ ((unused));				\
Packit Service 82fcde
    mp_limb_t _q, _r;							\
Packit Service 82fcde
    mp_limb_t _xh, _xl;							\
Packit Service 82fcde
    umul_ppmm (_q, _ql, (nh), (di));					\
Packit Service 82fcde
    _q += (nh);			/* DI is 2**BITS_PER_MP_LIMB too small */\
Packit Service 82fcde
    umul_ppmm (_xh, _xl, _q, (d));					\
Packit Service 82fcde
    sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl);				\
Packit Service 82fcde
    if (_xh != 0)							\
Packit Service 82fcde
      {									\
Packit Service 82fcde
	sub_ddmmss (_xh, _r, _xh, _r, 0, (d));				\
Packit Service 82fcde
	_q += 1;							\
Packit Service 82fcde
	if (_xh != 0)							\
Packit Service 82fcde
	  {								\
Packit Service 82fcde
	    sub_ddmmss (_xh, _r, _xh, _r, 0, (d));			\
Packit Service 82fcde
	    _q += 1;							\
Packit Service 82fcde
	  }								\
Packit Service 82fcde
      }									\
Packit Service 82fcde
    if (_r >= (d))							\
Packit Service 82fcde
      {									\
Packit Service 82fcde
	_r -= (d);							\
Packit Service 82fcde
	_q += 1;							\
Packit Service 82fcde
      }									\
Packit Service 82fcde
    (r) = _r;								\
Packit Service 82fcde
    (q) = _q;								\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
/* Like udiv_qrnnd_preinv, but for any value D.  DNORM is D shifted left
Packit Service 82fcde
   so that its most significant bit is set.  LGUP is ceil(log2(D)).  */
Packit Service 82fcde
#define udiv_qrnnd_preinv2gen(q, r, nh, nl, d, di, dnorm, lgup) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mp_limb_t n2, n10, n1, nadj, q1;					\
Packit Service 82fcde
    mp_limb_t _xh, _xl;							\
Packit Service 82fcde
    n2 = ((nh) << (BITS_PER_MP_LIMB - (lgup))) + ((nl) >> 1 >> (l - 1));\
Packit Service 82fcde
    n10 = (nl) << (BITS_PER_MP_LIMB - (lgup));				\
Packit Service 82fcde
    n1 = ((mp_limb_signed_t) n10 >> (BITS_PER_MP_LIMB - 1));		\
Packit Service 82fcde
    nadj = n10 + (n1 & (dnorm));					\
Packit Service 82fcde
    umul_ppmm (_xh, _xl, di, n2 - n1);					\
Packit Service 82fcde
    add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj);				\
Packit Service 82fcde
    q1 = ~(n2 + _xh);							\
Packit Service 82fcde
    umul_ppmm (_xh, _xl, q1, d);					\
Packit Service 82fcde
    add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl);				\
Packit Service 82fcde
    _xh -= (d);								\
Packit Service 82fcde
    (r) = _xl + ((d) & _xh);						\
Packit Service 82fcde
    (q) = _xh - q1;							\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
/* Exactly like udiv_qrnnd_preinv, but branch-free.  It is not clear which
Packit Service 82fcde
   version to use.  */
Packit Service 82fcde
#define udiv_qrnnd_preinv2norm(q, r, nh, nl, d, di) \
Packit Service 82fcde
  do {									\
Packit Service 82fcde
    mp_limb_t n2, n10, n1, nadj, q1;					\
Packit Service 82fcde
    mp_limb_t _xh, _xl;							\
Packit Service 82fcde
    n2 = (nh);								\
Packit Service 82fcde
    n10 = (nl);								\
Packit Service 82fcde
    n1 = ((mp_limb_signed_t) n10 >> (BITS_PER_MP_LIMB - 1));		\
Packit Service 82fcde
    nadj = n10 + (n1 & (d));						\
Packit Service 82fcde
    umul_ppmm (_xh, _xl, di, n2 - n1);					\
Packit Service 82fcde
    add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj);				\
Packit Service 82fcde
    q1 = ~(n2 + _xh);							\
Packit Service 82fcde
    umul_ppmm (_xh, _xl, q1, d);					\
Packit Service 82fcde
    add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl);				\
Packit Service 82fcde
    _xh -= (d);								\
Packit Service 82fcde
    (r) = _xl + ((d) & _xh);						\
Packit Service 82fcde
    (q) = _xh - q1;							\
Packit Service 82fcde
  } while (0)
Packit Service 82fcde
Packit Service 82fcde
#if defined (__GNUC__)
Packit Service 82fcde
/* Define stuff for longlong.h.  */
Packit Service 82fcde
typedef unsigned int UQItype	__attribute__ ((mode (QI)));
Packit Service 82fcde
typedef 	 int SItype	__attribute__ ((mode (SI)));
Packit Service 82fcde
typedef unsigned int USItype	__attribute__ ((mode (SI)));
Packit Service 82fcde
typedef		 int DItype	__attribute__ ((mode (DI)));
Packit Service 82fcde
typedef unsigned int UDItype	__attribute__ ((mode (DI)));
Packit Service 82fcde
#else
Packit Service 82fcde
typedef unsigned char UQItype;
Packit Service 82fcde
typedef 	 long SItype;
Packit Service 82fcde
typedef unsigned long USItype;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
typedef mp_limb_t UWtype;
Packit Service 82fcde
typedef unsigned int UHWtype;
Packit Service 82fcde
#define W_TYPE_SIZE BITS_PER_MP_LIMB
Packit Service 82fcde
Packit Service 82fcde
/* Internal mpn calls */
Packit Service 82fcde
#define impn_mul_n_basecase	__MPN(impn_mul_n_basecase)
Packit Service 82fcde
#define impn_mul_n		__MPN(impn_mul_n)
Packit Service 82fcde
#define impn_sqr_n_basecase	__MPN(impn_sqr_n_basecase)
Packit Service 82fcde
#define impn_sqr_n		__MPN(impn_sqr_n)
Packit Service 82fcde
Packit Service 82fcde
#ifndef _PROTO
Packit Service 82fcde
#if defined (__STDC__) || defined (__cplusplus)
Packit Service 82fcde
#define _PROTO(x) x
Packit Service 82fcde
#else
Packit Service 82fcde
#define _PROTO(x) ()
Packit Service 82fcde
#endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Prototypes for internal mpn calls.  */
Packit Service 82fcde
extern void impn_mul_n_basecase _PROTO ((mp_ptr prodp, mp_srcptr up,
Packit Service 82fcde
					 mp_srcptr vp, mp_size_t size))
Packit Service 82fcde
     attribute_hidden;
Packit Service 82fcde
extern void impn_mul_n _PROTO ((mp_ptr prodp, mp_srcptr up, mp_srcptr vp,
Packit Service 82fcde
				mp_size_t size, mp_ptr tspace))
Packit Service 82fcde
     attribute_hidden;
Packit Service 82fcde
extern void impn_sqr_n_basecase _PROTO ((mp_ptr prodp, mp_srcptr up,
Packit Service 82fcde
					 mp_size_t size))
Packit Service 82fcde
     attribute_hidden;
Packit Service 82fcde
extern void impn_sqr_n _PROTO ((mp_ptr prodp, mp_srcptr up, mp_size_t size,
Packit Service 82fcde
				mp_ptr tspace))
Packit Service 82fcde
     attribute_hidden;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#ifndef IEEE_DOUBLE_BIG_ENDIAN
Packit Service 82fcde
#define IEEE_DOUBLE_BIG_ENDIAN 1
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef IEEE_DOUBLE_MIXED_ENDIAN
Packit Service 82fcde
#define IEEE_DOUBLE_MIXED_ENDIAN 0
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if IEEE_DOUBLE_MIXED_ENDIAN
Packit Service 82fcde
union ieee_double_extract
Packit Service 82fcde
{
Packit Service 82fcde
  struct
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int manh:20;
Packit Service 82fcde
      unsigned int exp:11;
Packit Service 82fcde
      unsigned int sig:1;
Packit Service 82fcde
      unsigned int manl:32;
Packit Service 82fcde
    } s;
Packit Service 82fcde
  double d;
Packit Service 82fcde
};
Packit Service 82fcde
#else
Packit Service 82fcde
#if IEEE_DOUBLE_BIG_ENDIAN
Packit Service 82fcde
union ieee_double_extract
Packit Service 82fcde
{
Packit Service 82fcde
  struct
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int sig:1;
Packit Service 82fcde
      unsigned int exp:11;
Packit Service 82fcde
      unsigned int manh:20;
Packit Service 82fcde
      unsigned int manl:32;
Packit Service 82fcde
    } s;
Packit Service 82fcde
  double d;
Packit Service 82fcde
};
Packit Service 82fcde
#else
Packit Service 82fcde
union ieee_double_extract
Packit Service 82fcde
{
Packit Service 82fcde
  struct
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int manl:32;
Packit Service 82fcde
      unsigned int manh:20;
Packit Service 82fcde
      unsigned int exp:11;
Packit Service 82fcde
      unsigned int sig:1;
Packit Service 82fcde
    } s;
Packit Service 82fcde
  double d;
Packit Service 82fcde
};
Packit Service 82fcde
#endif
Packit Service 82fcde
#endif