diff options
Diffstat (limited to 'libraries/libtfm/fp_to_unsigned_bin.c')
-rw-r--r-- | libraries/libtfm/fp_to_unsigned_bin.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/libraries/libtfm/fp_to_unsigned_bin.c b/libraries/libtfm/fp_to_unsigned_bin.c new file mode 100644 index 0000000..618167d --- /dev/null +++ b/libraries/libtfm/fp_to_unsigned_bin.c @@ -0,0 +1,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$ */ |