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

Reply via email to