aboutsummaryrefslogtreecommitdiff
path: root/libraries/libtfm
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/libtfm')
-rw-r--r--libraries/libtfm/Makefile71
-rw-r--r--libraries/libtfm/fp_to_unsigned_bin.c62
-rw-r--r--libraries/libtfm/tomsfastmath/Makefile4
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