x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
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 <[email protected]> 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
---
v2:
- Added coreboot git repository link to commit message
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
arch/x86/config.mk +0 -3
@@ -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
arch/x86/lib/Makefile +1 -1
@@ -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
arch/x86/lib/div64.c new file +113 -0
113 lines not on this page · raw message
arch/x86/lib/gcc.c deleted +0 -29
@@ -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
Signature · 1 line
2.15.0
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Stefan,
Quoted 202 lines · 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.
The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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.carch/x86/config.mk +0
-3@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +113
-0@@ -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; +}arch/x86/lib/gcc.c deleted +0
-20@@ -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)) \
arch/x86/lib/gcc.c
Quoted 10 lines
arch/x86/lib/gcc.c deleted +0
-10- __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 --
I don't see __divdi3 and __moddi3 in the new implementation. Are they not needed?
Regards,
Bin
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Bin,
Quoted 208 lines · Bin Meng
Quoted 207 lines · 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.
The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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 100644arch/x86/lib/gcc.carch/x86/config.mk +0
-3@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +113
-0@@ -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; +}arch/x86/lib/gcc.c deleted +0
-25@@ -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)
Quoted 8 lines
arch/x86/lib/gcc.c
Quoted 5 lines
arch/x86/lib/gcc.c deleted +0
-5-WRAP_LIBGCC_CALL(long long, __moddi3) -WRAP_LIBGCC_CALL(unsigned long long, __umoddi3) - -#endif --I don't see
__divdi3and__moddi3in the new implementation. Are they not needed?
Yes, at least I couldn't find any problems compiling U-Boot for x86 with this patch.
BTW: The code size also did shrink a bit with this patch.
Thanks,
Stefan
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Stefan,
Quoted 230 lines · Stefan Roese
Hi Bin,
Quoted 216 lines · Bin Meng
Quoted 214 lines · 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.
The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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 100644arch/x86/lib/gcc.carch/x86/config.mk +0
-5@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +69
-0@@ -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. */
arch/x86/lib/div64.c new file +44
-0+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; +}arch/x86/lib/gcc.c deleted +0
-18@@ -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)));\
arch/x86/lib/gcc.c deleted +0
-8- 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)Quoted 8 lines
arch/x86/lib/gcc.c
Quoted 4 lines
arch/x86/lib/gcc.c deleted +0
-4-WRAP_LIBGCC_CALL(unsigned long long, __umoddi3) - -#endif --I don't see
__divdi3and__moddi3in the new implementation. Are they not needed?
Quoted 4 lines
Yes, at least I couldn't find any problems compiling U-Boot for x86 with this patch.
BTW: The code size also did shrink a bit with this patch.
But this is needed in fact. If you write some codes doing signed 64-bit integer division, you will get link errors.
undefined reference to `__divdi3'
Regards,
Bin
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Bin,
Quoted 234 lines · Bin Meng
Quoted 233 lines · Stefan Roese
Hi Bin,
Quoted 216 lines · Bin Meng
Quoted 214 lines · 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.
The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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 100644arch/x86/lib/gcc.carch/x86/config.mk +0
-5@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +69
-0@@ -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. */
arch/x86/lib/div64.c new file +44
-0+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; +}arch/x86/lib/gcc.c deleted +0
-18@@ -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)));\
arch/x86/lib/gcc.c deleted +0
-8- 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)Quoted 8 lines
arch/x86/lib/gcc.c
Quoted 4 lines
arch/x86/lib/gcc.c deleted +0
-4-WRAP_LIBGCC_CALL(unsigned long long, __umoddi3) - -#endif --I don't see
__divdi3and__moddi3in the new implementation. Are they not needed?Yes, at least I couldn't find any problems compiling U-Boot for x86 with this patch.
Quoted 6 lines
Quoted 1 line
BTW: The code size also did shrink a bit with this patch.
But this is needed in fact. If you write some codes doing signed 64-bit integer division, you will get link errors.
undefined reference to `__divdi3'
You wrote some additional code to test this, that is currently not in mainline, right? Writing code with divisions should be done very carefully from my point of view. And as far as I know, using do_div() and the functions from lib/div64 is preferred here.
I would prefer to add this patch and once compile breakage occur because of such "undefined reference" error from above, we should investigate the root cause of fix it by replacing division operation by one of the provided helper functions.
Thanks,
Stefan
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Stefan,
Quoted 254 lines · Stefan Roese
Hi Bin,
Quoted 250 lines · Bin Meng
Quoted 239 lines · Stefan Roese
Hi Bin,
Quoted 223 lines · Bin Meng
Quoted 220 lines · 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.
The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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 100644arch/x86/lib/gcc.carch/x86/config.mk +0
-5@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +26
-0@@ -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);
arch/x86/lib/div64.c new file +18
-0+ 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);
arch/x86/lib/div64.c new file +19
-0+ 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
arch/x86/lib/div64.c new file +6
-0+* exception. +*/ +if (!divider) +return 1 / (u32 )divider; + +/* As an optimization, let's not use 64 bit division unless we must. */
arch/x86/lib/div64.c new file +44
-0+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; +}arch/x86/lib/gcc.c deleted +0
-18@@ -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)));
\arch/x86/lib/gcc.c deleted +0
-9- 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)Quoted 8 lines
arch/x86/lib/gcc.c
Quoted 3 lines
arch/x86/lib/gcc.c deleted +0
-3- -#endif --I don't see
__divdi3and__moddi3in the new implementation. Are they not needed?Quoted 4 lines
Yes, at least I couldn't find any problems compiling U-Boot for x86 with this patch.
BTW: The code size also did shrink a bit with this patch.
But this is needed in fact. If you write some codes doing signed 64-bit integer division, you will get link errors.
Quoted 8 lines
Quoted 1 line
undefined reference to `__divdi3'
You wrote some additional code to test this, that is currently not in mainline, right? Writing code with divisions should be done very carefully from my point of view. And as far as I know, using
do_div()and the functions from lib/div64 is preferred here.
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;
The compiler will generate codes to call __divdi3. This works before your patch.
Quoted 5 lines
I would prefer to add this patch and once compile breakage occur because of such "undefined reference" error from above, we should investigate the root cause of fix it by replacing division operation by one of the provided helper functions.
Regards,
Bin
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Bin,
Quoted 264 lines · Bin Meng
Quoted 254 lines · Stefan Roese
Hi Bin,
Quoted 250 lines · Bin Meng
Quoted 239 lines · Stefan Roese
Hi Bin,
Quoted 223 lines · Bin Meng
Quoted 220 lines · 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.
The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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.carch/x86/config.mk +0
-5@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +26
-0@@ -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);
arch/x86/lib/div64.c new file +18
-0+ 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);
arch/x86/lib/div64.c new file +19
-0+ 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
arch/x86/lib/div64.c new file +6
-0+* exception. +*/ +if (!divider) +return 1 / (u32 )divider; + +/* As an optimization, let's not use 64 bit division unless we must. */
arch/x86/lib/div64.c new file +44
-0+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; +}arch/x86/lib/gcc.c deleted +0
-18@@ -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)));
\arch/x86/lib/gcc.c deleted +0
-9- 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)Quoted 8 lines
arch/x86/lib/gcc.c
Quoted 3 lines
arch/x86/lib/gcc.c deleted +0
-3- -#endif --I don't see
__divdi3and__moddi3in the new implementation. Are they not needed?Quoted 4 lines
Yes, at least I couldn't find any problems compiling U-Boot for x86 with this patch.
BTW: The code size also did shrink a bit with this patch.
But this is needed in fact. If you write some codes doing signed 64-bit integer division, you will get link errors.
Quoted 8 lines
Quoted 1 line
undefined reference to `__divdi3'
You wrote some additional code to test this, that is currently not in mainline, right? Writing code with divisions should be done very carefully from my point of view. And as far as I know, using
do_div()and the functions from lib/div64 is preferred here.
Quoted 6 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your patch.
Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks,
Stefan
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Stefan,
Quoted 304 lines · Stefan Roese
Hi Bin,
Quoted 279 lines · Bin Meng
Quoted 267 lines · Stefan Roese
Hi Bin,
Quoted 262 lines · Bin Meng
Quoted 248 lines · Stefan Roese
Hi Bin,
Quoted 230 lines · Bin Meng
Quoted 226 lines · 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.The code taken from coreboot is authored from Vadim Bendebury <[email protected]> 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.gitSigned-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Bin Meng <[email protected]>---
v2:
- Added coreboot git repository link to commit messagearch/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.carch/x86/config.mk +0
-5@@ -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-undefinedarch/x86/lib/Makefile +1
-1@@ -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.oarch/x86/lib/div64.c new file +26
-0@@ -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);
arch/x86/lib/div64.c new file +5
-0+ output.words.lower =0 ; + }else { +if (!shift) +return num; + output.words.higher = (output.words.higher << shift)|
arch/x86/lib/div64.c new file +13
-0+ (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);
arch/x86/lib/div64.c new file +19
-0+ 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
arch/x86/lib/div64.c new file +6
-0+* exception. +*/ +if (!divider) +return 1 / (u32 )divider; + +/* As an optimization, let's not use 64 bit division unless we
must. */arch/x86/lib/div64.c new file +9
-0+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;
arch/x86/lib/div64.c new file +35
-0+ } +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; +}arch/x86/lib/gcc.c deleted +0
-18@@ -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)));
\arch/x86/lib/gcc.c deleted +0
-10- 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) -Quoted 8 lines
Quoted 2 lines
-#endif
--I don't see
__divdi3and__moddi3in the new implementation. Are they not needed?Quoted 5 lines
Yes, at least I couldn't find any problems compiling U-Boot for x86 with
this patch.BTW: The code size also did shrink a bit with this patch.
But this is needed in fact. If you write some codes doing signed 64-bit integer division, you will get link errors.
Quoted 9 lines
Quoted 1 line
undefined reference to `__divdi3'
You wrote some additional code to test this, that is currently not in mainline, right? Writing code with divisions should be done very carefully from my point of view. And as far as I know, using
do_div()and the functions from lib/div64 is preferred here.Quoted 7 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your patch.Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
Quoted 4 lines
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks for the background. I am not familiar with yocto project, but is the build broken due to the gcc on the build host does not ship with multilib?
I am using a 64-bit host with gcc multilib, and there is no such build error observed.
Regards,
Bin
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Bin,
On 29.11.2017 09:30, Bin Meng wrote:
<snip>
Quoted 21 lines
Quoted 21 lines
Quoted 7 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your patch.Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
Quoted 8 lines
Quoted 4 lines
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks for the background. I am not familiar with yocto project, but is the build broken due to the gcc on the build host does not ship with multilib?
Please take a look at the email thread mentioned above for a detailed explanation. Especially this post should answer your questions:
https://www.mail-archive.com/yocto at yoctoproject.org/msg36748.html
Quoted 2 lines
I am using a 64-bit host with gcc multilib, and there is no such build error observed.
Right. This issue is only seen on Yocto builds (AFAIK). But again, I would really like to see U-Boot x86 being self-contained without any host libgcc dependencies as on other architectures as well.
Thanks,
Stefan
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Stefan,
Quoted 39 lines · Stefan Roese
Hi Bin,
On 29.11.2017 09:30, Bin Meng wrote:
<snip>
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your
patch.Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
Quoted 8 lines
Quoted 4 lines
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks for the background. I am not familiar with yocto project, but is the build broken due to the gcc on the build host does not ship with multilib?
Quoted 4 lines
Please take a look at the email thread mentioned above for a detailed explanation. Especially this post should answer your questions:
https://www.mail-archive.com/yocto at yoctoproject.org/msg36748.html
Now I see. Thank you.
Quoted 8 lines
Quoted 3 lines
I am using a 64-bit host with gcc multilib, and there is no such build error observed.
Right. This issue is only seen on Yocto builds (AFAIK). But again, I would really like to see U-Boot x86 being self-contained without any host libgcc dependencies as on other architectures as well.
So to completely resolve such issue to make U-Boot self-contained, we should remove the reference to the host libgcc.a in arch/x86/lib/Makefile, and use CONFIG_USE_PRIVATE_GCC to include the build for div64.o. Thoughts?
Regards,
Bin
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Bin,
Quoted 52 lines · Bin Meng
Quoted 39 lines · Stefan Roese
Hi Bin,
On 29.11.2017 09:30, Bin Meng wrote:
<snip>
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your
patch.Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
Quoted 8 lines
Quoted 4 lines
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks for the background. I am not familiar with yocto project, but is the build broken due to the gcc on the build host does not ship with multilib?
Quoted 4 lines
Please take a look at the email thread mentioned above for a detailed explanation. Especially this post should answer your questions:
https://www.mail-archive.com/yocto at yoctoproject.org/msg36748.html
Now I see. Thank you.
Quoted 5 lines
Quoted 3 lines
I am using a 64-bit host with gcc multilib, and there is no such build error observed.
Quoted 8 lines
Quoted 3 lines
Right. This issue is only seen on Yocto builds (AFAIK). But again, I would really like to see U-Boot x86 being self-contained without any host libgcc dependencies as on other architectures as well.
So to completely resolve such issue to make U-Boot self-contained, we should remove the reference to the host libgcc.a in
arch/x86/lib/Makefile, and useCONFIG_USE_PRIVATE_GCCto include the build for div64.o. Thoughts?
I was under the impression, that I already removed the host libgcc reference completely for x86 with my patch. But you are correct - there still is a reference in this Makefile which is used by the standalone code, AFAICT.
Any quick idea on how to rid of this one as well?
Thanks,
Stefan
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Stefan,
Quoted 73 lines · Stefan Roese
Hi Bin,
Quoted 63 lines · Bin Meng
Quoted 42 lines · Stefan Roese
Hi Bin,
On 29.11.2017 09:30, Bin Meng wrote:
<snip>
Quoted 24 lines
Quoted 24 lines
Quoted 8 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your
patch.Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
Quoted 8 lines
Quoted 4 lines
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks for the background. I am not familiar with yocto project, but is the build broken due to the gcc on the build host does not ship with multilib?
Quoted 4 lines
Please take a look at the email thread mentioned above for a detailed explanation. Especially this post should answer your questions:
https://www.mail-archive.com/yocto at yoctoproject.org/msg36748.html
Now I see. Thank you.
Quoted 9 lines
Quoted 3 lines
I am using a 64-bit host with gcc multilib, and there is no such build error observed.
Right. This issue is only seen on Yocto builds (AFAIK). But again, I would really like to see U-Boot x86 being self-contained without any host libgcc dependencies as on other architectures as well.
Quoted 4 lines
So to completely resolve such issue to make U-Boot self-contained, we should remove the reference to the host libgcc.a in
arch/x86/lib/Makefile, and useCONFIG_USE_PRIVATE_GCCto include the build for div64.o. Thoughts?
Quoted 7 lines
I was under the impression, that I already removed the host libgcc reference completely for x86 with my patch. But you are correct - there still is a reference in this
Makefilewhich is used by the standalone code, AFAICT.Any quick idea on how to rid of this one as well?
I believe we need change
obj-y += div64.o
to
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += div64.o
To remove the libgcc dependency completely.
Regards,
Bin
PATCH v2 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones
Hi Bin,
Quoted 86 lines · Bin Meng
Hi Stefan,
Quoted 73 lines · Stefan Roese
Hi Bin,
Quoted 63 lines · Bin Meng
Quoted 42 lines · Stefan Roese
Hi Bin,
On 29.11.2017 09:30, Bin Meng wrote:
<snip>
Quoted 24 lines
Quoted 24 lines
Quoted 8 lines
I wrote some codes soemthing like:
s64 a, b, c;
c = a/b;The compiler will generate codes to call
__divdi3. This works before your
patch.Yes, I understand this. But right now, we don't have any code generating this error. And if this will happen at some time, I would prefer to investigate this code sequence introducing this division, to use the division functions / macros available in U-Boot (as mentioned above) and in the kernel instead.
Here a short explanation, why this new version is preferred to the currently available functions pulled from libgcc: We are fixing an "ugly" Yocto build problem with this patch, related to 32bit binaries with 64bit toolchains (multilib) building by not relying on anything from libgcc. Please see this thread for some more details:
Quoted 8 lines
Quoted 4 lines
https://www.mail-archive.com/yocto at yoctoproject.org/msg36721.html
I hope this helps a bit to understand the motivation behind this patch.
Thanks for the background. I am not familiar with yocto project, but is the build broken due to the gcc on the build host does not ship with multilib?
Quoted 4 lines
Please take a look at the email thread mentioned above for a detailed explanation. Especially this post should answer your questions:
https://www.mail-archive.com/yocto at yoctoproject.org/msg36748.html
Now I see. Thank you.
Quoted 9 lines
Quoted 3 lines
I am using a 64-bit host with gcc multilib, and there is no such build error observed.
Right. This issue is only seen on Yocto builds (AFAIK). But again, I would really like to see U-Boot x86 being self-contained without any host libgcc dependencies as on other architectures as well.
Quoted 4 lines
So to completely resolve such issue to make U-Boot self-contained, we should remove the reference to the host libgcc.a in
arch/x86/lib/Makefile, and useCONFIG_USE_PRIVATE_GCCto include the build for div64.o. Thoughts?Quoted 7 lines
I was under the impression, that I already removed the host libgcc reference completely for x86 with my patch. But you are correct - there still is a reference in this
Makefilewhich is used by the standalone code, AFAICT.Any quick idea on how to rid of this one as well?
I believe we need change
Quoted 7 lines
obj-y += div64.o
to
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += div64.o
To remove the libgcc dependency completely.
Yep. Thanks.
I've posted v3 with this additional removal.
Thanks,
Stefan