libase/progress: move __div64_32, do_div to div64.h/c as it was in Barebox.
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 10 Jun 2020 05:47:21 +0000 (07:47 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 10 Jun 2020 05:47:21 +0000 (07:47 +0200)
litex/soc/software/bios/boot.c
litex/soc/software/include/base/div64.h [new file with mode: 0644]
litex/soc/software/libbase/Makefile
litex/soc/software/libbase/div64.c [new file with mode: 0644]
litex/soc/software/libbase/progress.c

index 786039f0e22e1caa72e8ccb43f352b8f4958b524..20953e71190451fd537415fd073f3e01a18349b4 100644 (file)
@@ -23,6 +23,7 @@
 #include "sfl.h"
 #include "boot.h"
 
+#include <progress.h>
 #include <spiflash.h>
 
 #include <libliteeth/udp.h>
diff --git a/litex/soc/software/include/base/div64.h b/litex/soc/software/include/base/div64.h
new file mode 100644 (file)
index 0000000..2f07547
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _ASM_GENERIC_DIV64_H
+#define _ASM_GENERIC_DIV64_H
+/*
+ * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
+ * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
+ *
+ * The semantics of do_div() are:
+ *
+ * uint32_t do_div(uint64_t *n, uint32_t base)
+ * {
+ *     uint32_t remainder = *n % base;
+ *     *n = *n / base;
+ *     return remainder;
+ * }
+ *
+ * NOTE: macro parameter n is evaluated multiple times,
+ *       beware of side effects!
+ */
+
+#include <stdint.h>
+
+extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({                             \
+       uint32_t __base = (base);                       \
+       uint32_t __rem;                                 \
+       (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
+       if (((n) >> 32) == 0) {                 \
+               __rem = (uint32_t)(n) % __base;         \
+               (n) = (uint32_t)(n) / __base;           \
+       } else                                          \
+               __rem = __div64_32(&(n), __base);       \
+       __rem;                                          \
+ })
+
+#endif /* _ASM_GENERIC_DIV64_H */
index 107c8736466ad0861b8dcd8538739e5b586b004f..5974e00073bcf30d89803f928cd360a4688b1e66 100755 (executable)
@@ -3,7 +3,7 @@ include $(SOC_DIRECTORY)/software/common.mak
 
 OBJECTS = exception.o libc.o errno.o crc16.o crc32.o console.o \
        system.o id.o uart.o time.o qsort.o strtod.o spiflash.o strcasecmp.o i2c.o \
-       progress.o
+       div64.o progress.o
 
 all: crt0-ctr.o crt0-xip.o libbase.a libbase-nofloat.a
 
diff --git a/litex/soc/software/libbase/div64.c b/litex/soc/software/libbase/div64.c
new file mode 100644 (file)
index 0000000..98d7748
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * Based on former do_div() implementation from asm-parisc/div64.h:
+ *     Copyright (C) 1999 Hewlett-Packard Co
+ *     Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ *
+ * Generic C version of 64bit/32bit division and modulo, with
+ * 64bit result and 32bit remainder.
+ *
+ * The fast case for (n>>32 == 0) is handled inline by do_div().
+ *
+ * Code generated for this function might be very inefficient
+ * for some CPUs. __div64_32() can be overridden by linking arch-specific
+ * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S.
+ */
+
+#include <stdint.h>
+
+#include <div64.h>
+
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+       uint64_t rem = *n;
+       uint64_t b = base;
+       uint64_t res, d = 1;
+       uint32_t high = rem >> 32;
+
+       /* Reduce the thing a bit first */
+       res = 0;
+       if (high >= base) {
+               high /= base;
+               res = (uint64_t) high << 32;
+               rem -= (uint64_t) (high*base) << 32;
+       }
+
+       while ((int64_t)b > 0 && b < rem) {
+               b = b+b;
+               d = d+d;
+       }
+
+       do {
+               if (rem >= b) {
+                       rem -= b;
+                       res += d;
+               }
+               b >>= 1;
+               d >>= 1;
+       } while (d);
+
+       *n = res;
+       return rem;
+}
index c13b2dad4a1166ca7a1cc0de903c513bba698f9e..d8521fce08353618aaf09c1b00b037284ec370b1 100644 (file)
@@ -20,6 +20,8 @@
 #include <console.h>
 #include <stdio.h>
 #include <stdint.h>
+
+#include <div64.h>
 #include <progress.h>
 
 #define FILESIZE_MAX    100000000
@@ -29,56 +31,6 @@ static int printed;
 static int progress_max;
 static int spin;
 
-uint32_t __div64_32(uint64_t *n, uint32_t base)
-{
-       uint64_t rem = *n;
-       uint64_t b = base;
-       uint64_t res, d = 1;
-       uint32_t high = rem >> 32;
-
-       /* Reduce the thing a bit first */
-       res = 0;
-       if (high >= base) {
-               high /= base;
-               res = (uint64_t) high << 32;
-               rem -= (uint64_t) (high*base) << 32;
-       }
-
-       while ((int64_t)b > 0 && b < rem) {
-               b = b+b;
-               d = d+d;
-       }
-
-       do {
-               if (rem >= b) {
-                       rem -= b;
-                       res += d;
-               }
-               b >>= 1;
-               d >>= 1;
-       } while (d);
-
-       *n = res;
-       return rem;
-}
-
-
-/* The unnecessary pointer compare is there
- * to check for type safety (n must be 64bit)
- */
-# define do_div(n,base) ({                             \
-       uint32_t __base = (base);                       \
-       uint32_t __rem;                                 \
-       (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
-       if (((n) >> 32) == 0) {                 \
-               __rem = (uint32_t)(n) % __base;         \
-               (n) = (uint32_t)(n) / __base;           \
-       } else                                          \
-               __rem = __div64_32(&(n), __base);       \
-       __rem;                                          \
- })
-
-
 void show_progress(int now)
 {
        char spinchr[] = "\\|/-";