Skip to contentSkip to conversation

x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones

PATCH New Stefan Roese 3 participants 4 messages Nov 29, 2017 – Dec 2, 2017 x86

lore
Share & tools
lore
#0 lore raw

PATCH v3 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

---
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
arch/x86/config.mk +0 -3
index 8835dcf36f..472ada5490 100644
@@ -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 -7
index fe00d7573f..7d729ea0f7 100644
@@ -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
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
deleted file mode 100644
index 3c70d790d4..0000000000
@@ -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
#1 lore raw

PATCH v3 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones

Quoted 26 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.git

---
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

Quoted 8 lines
 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
#2 lore raw

PATCH v3 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones

Quoted 36 lines · Bin Meng
Quoted 26 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.git

---
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

Quoted 8 lines
 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
Quoted 2 lines

applied to u-boot-x86, thanks!

#3 lore raw

PATCH v3 1/1 x86: lib: Implement standalone __udivdi3 etc instead of libgcc ones

In reply to Stefan Roese

Op Wed, 29 Nov 2017 16:23:31 +0100, schreef Stefan Roese:

Quoted 4 lines

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.

Quoted 43 lines

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

---
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

arch/x86/config.mk index renamed from arch/x86/config.mk +0 -0

8835dcf36f..472ada5490 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -34,9 +34,6 @@ PLATFORM_RELFLAGS +=

arch/x86/config.mk index renamed from arch/x86/config.mk +0 -3
-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 index renamed from arch/x86/lib/Makefile +0 -0
Quoted 7 lines

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

Quoted 30 lines
arch/x86/lib/Makefile index renamed from arch/x86/lib/Makefile +1 -4
@@ -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
arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +0 -0

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 + */

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +8 -0
+
+#include <common.h>
+
+union overlay64 {
+	u64 longw;
+	struct {
+		u32 lower;
+		u32 higher;

arch/x86/lib/div64.c new file mode

Quoted 10 lines
arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +10 -0
+	} 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 mode

Quoted 5 lines

output.words.lower = 0;

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +4 -0
+	} else {
+		if (!shift)
+			return num;
+		output.words.higher = (output.words.higher << shift) | 

+

arch/x86/lib/div64.c new file mode

Quoted 13 lines

(output.words.lower >> (32 - shift));

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +12 -0
+		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 mode

Quoted 5 lines

output.words.higher = 0;

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +4 -0
+	} else {
+		if (!shift)
+			return num;
+		output.words.lower = output.words.lower >> shift | 

+

Quoted 4 lines

(output.words.higher << (32 - shift));

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +3 -0
+		output.words.higher = output.words.higher >> shift;
+	}
+	return output.longw;

arch/x86/lib/div64.c new file mode

Quoted 10 lines
arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +10 -0
+}
+
+#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 mode

Quoted 6 lines

exception.

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +5 -0
+	 */
+	if (!divider)
+		return 1 / (u32)divider;
+
+	/* As an optimization, let's not use 64 bit division unless we 

must.

Quoted 61 lines

*/ + if (dividend <= MAX_32BIT_UINT) {

arch/x86/lib/div64.c new file mode renamed from arch/x86/lib/div64.c +43 -0
+		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 file mode renamed from arch/x86/lib/gcc.c +0 -0

100644 index 3c70d790d4..0000000000 --- a/arch/x86/lib/gcc.c +++ /dev/null @@ -1,29 +0,0 @@

arch/x86/lib/gcc.c deleted file mode renamed from arch/x86/lib/gcc.c +0 -10
-/*
- * 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.
- */

arch/x86/lib/gcc.c deleted file mode

Quoted 2 lines
arch/x86/lib/gcc.c deleted file mode renamed from arch/x86/lib/gcc.c +0 -2
-#define WRAP_LIBGCC_CALL(type, name) \
-	type __normal_##name(type a, type b) __attribute__((regparm(0))); 

\

Quoted 11 lines
arch/x86/lib/gcc.c deleted file mode renamed from arch/x86/lib/gcc.c +0 -11
-	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