1 /* mpz_import -- set mpz from word data.
3 Copyright 2002, 2012 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any
20 or both in parallel, as here.
22 The GNU MP Library is distributed in the hope that it will be useful, but
23 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 You should have received copies of the GNU General Public License and the
28 GNU Lesser General Public License along with the GNU MP Library. If not,
29 see https://www.gnu.org/licenses/. */
37 #if HAVE_LIMB_BIG_ENDIAN
40 #if HAVE_LIMB_LITTLE_ENDIAN
41 #define HOST_ENDIAN (-1)
44 static const mp_limb_t endian_test
= (CNST_LIMB(1) << (GMP_LIMB_BITS
-7)) - 1;
45 #define HOST_ENDIAN (* (signed char *) &endian_test)
50 mpz_import (mpz_ptr z
, size_t count
, int order
,
51 size_t size
, int endian
, size_t nail
, const void *data
)
56 ASSERT (order
== 1 || order
== -1);
57 ASSERT (endian
== 1 || endian
== 0 || endian
== -1);
58 ASSERT (nail
<= 8*size
);
60 zsize
= BITS_TO_LIMBS (count
* (8*size
- nail
));
61 zp
= MPZ_NEWALLOC (z
, zsize
);
66 /* Can't use these special cases with nails currently, since they don't
67 mask out the nail bits in the input data. */
68 if (nail
== 0 && GMP_NAIL_BITS
== 0)
70 unsigned align
= ((char *) data
- (char *) NULL
) % sizeof (mp_limb_t
);
73 && size
== sizeof (mp_limb_t
)
74 && endian
== HOST_ENDIAN
77 MPN_COPY (zp
, (mp_srcptr
) data
, (mp_size_t
) count
);
82 && size
== sizeof (mp_limb_t
)
83 && endian
== - HOST_ENDIAN
86 MPN_BSWAP (zp
, (mp_srcptr
) data
, (mp_size_t
) count
);
91 && size
== sizeof (mp_limb_t
)
92 && endian
== HOST_ENDIAN
95 MPN_REVERSE (zp
, (mp_srcptr
) data
, (mp_size_t
) count
);
101 mp_limb_t limb
, byte
, wbitsmask
;
102 size_t i
, j
, numb
, wbytes
;
107 numb
= size
* 8 - nail
;
109 /* whole bytes to process */
112 /* partial byte to process */
114 wbitsmask
= (CNST_LIMB(1) << wbits
) - 1;
116 /* offset to get to the next word after processing wbytes and wbits */
117 woffset
= (numb
+ 7) / 8;
118 woffset
= (endian
>= 0 ? woffset
: -woffset
)
119 + (order
< 0 ? size
: - (mp_size_t
) size
);
121 /* least significant byte */
122 dp
= (unsigned char *) data
123 + (order
>= 0 ? (count
-1)*size
: 0) + (endian
>= 0 ? size
-1 : 0);
125 #define ACCUMULATE(N) \
127 ASSERT (lbits < GMP_NUMB_BITS); \
128 ASSERT (limb <= (CNST_LIMB(1) << lbits) - 1); \
130 limb |= (mp_limb_t) byte << lbits; \
132 if (lbits >= GMP_NUMB_BITS) \
134 *zp++ = limb & GMP_NUMB_MASK; \
135 lbits -= GMP_NUMB_BITS; \
136 ASSERT (lbits < (N)); \
137 limb = byte >> ((N) - lbits); \
143 for (i
= 0; i
< count
; i
++)
145 for (j
= 0; j
< wbytes
; j
++)
153 byte
= *dp
& wbitsmask
;
162 ASSERT (lbits
<= GMP_NUMB_BITS
);
167 ASSERT (zp
== PTR(z
) + zsize
);
169 /* low byte of word after most significant */
170 ASSERT (dp
== (unsigned char *) data
171 + (order
< 0 ? count
*size
: - (mp_size_t
) size
)
172 + (endian
>= 0 ? (mp_size_t
) size
- 1 : 0));
178 MPN_NORMALIZE (zp
, zsize
);