summaryrefslogtreecommitdiff
path: root/mpz/out_raw.c
diff options
context:
space:
mode:
authorKevin Ryde <user42@zip.com.au>2002-04-23 00:13:40 +0200
committerKevin Ryde <user42@zip.com.au>2002-04-23 00:13:40 +0200
commitb030bf732321853579ec18a8fa51753237531e8e (patch)
treee39057a686ba71491da6916cab10e71c7b4d43a4 /mpz/out_raw.c
parentbadc09ffe7512164ebb0690583ccff5cf5791708 (diff)
downloadgmp-b030bf732321853579ec18a8fa51753237531e8e.tar.gz
* mpz/inp_raw.c, mpz/out_raw.c: Nailify.
Diffstat (limited to 'mpz/out_raw.c')
-rw-r--r--mpz/out_raw.c78
1 files changed, 63 insertions, 15 deletions
diff --git a/mpz/out_raw.c b/mpz/out_raw.c
index b3895e57b..0dafaa2fb 100644
--- a/mpz/out_raw.c
+++ b/mpz/out_raw.c
@@ -93,7 +93,7 @@ mpz_out_raw (FILE *fp, mpz_srcptr x)
xsize = SIZ(x);
abs_xsize = ABS (xsize);
- bytes = BYTES_PER_MP_LIMB * abs_xsize;
+ bytes = (abs_xsize * GMP_NUMB_BITS + 7) / 8;
tsize = ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB) + bytes;
tp = __GMP_ALLOCATE_FUNC_TYPE (tsize, char);
@@ -101,27 +101,75 @@ mpz_out_raw (FILE *fp, mpz_srcptr x)
if (bytes != 0)
{
- /* reverse limb order, and byte swap if necessary */
bp += bytes;
xp = PTR (x);
i = abs_xsize;
+
+ if (GMP_NAIL_BITS == 0)
+ {
+ /* reverse limb order, and byte swap if necessary */
#ifdef _CRAY
- _Pragma ("_CRI ivdep");
+ _Pragma ("_CRI ivdep");
#endif
- do
+ do
+ {
+ bp -= BYTES_PER_MP_LIMB;
+ xlimb = *xp;
+ HTON_LIMB_STORE ((mp_ptr) bp, xlimb);
+ xp++;
+ }
+ while (--i > 0);
+
+ /* strip high zero bytes (without fetching from bp) */
+ count_leading_zeros (zeros, xlimb);
+ zeros /= 8;
+ bp += zeros;
+ bytes -= zeros;
+ }
+ else
{
- bp -= BYTES_PER_MP_LIMB;
- xlimb = *xp;
- HTON_LIMB_STORE ((mp_ptr) bp, xlimb);
- xp++;
+ mp_limb_t new_xlimb;
+ int bits;
+ ASSERT_CODE (char *bp_orig = bp - bytes);
+
+ ASSERT_ALWAYS (GMP_NUMB_BITS >= 8);
+
+ bits = 0;
+ xlimb = 0;
+ for (;;)
+ {
+ while (bits >= 8)
+ {
+ ASSERT (bp > bp_orig);
+ *--bp = xlimb & 0xFF;
+ xlimb >>= 8;
+ bits -= 8;
+ }
+
+ if (i == 0)
+ break;
+
+ new_xlimb = *xp++;
+ i--;
+ ASSERT (bp > bp_orig);
+ *--bp = (xlimb | (new_xlimb << bits)) & 0xFF;
+ xlimb = new_xlimb >> (8 - bits);
+ bits += GMP_NUMB_BITS - 8;
+ }
+
+ if (bits != 0)
+ {
+ ASSERT (bp > bp_orig);
+ *--bp = xlimb;
+ }
+
+ ASSERT (bp == bp_orig);
+ while (*bp == 0)
+ {
+ bp++;
+ bytes--;
+ }
}
- while (--i > 0);
-
- /* strip high zero bytes (without fetching from bp) */
- count_leading_zeros (zeros, xlimb);
- zeros /= 8;
- bp += zeros;
- bytes -= zeros;
}
/* total bytes to be written */