Annotation of OpenXM_contrib/gmp/mpz/import.c, Revision 1.1.1.1
1.1 ohara 1: /* mpz_import -- set mpz from word data.
2:
3: Copyright 2002 Free Software Foundation, Inc.
4:
5: This file is part of the GNU MP Library.
6:
7: The GNU MP Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The GNU MP Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include <stdio.h> /* for NULL */
23: #include "gmp.h"
24: #include "gmp-impl.h"
25:
26:
27:
28: #if HAVE_LIMB_BIG_ENDIAN
29: #define HOST_ENDIAN 1
30: #endif
31: #if HAVE_LIMB_LITTLE_ENDIAN
32: #define HOST_ENDIAN (-1)
33: #endif
34: #ifndef HOST_ENDIAN
35: static const mp_limb_t endian_test = (CNST_LIMB(1) << (GMP_LIMB_BITS-7)) - 1;
36: #define HOST_ENDIAN (* (signed char *) &endian_test)
37: #endif
38:
39:
40: void
41: mpz_import (mpz_ptr z, size_t count, int order,
42: size_t size, int endian, size_t nail, const void *data)
43: {
44: mp_size_t zsize;
45: mp_ptr zp;
46:
47: ASSERT (order == 1 || order == -1);
48: ASSERT (endian == 1 || endian == 0 || endian == -1);
49: ASSERT (nail <= 8*size);
50:
51: zsize = (count * (8*size - nail) + GMP_NUMB_BITS-1) / GMP_NUMB_BITS;
52: MPZ_REALLOC (z, zsize);
53: zp = PTR(z);
54:
55: if (endian == 0)
56: endian = HOST_ENDIAN;
57:
58: /* Can't use these special cases with nails currently, since they don't
59: mask out the nail bits in the input data. */
60: if (nail == 0 && GMP_NAIL_BITS == 0)
61: {
62: unsigned align = ((char *) data - (char *) NULL) % sizeof (mp_limb_t);
63:
64: if (order == -1
65: && size == sizeof (mp_limb_t)
66: && endian == HOST_ENDIAN
67: && align == 0)
68: {
69: MPN_COPY (zp, (mp_srcptr) data, (mp_size_t) count);
70: goto done;
71: }
72:
73: if (order == -1
74: && size == sizeof (mp_limb_t)
75: && endian == - HOST_ENDIAN
76: && align == 0)
77: {
78: MPN_BSWAP (zp, (mp_srcptr) data, (mp_size_t) count);
79: goto done;
80: }
81:
82: if (order == 1
83: && size == sizeof (mp_limb_t)
84: && endian == HOST_ENDIAN
85: && align == 0)
86: {
87: MPN_REVERSE (zp, (mp_srcptr) data, (mp_size_t) count);
88: goto done;
89: }
90: }
91:
92: {
93: mp_limb_t limb, byte, wbitsmask;
94: size_t i, j, numb, wbytes;
95: mp_size_t woffset;
96: unsigned char *dp;
97: int lbits, wbits;
98:
99: numb = size * 8 - nail;
100:
101: /* whole bytes to process */
102: wbytes = numb / 8;
103:
104: /* partial byte to process */
105: wbits = numb % 8;
106: wbitsmask = (CNST_LIMB(1) << wbits) - 1;
107:
108: /* offset to get to the next word after processing wbytes and wbits */
109: woffset = (numb + 7) / 8;
110: woffset = (endian >= 0 ? woffset : -woffset)
111: + (order < 0 ? size : - (mp_size_t) size);
112:
113: /* least significant byte */
114: dp = (unsigned char *) data
115: + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0);
116:
117: #define ACCUMULATE(N) \
118: do { \
119: ASSERT (lbits < GMP_NUMB_BITS); \
120: ASSERT (limb <= (CNST_LIMB(1) << lbits) - 1); \
121: \
122: limb |= (mp_limb_t) byte << lbits; \
123: lbits += (N); \
124: if (lbits >= GMP_NUMB_BITS) \
125: { \
126: *zp++ = limb & GMP_NUMB_MASK; \
127: lbits -= GMP_NUMB_BITS; \
128: ASSERT (lbits < (N)); \
129: limb = byte >> ((N) - lbits); \
130: } \
131: } while (0)
132:
133: limb = 0;
134: lbits = 0;
135: for (i = 0; i < count; i++)
136: {
137: for (j = 0; j < wbytes; j++)
138: {
139: byte = *dp;
140: dp -= endian;
141: ACCUMULATE (8);
142: }
143: if (wbits != 0)
144: {
145: byte = *dp & wbitsmask;
146: dp -= endian;
147: ACCUMULATE (wbits);
148: }
149: dp += woffset;
150: }
151:
152: if (lbits != 0)
153: {
154: ASSERT (lbits <= GMP_NUMB_BITS);
155: ASSERT_LIMB (limb);
156: *zp++ = limb;
157: }
158:
159: ASSERT (zp == PTR(z) + zsize);
160:
161: /* low byte of word after most significant */
162: ASSERT (dp == (unsigned char *) data
163: + (order < 0 ? count*size : - (mp_size_t) size)
164: + (endian >= 0 ? (mp_size_t) size - 1 : 0));
165:
166: }
167:
168: done:
169: zp = PTR(z);
170: MPN_NORMALIZE (zp, zsize);
171: SIZ(z) = zsize;
172: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>