Annotation of OpenXM_contrib/gmp/mpz/out_raw.c, Revision 1.1.1.3
1.1.1.3 ! ohara 1: /* mpz_out_raw -- write an mpz_t in raw format.
1.1 maekawa 2:
1.1.1.3 ! ohara 3: Copyright 2001, 2002 Free Software Foundation, Inc.
1.1 maekawa 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
1.1.1.2 maekawa 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
1.1 maekawa 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
1.1.1.2 maekawa 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 15: License for more details.
16:
1.1.1.2 maekawa 17: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 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>
23: #include "gmp.h"
24: #include "gmp-impl.h"
1.1.1.3 ! ohara 25: #include "longlong.h"
1.1 maekawa 26:
1.1.1.3 ! ohara 27:
! 28: /* HTON_LIMB_STORE takes a normal host byte order limb and stores it as
! 29: network byte order (ie. big endian). */
! 30:
! 31: #if HAVE_LIMB_BIG_ENDIAN
! 32: #define HTON_LIMB_STORE(dst, limb) do { *(dst) = (limb); } while (0)
! 33: #endif
! 34:
! 35: /* The generic implementations below very likely come out as lots of
! 36: separate byte stores, so if we know the host is little endian then
! 37: instead use a purely arithmetic BSWAP_LIMB and a single store. */
! 38: #if HAVE_LIMB_LITTLE_ENDIAN
! 39: #define HTON_LIMB_STORE(dst, limb) BSWAP_LIMB_STORE (dst, limb)
! 40: #endif
! 41:
! 42: #if ! defined (HTON_LIMB_STORE)
! 43: #if BITS_PER_MP_LIMB == 8
! 44: #define HTON_LIMB_STORE(dst, limb) do { *(dst) = (limb); } while (0)
! 45: #endif
! 46: #if BITS_PER_MP_LIMB == 16
! 47: #define HTON_LIMB_STORE(dst, limb) \
! 48: do { \
! 49: mp_limb_t __limb = (limb); \
! 50: char *__p = (char *) (dst); \
! 51: __p[1] = (__limb); \
! 52: __p[0] = (__limb) >> 8; \
! 53: } while (0)
! 54: #endif
! 55: #if BITS_PER_MP_LIMB == 32
! 56: #define HTON_LIMB_STORE(dst, limb) \
! 57: do { \
! 58: mp_limb_t __limb = (limb); \
! 59: char *__p = (char *) (dst); \
! 60: __p[3] = (__limb); \
! 61: __p[2] = (__limb) >> 8; \
! 62: __p[1] = (__limb) >> 16; \
! 63: __p[0] = (__limb) >> 24; \
! 64: } while (0)
! 65: #endif
! 66: #if BITS_PER_MP_LIMB == 64
! 67: #define HTON_LIMB_STORE(dst, limb) \
! 68: do { \
! 69: mp_limb_t __limb = (limb); \
! 70: char *__p = (char *) (dst); \
! 71: __p[7] = (__limb); \
! 72: __p[6] = (__limb) >> 8; \
! 73: __p[5] = (__limb) >> 16; \
! 74: __p[4] = (__limb) >> 24; \
! 75: __p[3] = (__limb) >> 32; \
! 76: __p[2] = (__limb) >> 40; \
! 77: __p[1] = (__limb) >> 48; \
! 78: __p[0] = (__limb) >> 56; \
! 79: } while (0)
1.1 maekawa 80: #endif
1.1.1.3 ! ohara 81: #endif
! 82:
! 83:
! 84: size_t
! 85: mpz_out_raw (FILE *fp, mpz_srcptr x)
1.1 maekawa 86: {
1.1.1.3 ! ohara 87: mp_size_t xsize, abs_xsize, bytes, i;
! 88: mp_srcptr xp;
! 89: char *tp, *bp;
! 90: mp_limb_t xlimb;
! 91: int zeros;
! 92: size_t tsize, ssize;
! 93:
! 94: xsize = SIZ(x);
! 95: abs_xsize = ABS (xsize);
! 96: bytes = (abs_xsize * GMP_NUMB_BITS + 7) / 8;
! 97: tsize = ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB) + bytes;
1.1 maekawa 98:
1.1.1.3 ! ohara 99: tp = __GMP_ALLOCATE_FUNC_TYPE (tsize, char);
! 100: bp = tp + ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB);
1.1 maekawa 101:
1.1.1.3 ! ohara 102: if (bytes != 0)
1.1 maekawa 103: {
1.1.1.3 ! ohara 104: bp += bytes;
! 105: xp = PTR (x);
! 106: i = abs_xsize;
! 107:
! 108: if (GMP_NAIL_BITS == 0)
! 109: {
! 110: /* reverse limb order, and byte swap if necessary */
! 111: #ifdef _CRAY
! 112: _Pragma ("_CRI ivdep");
! 113: #endif
! 114: do
! 115: {
! 116: bp -= BYTES_PER_MP_LIMB;
! 117: xlimb = *xp;
! 118: HTON_LIMB_STORE ((mp_ptr) bp, xlimb);
! 119: xp++;
! 120: }
! 121: while (--i > 0);
! 122:
! 123: /* strip high zero bytes (without fetching from bp) */
! 124: count_leading_zeros (zeros, xlimb);
! 125: zeros /= 8;
! 126: bp += zeros;
! 127: bytes -= zeros;
! 128: }
! 129: else
! 130: {
! 131: mp_limb_t new_xlimb;
! 132: int bits;
! 133: ASSERT_CODE (char *bp_orig = bp - bytes);
! 134:
! 135: ASSERT_ALWAYS (GMP_NUMB_BITS >= 8);
! 136:
! 137: bits = 0;
! 138: xlimb = 0;
! 139: for (;;)
! 140: {
! 141: while (bits >= 8)
! 142: {
! 143: ASSERT (bp > bp_orig);
! 144: *--bp = xlimb & 0xFF;
! 145: xlimb >>= 8;
! 146: bits -= 8;
! 147: }
! 148:
! 149: if (i == 0)
! 150: break;
! 151:
! 152: new_xlimb = *xp++;
! 153: i--;
! 154: ASSERT (bp > bp_orig);
! 155: *--bp = (xlimb | (new_xlimb << bits)) & 0xFF;
! 156: xlimb = new_xlimb >> (8 - bits);
! 157: bits += GMP_NUMB_BITS - 8;
! 158: }
! 159:
! 160: if (bits != 0)
! 161: {
! 162: ASSERT (bp > bp_orig);
! 163: *--bp = xlimb;
! 164: }
! 165:
! 166: ASSERT (bp == bp_orig);
! 167: while (*bp == 0)
! 168: {
! 169: bp++;
! 170: bytes--;
! 171: }
! 172: }
1.1 maekawa 173: }
174:
1.1.1.3 ! ohara 175: /* total bytes to be written */
! 176: ssize = 4 + bytes;
1.1 maekawa 177:
1.1.1.3 ! ohara 178: /* twos complement negative for the size value */
! 179: bytes = (xsize >= 0 ? bytes : -bytes);
1.1 maekawa 180:
1.1.1.3 ! ohara 181: /* so we don't rely on sign extension in ">>" */
! 182: ASSERT_ALWAYS (sizeof (bytes) >= 4);
! 183:
! 184: bp[-4] = bytes >> 24;
! 185: bp[-3] = bytes >> 16;
! 186: bp[-2] = bytes >> 8;
! 187: bp[-1] = bytes;
! 188: bp -= 4;
! 189:
! 190: if (fp == 0)
! 191: fp = stdout;
! 192: if (fwrite (bp, ssize, 1, fp) != 1)
! 193: ssize = 0;
! 194:
! 195: (*__gmp_free_func) (tp, tsize);
! 196: return ssize;
1.1 maekawa 197: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>