1 /* mpz_out_raw -- write an mpz_t in raw format.
3 Copyright 2001, 2002 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 the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
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.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
26 /* HTON_LIMB_STORE takes a normal host byte order limb and stores it as
27 network byte order (ie. big endian). */
29 #if HAVE_LIMB_BIG_ENDIAN
30 #define HTON_LIMB_STORE(dst, limb) do { *(dst) = (limb); } while (0)
33 #if HAVE_LIMB_LITTLE_ENDIAN
34 #define HTON_LIMB_STORE(dst, limb) BSWAP_LIMB_STORE (dst, limb)
37 #ifndef HTON_LIMB_STORE
38 #define HTON_LIMB_STORE(dst, limb) \
40 mp_limb_t __limb = (limb); \
41 char *__p = (char *) (dst); \
43 for (__i = 0; __i < BYTES_PER_MP_LIMB; __i++) \
44 __p[__i] = (char) (__limb >> ((BYTES_PER_MP_LIMB-1 - __i) * 8)); \
50 mpz_out_raw (FILE *fp
, mpz_srcptr x
)
52 mp_size_t xsize
, abs_xsize
, bytes
, i
;
60 abs_xsize
= ABS (xsize
);
61 bytes
= (abs_xsize
* GMP_NUMB_BITS
+ 7) / 8;
62 tsize
= ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB
) + bytes
;
64 tp
= __GMP_ALLOCATE_FUNC_TYPE (tsize
, char);
65 bp
= tp
+ ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB
);
73 if (GMP_NAIL_BITS
== 0)
75 /* reverse limb order, and byte swap if necessary */
77 _Pragma ("_CRI ivdep");
81 bp
-= BYTES_PER_MP_LIMB
;
83 HTON_LIMB_STORE ((mp_ptr
) bp
, xlimb
);
88 /* strip high zero bytes (without fetching from bp) */
89 count_leading_zeros (zeros
, xlimb
);
98 ASSERT_CODE (char *bp_orig
= bp
- bytes
);
100 ASSERT_ALWAYS (GMP_NUMB_BITS
>= 8);
108 ASSERT (bp
> bp_orig
);
109 *--bp
= xlimb
& 0xFF;
119 ASSERT (bp
> bp_orig
);
120 *--bp
= (xlimb
| (new_xlimb
<< bits
)) & 0xFF;
121 xlimb
= new_xlimb
>> (8 - bits
);
122 bits
+= GMP_NUMB_BITS
- 8;
127 ASSERT (bp
> bp_orig
);
131 ASSERT (bp
== bp_orig
);
140 /* total bytes to be written */
143 /* twos complement negative for the size value */
144 bytes
= (xsize
>= 0 ? bytes
: -bytes
);
146 /* so we don't rely on sign extension in ">>" */
147 ASSERT_ALWAYS (sizeof (bytes
) >= 4);
149 bp
[-4] = bytes
>> 24;
150 bp
[-3] = bytes
>> 16;
157 if (fwrite (bp
, ssize
, 1, fp
) != 1)
160 (*__gmp_free_func
) (tp
, tsize
);