This patch removes the inclusion of the libgcc math functions and
replaces them by functions coded in C, taken from the coreboot
project. This makes U-Boot building more independent from the toolchain
installed / available on the build system.
The code taken from coreboot is authored from Vadim Bendebury
on 2014-11-28 and committed with commit
ID e63990ef [libpayload: provide basic 64bit division implementation].
I modified the code so that its checkpatch clean without any
functional changes.
Signed-off-by: Stefan Roese
Cc: Simon Glass
Cc: Bin Meng
---
arch/x86/config.mk| 3 --
arch/x86/lib/Makefile | 2 +-
arch/x86/lib/div64.c | 113 ++
arch/x86/lib/gcc.c| 29 -
4 files changed, 114 insertions(+), 33 deletions(-)
create mode 100644 arch/x86/lib/div64.c
delete mode 100644 arch/x86/lib/gcc.c
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 8835dcf36f..472ada5490 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -34,9 +34,6 @@ PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions
PLATFORM_LDFLAGS += -m $(if $(IS_32BIT),elf_i386,elf_x86_64)
-LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
-LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
-
# This is used in the top-level Makefile which does not include
# PLATFORM_LDFLAGS
LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index fe00d7573f..d9b23f5cc4 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_SEABIOS) += coreboot_table.o
obj-y += early_cmos.o
obj-$(CONFIG_EFI) += efi/
obj-y += e820.o
-obj-y += gcc.o
+obj-y += div64.o
obj-y += init_helpers.o
obj-y += interrupts.o
obj-y += lpc-uclass.o
diff --git a/arch/x86/lib/div64.c b/arch/x86/lib/div64.c
new file mode 100644
index 00..4efed74037
--- /dev/null
+++ b/arch/x86/lib/div64.c
@@ -0,0 +1,113 @@
+/*
+ * This file is copied from the coreboot repository as part of
+ * the libpayload project:
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include
+
+union overlay64 {
+ u64 longw;
+ struct {
+ u32 lower;
+ u32 higher;
+ } words;
+};
+
+u64 __ashldi3(u64 num, unsigned int shift)
+{
+ union overlay64 output;
+
+ output.longw = num;
+ if (shift >= 32) {
+ output.words.higher = output.words.lower << (shift - 32);
+ output.words.lower = 0;
+ } else {
+ if (!shift)
+ return num;
+ output.words.higher = (output.words.higher << shift) |
+ (output.words.lower >> (32 - shift));
+ output.words.lower = output.words.lower << shift;
+ }
+ return output.longw;
+}
+
+u64 __lshrdi3(u64 num, unsigned int shift)
+{
+ union overlay64 output;
+
+ output.longw = num;
+ if (shift >= 32) {
+ output.words.lower = output.words.higher >> (shift - 32);
+ output.words.higher = 0;
+ } else {
+ if (!shift)
+ return num;
+ output.words.lower = output.words.lower >> shift |
+ (output.words.higher << (32 - shift));
+ output.words.higher = output.words.higher >> shift;
+ }
+ return output.longw;
+}
+
+#define MAX_32BIT_UINT u64)1) << 32) - 1)
+
+static u64 _64bit_divide(u64 dividend, u64 divider, u64 *rem_p)
+{
+ u64 result = 0;
+
+ /*
+* If divider is zero - let the rest of the system care about the
+* exception.
+*/
+ if (!divider)
+ return 1 / (u32)divider;
+
+ /* As an optimization, let's not use 64 bit division unless we must. */
+ if (dividend <= MAX_32BIT_UINT) {
+ if (divider > MAX_32BIT_UINT) {
+ result = 0;
+ if (rem_p)
+ *rem_p = divider;
+ } else {
+ result = (u32)dividend / (u32)divider;
+ if (rem_p)
+ *rem_p = (u32)dividend % (u32)divider;
+ }
+ return result;
+ }
+
+ while (divider <= dividend) {
+ u64 locald = divider;
+ u64 limit = __lshrdi3(dividend, 1);
+ int shifts = 0;
+
+ while (locald <= limit) {
+ shifts++;
+ locald = locald + locald;
+ }
+ result |= __ashldi3(1, shifts);
+ dividend -= locald;
+ }
+
+ if (rem_p)
+ *rem_p = dividend;
+
+ return result;
+}
+
+u64 __udivdi3(u64 num, u64 den)
+{
+ return _64bit_divide(num, den, NULL);
+}
+
+u64 __umoddi3(u64 num, u