Op Wed, 29 Nov 2017 16:23:31 +0100, schreef Stefan Roese: > 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.
Thanks Stefan, Great work, I'll try to test that soon. BTW I eventually have been able to work around the problem in Yocto. The work around involved creating a seperate .conf file for u-boot which includes multilib support. I couldn't add multilib support to my rootfs .conf file because that broke building the sdk. Of course the effect is to build a complete seperate target infrastructure (x86_64 + ml) just to build one binary. This patch will save people a lot of grief I'm sure. > The code taken from coreboot is authored from Vadim Bendebury > <vben...@chromium.org> on 2014-11-28 and committed with commit ID > e63990ef [libpayload: provide basic 64bit division implementation] > (coreboot git repository located here [1]). > > I modified the code so that its checkpatch clean without any functional > changes. > > [1] git://github.com/coreboot/coreboot.git > > Signed-off-by: Stefan Roese <s...@denx.de> > Cc: Simon Glass <s...@chromium.org> > Cc: Bin Meng <bmeng...@gmail.com> > --- > v3: > - Completely get rid of all libgcc references in arch/x86/lib/Makefile, > also for the standalone applications > > v2: > - Added coreboot git repository link to commit message > > arch/x86/config.mk | 3 -- > arch/x86/lib/Makefile | 8 +--- > arch/x86/lib/div64.c | 113 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > arch/x86/lib/gcc.c | 29 ------------- > 4 files changed, 114 insertions(+), 39 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..7d729ea0f7 100644 --- a/arch/x86/lib/Makefile +++ > b/arch/x86/lib/Makefile @@ -18,7 +18,6 @@ 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 += init_helpers.o obj-y += interrupts.o obj-y += lpc- uclass.o > @@ -49,12 +48,7 @@ endif > obj-$(CONFIG_HAVE_FSP) += fsp/ > obj-$(CONFIG_SPL_BUILD) += spl.o > > -extra-$(CONFIG_USE_PRIVATE_LIBGCC) += lib.a - > -NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) > -print-libgcc-file-name) -OBJCOPYFLAGS := --prefix-symbols=__normal_ > -$(obj)/lib.a: $(NORMAL_LIBGCC) FORCE - $(call if_changed,objcopy) > +lib-$(CONFIG_USE_PRIVATE_LIBGCC) += div64.o > > ifeq ($(CONFIG_$(SPL_)X86_64),) > obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o > diff --git a/arch/x86/lib/div64.c b/arch/x86/lib/div64.c new file mode > 100644 index 0000000000..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 <common.h> > + > +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, u64 den) > +{ > + u64 v = 0; > + > + _64bit_divide(num, den, &v); > + return v; > +} > diff --git a/arch/x86/lib/gcc.c b/arch/x86/lib/gcc.c deleted file mode > 100644 index 3c70d790d4..0000000000 --- a/arch/x86/lib/gcc.c +++ > /dev/null @@ -1,29 +0,0 @@ > -/* > - * This file is part of the coreboot project. > - * > - * Copyright (C) 2009 coresystems GmbH - * > - * SPDX-License-Identifier: GPL-2.0 - */ > - > -#ifdef __GNUC__ > - > -/* > - * GCC's libgcc handling is quite broken. While the libgcc functions - > * are always regparm(0) the code that calls them uses whatever the - * > compiler call specifies. Therefore we need a wrapper around those - * > functions. See gcc bug PR41055 for more information. > - */ > -#define WRAP_LIBGCC_CALL(type, name) \ > - type __normal_##name(type a, type b) __attribute__((regparm(0))); \ > - type __wrap_##name(type a, type b); \ > - type __attribute__((no_instrument_function)) \ > - __wrap_##name(type a, type b) \ > - { return __normal_##name(a, b); } > - > -WRAP_LIBGCC_CALL(long long, __divdi3) > -WRAP_LIBGCC_CALL(unsigned long long, __udivdi3) > -WRAP_LIBGCC_CALL(long long, __moddi3) > -WRAP_LIBGCC_CALL(unsigned long long, __umoddi3) > - > -#endif _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot