aboutsummaryrefslogtreecommitdiff
path: root/libraries/libtfm/fp_to_unsigned_bin.c
blob: 618167d636c4e092ccc0ede3618840a9378c7bfe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* TomsFastMath, a fast ISO C bignum library.
 * 
 * This project is meant to fill in where LibTomMath
 * falls short.  That is speed ;-)
 *
 * This project is public domain and free for all purposes.
 * 
 * Tom St Denis, tomstdenis@gmail.com
 */
#include <tfm_private.h>

void fp_to_unsigned_bin(fp_int *a, unsigned char *b)
{
  /* If we know the endianness of this architecture, and we're using
     32-bit fp_digits, we can optimize this */
#if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(FP_64BIT)
  /* But not for both simultaneously */
#if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG)
#error Both ENDIAN_LITTLE and ENDIAN_BIG defined.
#endif
  {
    int c = fp_unsigned_bin_size(a);
    unsigned char *pd = (unsigned char *)a->dp;

    /* read the bytes out */
#ifdef ENDIAN_BIG
    {
      /* Use Duff's device to unroll the loop. */
      int idx = (c - 1) & ~3;
      switch (c % 4) {
      case 0:	do { b[idx+0] = *pd++;
      case 3:	     b[idx+1] = *pd++;
      case 2:	     b[idx+2] = *pd++;
      case 1:	     b[idx+3] = *pd++;
                     idx -= 4;
                } while ((c -= 4) > 0);
      }
    }
#else
    for (c -= 1; c >= 0; c -= 1) {
      b[c] = *pd++;
    }
#endif
  }
#else
  int     x;
  fp_int  t;

  fp_init_copy(&t, a);

  x = 0;
  while (fp_iszero (&t) == FP_NO) {
      b[x++] = (unsigned char) (t.dp[0] & 255);
      fp_div_2d (&t, 8, &t, NULL);
  }
  fp_reverse (b, x);
#endif
}

/* $Source$ */
/* $Revision$ */
/* $Date$ */