diff options
Diffstat (limited to 'libraries/libtfm')
-rw-r--r-- | libraries/libtfm/Makefile | 71 | ||||
-rw-r--r-- | libraries/libtfm/fp_to_unsigned_bin.c | 62 | ||||
-rw-r--r-- | libraries/libtfm/tomsfastmath/Makefile | 4 |
3 files changed, 137 insertions, 0 deletions
diff --git a/libraries/libtfm/Makefile b/libraries/libtfm/Makefile new file mode 100644 index 0000000..aa5031f --- /dev/null +++ b/libraries/libtfm/Makefile @@ -0,0 +1,71 @@ + +# This duplicates more of sw/thirdparty/libtfm/Makefile than I +# would like, but it does the job. Prettier makefiles can wait for another day. + +# vpath %.c ${LIBTFM_SRC} +# vpath %.h ${LIBTFM_SRC} + +BITS := 4096 + +HDR := ${LIBTFM_SRC}/tomsfastmath/src/headers/tfm.h +LIB := tomsfastmath/libtfm.a + +# See sw/thirdparty/libtfm/Makefile for compilation options. Note +# that libtfm platform-specific assembly code has opinions on the +# optimization level (and appears to be best tested with -O3). + +# Using $(subst...) here is a kludge. A cleaner approach might be for +# sw/stm32/Makefile to build up the non-variant parts of CFLAGS in a +# different variable before merging the variant and non-variant parts +# into CFLAGS, which would give us a clean copy of the non-variant +# parts to use when constructing our own CFLAGS. Later. + +# The ARM assembly code in libtfm still generates a lot of warnings of the form: +# +# warning: matching constraint does not allow a register [enabled by default] +# +# This is just a warning, the resulting library appears to work +# correctly, and the fix appears to require a nasty intervention in +# the guts of the libtfm assembly code, so we live with the warning +# for now, at least until we confirm that it hasn't already been fixed +# in a newer version of libtfm. + +ifdef DO_PROFILING +# arm-none-eabi-gcc: error: -pg and -fomit-frame-pointer are incompatible +STM32_LIBTFM_CFLAGS_OPTIMIZATION := -O3 -funroll-loops +else +STM32_LIBTFM_CFLAGS_OPTIMIZATION := -O3 -funroll-loops -fomit-frame-pointer +endif + +CFLAGS := $(subst ${STM32_CFLAGS_OPTIMIZATION},${STM32_LIBTFM_CFLAGS_OPTIMIZATION},${CFLAGS}) +CFLAGS += -DTFM_ARM -DENDIAN_LITTLE -Dasm=__asm__ -Wa,-mimplicit-it=thumb +CFLAGS += -I${LIBTFM_SRC}/tomsfastmath/src/headers +CFLAGS += -DFP_MAX_SIZE="(${BITS}*2+(8*DIGIT_BIT))" +CFLAGS += -Wall -W -Wshadow -Wno-uninitialized + +TARGETS := $(notdir ${HDR} ${LIB}) + +REPLACE = fp_to_unsigned_bin.o + +all: ${TARGETS} + +clean: + rm -rf ${TARGETS} $(notdir ${HDR}.tmp) ${LIB} tomsfastmath/src ${REPLACE} + +distclean: clean + rm -f TAGS + +$(notdir ${HDR}): ${HDR} + echo >$@.tmp '/* Configure size of largest bignum we want to handle -- see notes in tfm.pdf */' + echo >>$@.tmp '#define FP_MAX_SIZE (${BITS}*2+(8*DIGIT_BIT))' + echo >>$@.tmp '' + cat >>$@.tmp $^ + mv -f $@.tmp $@ + +$(notdir ${LIB}): ${LIB} + ln -f $^ $@ + +${LIB}: ${HDR} ${REPLACE} + (cd ${LIBTFM_SRC} && find tomsfastmath/src -type d) | xargs mkdir -p + cd tomsfastmath; ${MAKE} CFLAGS='${CFLAGS}' + ar r ${LIB} ${REPLACE} 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$ */ diff --git a/libraries/libtfm/tomsfastmath/Makefile b/libraries/libtfm/tomsfastmath/Makefile new file mode 100644 index 0000000..695aa92 --- /dev/null +++ b/libraries/libtfm/tomsfastmath/Makefile @@ -0,0 +1,4 @@ +vpath %.c ${LIBTFM_SRC}/tomsfastmath +vpath %.h ${LIBTFM_SRC}/tomsfastmath + +include ${LIBTFM_SRC}/tomsfastmath/makefile |