299 lines
13 KiB
Plaintext
299 lines
13 KiB
Plaintext
Copyright 2008, William Hart
|
|
|
|
This file is part of the MPIR Library.
|
|
|
|
The MPIR 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 MPIR 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 MPIR Library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA.
|
|
|
|
MACROS in gmp_impl.h
|
|
===========================================
|
|
LIKELY(cond) - branch hint (likely), e.g. if LIKELY(x > 0)....
|
|
UNLIKELY(cond) - branch hint (unlikely)
|
|
|
|
ABS(x) - absolute value of x
|
|
MIN(x, y) - minimum of x and y (operands may be signed or unsigned)
|
|
MAX(x, y) - maximum of x and y
|
|
numberof(x) - assumes x is a pointer to an array, returns the number of elements
|
|
of the array that fit into a type the same size as a pointer (??)
|
|
|
|
SIZ(z) - _mp_size field of z
|
|
ABSIZ(z) - abs val of SIZ(z)
|
|
PTR(z) - _mp_d field of z
|
|
LIMBS(z) - same as PTR(z)
|
|
EXP(z) - _mp_exp field of x
|
|
PREC(x) - _mp_prec field of x
|
|
ALLOC(x) - _mp_alloc field of x
|
|
|
|
MP_LIMB_T_SWAP(x, y) - swap two mp_limb_t's
|
|
MP_SIZE_T_SWAP(x, y) - swap two mp_size_t's
|
|
MP_PTR_SWAP(x, y) - swap two mp_ptr's
|
|
MP_SRCPTR_SWAP(x, y) - swap two mp_srcptr's
|
|
MPN_PTR_SWAP(xp, xs, yp, ys) - swap {xp, xs} and {yp, ys}
|
|
MPN_SRCPTR_SWAP(xp, xs, yp, ys) - swap {xp, xs} and {yp, ys}
|
|
MPZ_PTR_SWAP(x, y) - swap two mpz_ptr's
|
|
MPZ_SRCPTR_SWAP(x, y) - swap two mpz_srcptr's
|
|
|
|
MPN_CMP(result, xp, yp, size) - compare {xp, size} with {yp, size} and set
|
|
result to -1, 0, 1, size may be zero
|
|
MPN_COPY_INCR(dst, src, size) - copy size limbs from src to dst incrementing
|
|
memory locations throughout copy (i.e. src must come after dst if they overlap)
|
|
size == 0 is allowed
|
|
MPN_COPY_DECR(dst, src, size) - as for MPN_COPY_INCR except ptrs are decremented
|
|
(i.e. src must come before dst if they overlap)
|
|
MPN_COPY(dst, src, size) - copy size limbs from src to dst which must be same
|
|
or separate
|
|
MPN_REVERSE(dst, src, size) - set {dst, size} to the limbs of {src, size} in
|
|
reverse order
|
|
MPN_ZERO(dst, n) - set n limbs at dst to zero
|
|
mpn_com_n(dst, src, size) - set {dst, size} to the complement of {src, size}
|
|
mpn_and_n(dst, src1, src2, n) - set {dst, n} to {src1, n} & {src2, n}
|
|
mpn_andn_n(dst, src1, src2, n) - set {dst, n} to {src1, n} & ~{src2, n}
|
|
mpn_nand_n(dst, src1, src2, n) - set {dst, n} to {src1, n} nand {src2, n}
|
|
mpn_ior_n(dst, src1, src2, n) - set {dst, n} to {src1, n} | {src2, n}
|
|
mpn_iorn_n(dst, src1, src2, n) - set {dst, n} to {src1, n} | ~{src2, n}
|
|
mpn_nior_n(dst, src1, src2, n) - set {dst, n} to {src1, n} nor {src2, n}
|
|
mpn_xor_n(dst, src1, src2, n) - set {dst, n} to {src1, n} xor {src2, n}
|
|
mpn_xnor_n(dst, src1, src2, n) - set {dst, n} to {src1, n} xnor {src2, n}
|
|
MPN_NORMALIZE(dst, nlimbs) - normalise the mpn at dst, i.e. set nlimbs to number
|
|
of non-zero limbs
|
|
MPN_NORMALIZE_NOT_ZERO(dst, nlimbs) - normalise the mpn at dst, i.e. set
|
|
nlimbs to number of non-zero limbs, assuming it isn't zero
|
|
MPN_STRIP_LOW_ZEROS_NOT_ZERO(ptr, size, low) - strip least sig zero limbs from
|
|
{ptr, size} by incr ptr and decr size, low should be ptr[0] and will be set
|
|
to new ptr[0] upon return, function assumes {ptr, size} is not zero
|
|
MPN_OVERLAP_P(xp, xsize, yp, ysize) - nonzero if the given mpns overlap
|
|
MPN_SAME_OR_INCR2_P(dst, dsize, src, ssize) - nonzero if ok for incr algorithm
|
|
MPN_SAME_OR_INCR_P(dst, src, size) - as for INCR2 variant, but same sizes
|
|
MPN_SAME_OR_DECR2_P(dst, dsize, src, ssize) - nonzero if ok for decr algorithm
|
|
MPN_SAME_OR_DECR_P(dst, src, size) - as for DECR2 variant, but same sizes
|
|
MPN_LOGOPS_N_INLINE(dst, src1, src2, n, operation) - do n operations involving
|
|
any of src1, src2, dst
|
|
MPN_INCR_U(ptr, size, incr) - {ptr, size} += n expect no carry
|
|
MPN_DECR_U(ptr, size, incr) - {ptr, size} -= n expect no carry
|
|
mpn_incr_u(ptr, incr) - {ptr, size} += n carry possible
|
|
mpn_decr_u(ptr, incr) - {ptr, size} -= n carry possible
|
|
MPN_SIZEINBASE(result, ptr, size, base) - set result to number of numerals
|
|
{ptr, size} has, in the given base. For power of 2 bases it is exact, otherwise
|
|
it may sometimes be one too big - this is done for efficiency so not all limbs
|
|
have to be checked
|
|
MPN_SIZEINBASE_16(result, ptr, size, base) - special optimisation for base 16
|
|
MPN_SET_UI(zp, zn, u) - set {zp, zn} to the given ui, where zn must be big enough
|
|
to accomodate a ulong
|
|
MPN_DIVREM_OR_PREINV_DIVREM_1(qp,xsize,ap,size,d,dinv,shift) - set {qp, xsize} to
|
|
{ap, size} divided by d with dinv an inverse of d and shift the number of bits
|
|
d has to be shifted, only uses the preinv if this will be better on this arch
|
|
MPN_MOD_OR_PREINV_MOD_1(ap,size,d,dinv) - return {ap, size} mod d with d an
|
|
inverse of d - using preinv only if better on this arch
|
|
MPN_DIVREM_OR_DIVEXACT_1(dst, src, size, divisor) - divide {src, size} by divisor assuming no remainder if this will be faster
|
|
MPN_DIVREM_OR_DIVEXACT_1(dst, src, size, divisor) - mpn_modexact_1_odd or
|
|
mpn_mod_1 depending on which is faster on this arch
|
|
MPN_BSWAP(dst, src, size) - byte swap limbs from {src,size} and store
|
|
at {dst,size}
|
|
MPN_BSWAP_REVERSE(dst, src, size) - byte swap limbs from {dst,size} and
|
|
store in reverse order at {src,size}
|
|
|
|
ADDC_LIMB(cout, w, x, y) - w = x + y with cout set to 1 for carry from add
|
|
ADDC_LIMB(cout, w, x, y) - w = x - y with cout set to 1 for borrow from sub
|
|
|
|
BITS_TO_LIMBS(n) - number of limbs required to store the given number of bits
|
|
LIMB_HIGHBIT_TO_MASK(n) - platform independently set a mask to 0 or 0xFF..FF
|
|
depending on whether high bit of n is 0 or 1
|
|
LOW_ZEROS_MASK(n) - bit mask of all the least significant zero bits of n
|
|
ULONG_PARITY(p, n) - sets p to 1 if the number of 1 bits in n is odd
|
|
NEG_MOD(r, a, d) - r = -a mod d (a >= d is allowed) may return r > d (all limbs)
|
|
BSWAP_LIMB(dst, src) - reverse bytes in a limb
|
|
BSWAP_LIMB_FETCH(dst, src) - set dst to the reverse of the bytes in the limb
|
|
pointed to by src
|
|
BSWAP_LIMB_STORE(dst, src) - set limb pointed to by dst to the reverse of the bytes in src
|
|
popc_limb(result, input) - population count of a limb (fast!!)
|
|
POW2_P(n) - return 1 if n is a power of 2 (or 0)
|
|
CNST_LIMB(C) - platform independent way of writing e.g. 1L if C was 1 say
|
|
|
|
MEM_OVERLAP_P(xp, xsize, yp, ysize) - nonzero if given arrays of bytes overlap
|
|
|
|
invert_limb(invxl, xl) - set invxl to the "inverse" of the limb xl for functions
|
|
that take a precomputed "inverse" limb
|
|
technically this isn't an inverse, but it sets invxl to the largest limb
|
|
not larger than (2^(2*BITS_PER_MP_LIMB))/xl - (2^BITS_PER_MP_LIMB) and all
|
|
1's if this would give an overflow
|
|
udiv_qrnnd_preinv1(q, r, nh, nl, d, di) - nh, nl divided by d with di an "inverse"
|
|
of d. The most significant bit of d has to be set
|
|
udiv_qrnnd_preinv2(q, r, nh, nl, d, di) - as for preinv1 but branch free
|
|
udiv_qrnnd_preinv2gen(q, r, nh, nl, d, di, dnorm, lgup) - as for preinv2 but for
|
|
any d. dnorm is d shifted left so its msb is set, lgup is ceil_log2(d)
|
|
|
|
modlimb_invert(inv, n) - true limb invert, i.e. inv*n == 1 mod 2^GMP_NUMB_BITS
|
|
MODLIMB_INVERSE_3 - special case of modlimb_invert for n == 3
|
|
|
|
MPZ_TMP_INIT(X, NLIMBS) - Allocates a temporary mpz_t with space for NLIMBS, space
|
|
will automatically be cleared out upon calling function's return
|
|
MPZ_REALLOC(z, n) - reallocate mpz_t to n limbs if it doesn't have enough
|
|
MPZ_EQUAL_1_P(z) - returns 1 if z is 1, otherwise 0
|
|
MPZ_FAKE_UI(z, zp, u) - creates a fake mpz_t z from an ui. zp must have space for
|
|
an unsigned long
|
|
|
|
ABOVE_THRESHOLD(size, thresh) - decide whether to use algorithm A or B depending whether size >= thresh. thresh == MP_SIZE_T_MAX means only ever use A,
|
|
thresh == 0 means only ever use B
|
|
BELOW_THRESHOLD(size, thresh) - !ABOVE_THRESHOLD
|
|
|
|
Macro constants defined in gmp_impl.h
|
|
===========================================
|
|
|
|
BYTES_PER_MP_LIMB - bytes per limb
|
|
BITS_PER_MP_LIMB - bits per limb
|
|
BITS_PER_ULONG - bits in an unsigned long
|
|
LIMBS_PER_ULONG - number of limbs per unsigned long
|
|
|
|
ULONG_MAX - unsigned long ~0
|
|
UINT_MAX - unsigned in ~0
|
|
USHRT_MAX - unsigned short ~0
|
|
MP_LIMB_T_MAX - mp_limb_t ~0
|
|
|
|
ULONG_HIGHBIT - unsigned long high bit set
|
|
UINT_HIGHBIT - unsigned int high bit set
|
|
USHRT_HIGHBIT - unsigned short high bit set
|
|
GMP_LIMB_HIGHBIT - mp_limb_t high bit set
|
|
|
|
LONG_MIN - smallest negative long
|
|
LONG_MAX - largest positive long
|
|
LONG_HIGHBIT - LONG_MIN
|
|
INT_MIN - smallest negative int
|
|
INT_MAX - largest positive int
|
|
INT_HIGHBIT - INT_MIN
|
|
SHRT_MIN - smallest negative short
|
|
SHRT_MAX - largest positive short
|
|
SHRT_HIGHBIT - SHRT_MIN
|
|
MP_SIZE_T_MIN - smallest negative mp_size_t
|
|
MP_SIZE_T_MAX - largest positive mp_size_t
|
|
MP_EXP_T_MIN - smallest negative mp_exp_t
|
|
MP_EXP_T_MAX - largest positive mp_exp_t
|
|
GMP_NUMB_HIGHBIT - highest bit of a limb (not including nail bits)
|
|
|
|
GMP_NUMB_CEIL_MAX_DIV3 - ceil(GMP_NUMB_MAX/3)
|
|
GMP_NUMB_CEIL_2MAX_DIV3 - ceil(2*GMP_NUMB_MAX/3)
|
|
|
|
PP - product of odd primes that will fit in a limb 3x5x...
|
|
PP_FIRST_OMITTED - first odd prime omitted
|
|
PP_INVERTED - inverse of PP
|
|
|
|
Exception macros
|
|
===========================================
|
|
|
|
GMP_ERROR(code) - raise exception with given code
|
|
DIVIDE_BY_ZERO - raise divide by zero exception
|
|
SQRT_OF_NEGATIVE - raise square root of negative exception
|
|
|
|
Some types defined in gmp_impl.h
|
|
===========================================
|
|
|
|
gmp_uint_least32_t - unsigned integer type with at least 32 bits
|
|
|
|
Macros used in prototypes
|
|
===========================================
|
|
|
|
ATTRIBUTE_CONST - function examines its arguments and returns a value but no
|
|
memory is read or written to and function has no side effects
|
|
|
|
ATTRIBUTE_NORETURN - signifies a function that won't ever return (supresses
|
|
"code unreachable" compile time errors)
|
|
|
|
ATTRIBUTE_MALLOC - function returns a pointer that can't alias anything,
|
|
just as malloc does
|
|
|
|
REGPARM_2_1(a,b,x) - reorder parameters to x,a,b so that x can be put in a reg
|
|
REGPARM_3_1(a,b,c,x) - reorder parameters to x,a,b,c so that x can be put in a reg
|
|
REGPARM_ATTR(n) - make parameter a register parameter
|
|
|
|
Stack based memory manager
|
|
==========================
|
|
Usage: TMP_DECL;
|
|
TMP_MARK;
|
|
ptr = TMP_ALLOC(bytes);
|
|
TMP_FREE;
|
|
|
|
This pushes handling of the stack allocation onto the calling function, which is
|
|
what Pari does. It is faster than malloc and other stack based methods (!) A
|
|
reentrant version is available by doing #define WANT_TMP_REENTRANT 1
|
|
|
|
Variants: TMP_SDECL, TMP_SMARK, TMP_SALLOC, TMP_SFREE - for small allocations
|
|
(uses alloca if available)
|
|
TMP_SDECL, TMP_SMARK, TMP_SALLOC, TMP_SFREE - for large allocations
|
|
|
|
Note: TEMP_ALLOC calls TMP_SALLOC if bytes < 65536, otherwise TMP_BALLOC
|
|
|
|
TMP_B/S/ALLOC_TYPE(n, type) - alloc space for n variables of the given type
|
|
TMP_B/S/ALLOC_LIMBS(n) - alloc space for n limbs
|
|
|
|
TMP_B/S/ALLOC_MP_PTRS(n) - alloc space for n mp_ptr's
|
|
|
|
TMP_ALLOC_LIMBS_2(xp, xsize, yp, ysize) - makes two allocations at once (faster)
|
|
|
|
Memory manager
|
|
==========================
|
|
|
|
alloca(size) - allocate size bytes of space in the stack frame of the calling
|
|
function. Space is automatically freed when the calling function returns
|
|
|
|
__gmp_default_allocate(bytes) - alloc bytes using GMP default memory manager
|
|
__gmp_default_reallocate(ptr,bytes) - realloc bytes using default memory manager
|
|
__gmp_default_free(ptr, size) - free the size bytes allocated at ptr
|
|
|
|
__GMP_ALLOCATE_FUNC_TYPE(n, type) - allocate space for n vars of given type using
|
|
user defined memory management function
|
|
__GMP_ALLOCATE_FUNC_LIMBS(n) - allocate n limbs, user defined mem man
|
|
|
|
__GMP_REALLOCATE_FUNC_TYPE(p, old, new, type) - reallocate from old to new size
|
|
user defined memory management function
|
|
__GMP_REALLOCATE_FUNC_LIMBS(p, old, new) - realloc from old to new limbs,
|
|
user defined mem man
|
|
|
|
__GMP_FREE_FUNC_TYPE(n, type) - free space for n vars of given type using
|
|
user defined memory management function
|
|
__GMP_FREE_FUNC_LIMBS(n) - free n limbs, user defined mem man
|
|
|
|
__GMP_REALLOCATE_FUNC_MAYBE(p, old, new) - reallocate, oldsize can equal newsize,
|
|
user defined memory management function
|
|
|
|
__GMP_REALLOCATE_FUNC_MAYBE_TYPE(p, old, new, type) - reallocate type,
|
|
oldsize can equal newsize, user defined memory management function
|
|
|
|
Assembly macros
|
|
====================================
|
|
|
|
ASM_L(name) - local label for a gcc asm block
|
|
|
|
Debugging
|
|
====================================
|
|
|
|
MPZ_CHECK_FORMAT(z) - tries to check an mpz_t to see if it is broken
|
|
MPZ_PROVOKE_REALLOC(z) - cause z to be realloc'd just because ou feel like it
|
|
|
|
Misc
|
|
====================================
|
|
|
|
- Macros to do with the random generators
|
|
- Lot's of undocumented mpn functions presumably defined in mpn/generic
|
|
- macros for temp space required by kara and toom3 mul and sqr
|
|
- space for fibonnacci functions, fn for n-th fib num from table and biggest n
|
|
such that L_n fits in a long
|
|
- default values for mullow, kara, toom, fft params and thresholds, div divide and
|
|
conquer thresholds
|
|
- piles of different assert macros
|
|
- defines for longlong.h
|
|
- stuff for handling doubles
|
|
- lots of macros for v. fast computation of jacobi symbols
|
|
- stuff for mpf's
|
|
- stuff for formatted printing, reading
|