⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gmp-impl.h

📁 手机加密通话软件
💻 H
📖 第 1 页 / 共 5 页
字号:
/* Include file for internal GNU MP types and definitions.

   THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND ARE ALMOST CERTAIN TO
   BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE GNU MP RELEASES.

Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002 Free
Software Foundation, Inc.

This file is part of the GNU MP Library.

The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.

The GNU MP Library 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 Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */


#ifndef __GMP_IMPL_H__
#define __GMP_IMPL_H__

/* On Cray vector systems "short" and "unsigned short" might not be the same
   number of bits, making the SHRT_MAX defaults below fail.  (This depends
   on compiler options.)  Instead use limits.h.  */
#if defined _CRAY
#include <limits.h>
#endif

#if ! __GMP_WITHIN_CONFIGURE
#include "config.h"
#include "gmp-mparam.h"
#endif

#ifndef _WIN32_WCE
#ifdef __cplusplus
#include <string>
#endif
#endif

/* Might search and replace _PROTO to __GMP_PROTO internally one day, to
   avoid two names for one thing, but no hurry for that.  */
#define _PROTO(x)  __GMP_PROTO(x)

/* The following tries to get a good version of alloca.  The tests are
   adapted from autoconf AC_FUNC_ALLOCA, with a couple of additions.
   Whether this succeeds is tested by GMP_FUNC_ALLOCA and HAVE_ALLOCA will
   be setup appropriately.

   ifndef alloca - a cpp define might already exist.
       glibc <stdlib.h> includes <alloca.h> which uses GCC __builtin_alloca.
       HP cc +Olibcalls adds a #define of alloca to __builtin_alloca.

   GCC __builtin_alloca - preferred whenever available.

   _AIX pragma - IBM compilers need a #pragma in "each module that needs to
       use alloca".  Pragma indented to protect pre-ANSI cpp's.  _IBMR2 was
       used in past versions of GMP, retained still in case it matters.

       The autoconf manual says this pragma needs to be at the start of a C
       file, apart from comments and preprocessor directives.  Is that true?
       xlc on aix 4.xxx doesn't seem to mind it being after prototypes etc
       from gmp.h.
*/

#ifndef alloca
# ifdef __GNUC__
#  define alloca __builtin_alloca
# else
#  ifdef __DECC
#   define alloca(x) __ALLOCA(x)
#  else
#   ifdef _MSC_VER
#    include <malloc.h>
#    define alloca _alloca
#   else
#    ifdef HAVE_ALLOCA_H
//#     include <alloca.h>
#    else
#     if defined (_AIX) || defined (_IBMR2)
 #pragma alloca
#     else
       char *alloca ();
#     endif
#    endif
#   endif
#  endif
# endif
#endif


/* const and signed must match __gmp_const and __gmp_signed, so follow the
   decision made for those in gmp.h.    */
#if ! __GMP_HAVE_CONST
#define const   /* empty */
#define signed  /* empty */
#endif


/* "const" basically means a function does nothing but examine its arguments
   and give a return value, it doesn't read or write any memory (neither
   global nor pointed to by arguments), and has no other side-effects.  This
   is more restrictive than "pure".  See info node "(gcc)Function
   Attributes".  */
#if HAVE_ATTRIBUTE_CONST
#define ATTRIBUTE_CONST  __attribute__ ((const))
#else
#define ATTRIBUTE_CONST
#endif

#if HAVE_ATTRIBUTE_NORETURN
#define ATTRIBUTE_NORETURN  __attribute__ ((noreturn))
#else
#define ATTRIBUTE_NORETURN
#endif

/* "malloc" means a function behaves like malloc in that the pointer it
   returns doesn't alias anything.  */
#if HAVE_ATTRIBUTE_MALLOC
#define ATTRIBUTE_MALLOC  __attribute__ ((malloc))
#else
#define ATTRIBUTE_MALLOC
#endif

#ifdef _CRAY
#define CRAY_Pragma(str)  _Pragma (str)
#else
#define CRAY_Pragma(str)
#endif


#if ! HAVE_STRCHR
#define strchr(s,c)  index(s,c)
#endif

#if ! HAVE_MEMSET
#define memset(p, c, n)                 \
  do {                                  \
    ASSERT (n >= 0);                    \
    int  __i;                           \
    for (__i = 0; __i < (n); __i++)     \
      (p)[__i] = (c);                   \
  } while (0)
#endif

/* va_copy is standard in C99, and gcc provides __va_copy when in strict C89
   mode.  Falling back to a memcpy will give maximum portability, since it
   works no matter whether va_list is a pointer, struct or array.  */
#if ! defined (va_copy) && defined (__va_copy)
#define va_copy(dst,src)  __va_copy(dst,src)
#endif
#if ! defined (va_copy)
#define va_copy(dst,src) \
  do { memcpy (&(dst), &(src), sizeof (va_list)); } while (0)
#endif


#if defined (__cplusplus)
extern "C" {
#endif


/* Usage: TMP_DECL (marker);
          TMP_MARK (marker);
          ptr = TMP_ALLOC (bytes);
          TMP_FREE (marker);

   TMP_DECL just declares a variable, but might be empty and so must be last
   in a list of variables.  TMP_MARK must be done before any TMP_ALLOC.
   TMP_ALLOC(0) is not allowed.  TMP_FREE doesn't need to be done if a
   TMP_MARK was made, but then no TMP_ALLOCs.

   The name "marker" isn't used by the malloc-reentrant and debug methods,
   instead they hardcode a name which TMP_ALLOC will know.  For that reason
   two TMP_DECLs are not allowed, unless one is in a nested "{ }" block, and
   in that case TMP_MARK, TMP_ALLOC and TMP_FREE will refer to the TMP_DECL
   which is in scope, irrespective of the marker name given.  */

/* The alignment in bytes, used for TMP_ALLOCed blocks, when alloca or
   __gmp_allocate_func doesn't already determine it.  Currently TMP_ALLOC
   isn't used for "double"s, so that's not in the union.  */
union tmp_align_t {
  mp_limb_t  l;
  char       *p;
};
#define __TMP_ALIGN  sizeof (union tmp_align_t)

/* Return "a" rounded upwards to a multiple of "m", if it isn't already.
   "a" must be an unsigned type.  */
#define ROUND_UP_MULTIPLE(a,m)  ((a) + (-(a))%(m))

#if WANT_TMP_ALLOCA
/* Each TMP_ALLOC is simply an alloca(), and nothing else is needed.
   This is the preferred method.  */
#define TMP_DECL(m)
#define TMP_ALLOC(x) alloca(x)
#define TMP_MARK(m)
#define TMP_FREE(m)
#endif

#if WANT_TMP_REENTRANT
/* See tal-reent.c for some comments. */
struct tmp_reentrant_t {
  struct tmp_reentrant_t  *next;
  size_t                  size;   /* bytes, including header */
};
void *__gmp_tmp_reentrant_alloc _PROTO ((struct tmp_reentrant_t **, size_t)) ATTRIBUTE_MALLOC;
void  __gmp_tmp_reentrant_free _PROTO ((struct tmp_reentrant_t *));
#define TMP_DECL(marker)   struct tmp_reentrant_t *__tmp_marker
/* don't demand NULL, just cast a zero */
#define TMP_MARK(marker) \
  do { __tmp_marker = (struct tmp_reentrant_t *) 0; } while (0)
#define TMP_ALLOC(size)    __gmp_tmp_reentrant_alloc (&__tmp_marker, size)
#define TMP_FREE(marker)   __gmp_tmp_reentrant_free  (__tmp_marker)
#endif

#if WANT_TMP_NOTREENTRANT
/* See tal-notreent.c for some comments. */
struct tmp_marker
{
  struct tmp_stack *which_chunk;
  void *alloc_point;
};
typedef struct tmp_marker tmp_marker;
void *__gmp_tmp_alloc _PROTO ((unsigned long)) ATTRIBUTE_MALLOC;
void __gmp_tmp_mark _PROTO ((tmp_marker *));
void __gmp_tmp_free _PROTO ((tmp_marker *));
#define TMP_DECL(marker) tmp_marker marker
/* gcc recognises "(-(8*n))%8" or the like is always zero, which means the
   rounding up is a noop for allocs of whole limbs. */
#define TMP_ALLOC(size) \
  __gmp_tmp_alloc (ROUND_UP_MULTIPLE ((unsigned long) (size), __TMP_ALIGN))
#define TMP_MARK(marker) __gmp_tmp_mark (&marker)
#define TMP_FREE(marker) __gmp_tmp_free (&marker)
#endif

#if WANT_TMP_DEBUG
/* See tal-debug.c for some comments. */
struct tmp_debug_t {
  struct tmp_debug_entry_t  *list;
  const char                *file;
  int                       line;
};
struct tmp_debug_entry_t {
  struct tmp_debug_entry_t  *next;
  char                      *block;
  size_t                    size;
};
void  __gmp_tmp_debug_mark  _PROTO ((const char *, int, struct tmp_debug_t **,
                                     struct tmp_debug_t *,
                                     const char *, const char *));
void *__gmp_tmp_debug_alloc _PROTO ((const char *, int, int,
                                     struct tmp_debug_t **, const char *,
                                     size_t)) ATTRIBUTE_MALLOC;
void  __gmp_tmp_debug_free  _PROTO ((const char *, int, int,
                                     struct tmp_debug_t **,
                                     const char *, const char *));
#if HAVE_STRINGIZE
#define TMP_DECL(marker) TMP_DECL_NAME(marker, #marker)
#define TMP_MARK(marker) TMP_MARK_NAME(marker, #marker)
#define TMP_FREE(marker) TMP_FREE_NAME(marker, #marker)
#else
#define TMP_DECL(marker) TMP_DECL_NAME(marker, "marker")
#define TMP_MARK(marker) TMP_MARK_NAME(marker, "marker")
#define TMP_FREE(marker) TMP_FREE_NAME(marker, "marker")
#endif
/* The marker variable is designed to provoke an uninitialized varialble
   warning from the compiler if TMP_FREE is used without a TMP_MARK.
   __tmp_marker_inscope does the same for TMP_ALLOC.  Runtime tests pick
   these things up too.  */
#define TMP_DECL_NAME(marker, marker_name)                      \
  int marker;                                                   \
  int __tmp_marker_inscope;                                     \
  const char *__tmp_marker_name = marker_name;                  \
  struct tmp_debug_t  __tmp_marker_struct;                      \
  /* don't demand NULL, just cast a zero */                     \
  struct tmp_debug_t  *__tmp_marker = (struct tmp_debug_t *) 0
#define TMP_MARK_NAME(marker, marker_name)                      \
  do {                                                          \
    marker = 1;                                                 \
    __tmp_marker_inscope = 1;                                   \
    __gmp_tmp_debug_mark  (ASSERT_FILE, ASSERT_LINE,            \
                           &__tmp_marker, &__tmp_marker_struct, \
                           __tmp_marker_name, marker_name);     \
  } while (0)
#define TMP_ALLOC(size)                                                 \
  __gmp_tmp_debug_alloc (ASSERT_FILE, ASSERT_LINE,                      \
                         __tmp_marker_inscope,                          \
                         &__tmp_marker, __tmp_marker_name, size)
#define TMP_FREE_NAME(marker, marker_name)                      \
  do {                                                          \
    __gmp_tmp_debug_free  (ASSERT_FILE, ASSERT_LINE,            \
                           marker, &__tmp_marker,               \
                           __tmp_marker_name, marker_name);     \
  } while (0)
#endif


/* Allocating various types. */
#define TMP_ALLOC_TYPE(n,type) ((type *) TMP_ALLOC ((n) * sizeof (type)))
#define TMP_ALLOC_LIMBS(n)     TMP_ALLOC_TYPE(n,mp_limb_t)
#define TMP_ALLOC_MP_PTRS(n)   TMP_ALLOC_TYPE(n,mp_ptr)

/* It's more efficient to allocate one block than two.  This is certainly
   true of the malloc methods, but it can even be true of alloca if that
   involves copying a chunk of stack (various RISCs), or a call to a stack
   bounds check (mingw).  In any case, when debugging keep separate blocks
   so a redzoning malloc debugger can protect each individually.  */
#if WANT_TMP_DEBUG
#define TMP_ALLOC_LIMBS_2(xp,xsize, yp,ysize)   \
  do {                                          \
    (xp) = TMP_ALLOC_LIMBS (xsize);             \
    (yp) = TMP_ALLOC_LIMBS (ysize);             \
  } while (0)
#else
#define TMP_ALLOC_LIMBS_2(xp,xsize, yp,ysize)   \
  do {                                          \
    (xp) = TMP_ALLOC_LIMBS ((xsize) + (ysize)); \
    (yp) = (xp) + (xsize);                      \
  } while (0)
#endif


/* From gmp.h, nicer names for internal use. */
#define MPN_CMP(result, xp, yp, size)  __GMPN_CMP(result, xp, yp, size)

#define ABS(x) ((x) >= 0 ? (x) : -(x))
#define MIN(l,o) ((l) < (o) ? (l) : (o))
#define MAX(h,i) ((h) > (i) ? (h) : (i))
#define numberof(x)  (sizeof (x) / sizeof ((x)[0]))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -