[U-Boot] Cannot compile arm u-boot with hardfloat toolchain

Hello,
when using a hardfloat toolchain linking u-boot fails.
LD u-boot ld.bfd: error: /usr/lib/gcc/arm-linux-gnueabihf/4.9/libgcc.a(bpabi.o) uses VFP register arguments, u-boot does not ld.bfd: failed to merge target specific data of file /usr/lib/gcc/arm-linux-gnueabihf/4.9/libgcc.a(bpabi.o) ld.bfd: error: /usr/lib/gcc/arm-linux-gnueabihf/4.9/libgcc.a(_divdi3.o) uses VFP register arguments, u-boot does not ld.bfd: failed to merge target specific data of file /usr/lib/gcc/arm-linux-gnueabihf/4.9/libgcc.a(_divdi3.o) ld.bfd: error: /usr/lib/gcc/arm-linux-gnueabihf/4.9/libgcc.a(_udivdi3.o) uses VFP register arguments, u-boot does not ld.bfd: failed to merge target specific data of file /usr/lib/gcc/arm-linux-gnueabihf/4.9/libgcc.a(_udivdi3.o) Makefile:1065: recipe for target 'u-boot' failed make: *** [u-boot] Error 1
Removing the softfloat option fixes the issue:
--- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -16,7 +16,7 @@ endif LDFLAGS_FINAL += --gc-sections PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ -fno-common -ffixed-r9 -PLATFORM_RELFLAGS += $(call cc-option, -msoft-float) \ +PLATFORM_RELFLAGS += \ $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
# Support generic board on ARM
Did u-boot start using floating point calculations? Or are these objects superfluous? Or neither of that but addition of the softfloat option sometime last year just needlessly breaks builds?
Thanks
Michal

On Sun, Jan 04, 2015 at 11:23:29PM +0100, Michal Suchanek wrote:
Hello,
when using a hardfloat toolchain linking u-boot fails.
What version of U-Boot are you building? There's a few rc releases that fail with hardfp-only because a few things leaked in with 64bit math.

On 5 January 2015 at 02:28, Tom Rini trini@ti.com wrote:
On Sun, Jan 04, 2015 at 11:23:29PM +0100, Michal Suchanek wrote:
Hello,
when using a hardfloat toolchain linking u-boot fails.
What version of U-Boot are you building? There's a few rc releases that fail with hardfp-only because a few things leaked in with 64bit math.
I am building master (or what you get by cloning git) with some extra patches for sunxi support.
Maybe I should check if some of the sunxi patches cause the failure.
Thanks
Michal

On 05/01/15 01:28, Tom Rini wrote:
On Sun, Jan 04, 2015 at 11:23:29PM +0100, Michal Suchanek wrote:
when using a hardfloat toolchain linking u-boot fails.
What version of U-Boot are you building? There's a few rc releases that fail with hardfp-only because a few things leaked in with 64bit math.
Hi Tom,
I also encountered this problem ( http://lists.denx.de/pipermail/u-boot/2015-January/200123.html ) and found it was indeed when 64-bit maths operations were included. To be exact, it was this division of a long long in drivers/video/videomodes.c:
mode->pixclock = 1000000000000LL / EDID_DETAILED_TIMING_PIXEL_CLOCK(*t);
which was part of this commit in Hans' sunxi video series:
0cd5efe videomodes: Add video_edid_dtd_to_ctfb_res_modes helper function
and which was linked into the u-boot binary in a later commit:
e7872f3 sunxi: video: Use video-mode/-timing from videomodes diff --git a/drivers/video/Makefile b/drivers/video/Makefile [...] -obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o +obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o
Thanks, B.R. Oake.

Hi,
On 05-01-15 11:46, B.R. Oake wrote:
On 05/01/15 01:28, Tom Rini wrote:
On Sun, Jan 04, 2015 at 11:23:29PM +0100, Michal Suchanek wrote:
when using a hardfloat toolchain linking u-boot fails.
What version of U-Boot are you building? There's a few rc releases that fail with hardfp-only because a few things leaked in with 64bit math.
Hi Tom,
I also encountered this problem ( http://lists.denx.de/pipermail/u-boot/2015-January/200123.html ) and found it was indeed when 64-bit maths operations were included. To be exact, it was this division of a long long in drivers/video/videomodes.c:
mode->pixclock = 1000000000000LL / EDID_DETAILED_TIMING_PIXEL_CLOCK(*t);
which was part of this commit in Hans' sunxi video series:
0cd5efe videomodes: Add video_edid_dtd_to_ctfb_res_modes helper function
and which was linked into the u-boot binary in a later commit:
e7872f3 sunxi: video: Use video-mode/-timing from videomodes diff --git a/drivers/video/Makefile b/drivers/video/Makefile [...] -obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o +obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o
Ah, ok, thanks for figuring that out, so this only happens to people following my sunxi-wip branch, because that commit is not upstream yet.
So I guess I will need to fix this somehow without using 64 bit math, any suggestions?
Regards,
Hans

Hi
On Mon, Jan 5, 2015 at 11:51 AM, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 05-01-15 11:46, B.R. Oake wrote:
On 05/01/15 01:28, Tom Rini wrote:
On Sun, Jan 04, 2015 at 11:23:29PM +0100, Michal Suchanek wrote:
when using a hardfloat toolchain linking u-boot fails.
What version of U-Boot are you building? There's a few rc releases that fail with hardfp-only because a few things leaked in with 64bit math.
Hi Tom,
I also encountered this problem ( http://lists.denx.de/pipermail/u-boot/2015-January/200123.html ) and found it was indeed when 64-bit maths operations were included. To be exact, it was this division of a long long in drivers/video/videomodes.c:
mode->pixclock = 1000000000000LL /
EDID_DETAILED_TIMING_PIXEL_CLOCK(*t);
which was part of this commit in Hans' sunxi video series:
0cd5efe videomodes: Add video_edid_dtd_to_ctfb_res_modes helper function
and which was linked into the u-boot binary in a later commit:
e7872f3 sunxi: video: Use video-mode/-timing from videomodes diff --git a/drivers/video/Makefile b/drivers/video/Makefile [...] -obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o +obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o
Ah, ok, thanks for figuring that out, so this only happens to people following my sunxi-wip branch, because that commit is not upstream yet.
So I guess I will need to fix this somehow without using 64 bit math, any suggestions?
do_div?
Michael
Regards,
Hans
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 05/01/15 10:51, Hans de Goede wrote:
Ah, ok, thanks for figuring that out, so this only happens to people following my sunxi-wip branch, because that commit is not upstream yet.
So I guess I will need to fix this somehow without using 64 bit math, any suggestions?
EDID_DETAILED_TIMING_PIXEL_CLOCK() always returns a uint32 that is 10,000 times a uint16, so one way of avoiding 64-bit arithmetic would be to cancel out the 10,000 before the division:
--- a/drivers/video/videomodes.c 2015-01-05 10:18:58.745985034 +0000 +++ b/drivers/video/videomodes.c 2015-01-05 12:15:27.484150964 +0000 @@ -411,7 +411,8 @@ mode->refresh = EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) / (h_total * v_total);
- mode->pixclock = 1000000000000LL / EDID_DETAILED_TIMING_PIXEL_CLOCK(*t); + mode->pixclock = 100000000L / + (EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) / 10000); mode->pixclock_khz = (EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) + 500) / 1000;
I still wonder though whether a nicer way would be for the configs to be refactored so that -msoft-float was not set on platforms where it wasn't appropriate.
Cheers, B.R.

On Mon, Jan 05, 2015 at 12:24:13PM +0000, B.R. Oake wrote:
On 05/01/15 10:51, Hans de Goede wrote:
Ah, ok, thanks for figuring that out, so this only happens to people following my sunxi-wip branch, because that commit is not upstream yet.
So I guess I will need to fix this somehow without using 64 bit math, any suggestions?
EDID_DETAILED_TIMING_PIXEL_CLOCK() always returns a uint32 that is 10,000 times a uint16, so one way of avoiding 64-bit arithmetic would be to cancel out the 10,000 before the division:
Good idea!
[snip]
I still wonder though whether a nicer way would be for the configs to be refactored so that -msoft-float was not set on platforms where it wasn't appropriate.
We've gone over this before (so there's discussions in the archive) but in sum, no, we don't want to get into doing floating point.

On 05/01/15 13:37, Tom Rini wrote:
On Mon, Jan 05, 2015 at 12:24:13PM +0000, B.R. Oake wrote:
I still wonder though whether a nicer way would be for the configs to be refactored so that -msoft-float was not set on platforms where it wasn't appropriate.
We've gone over this before (so there's discussions in the archive) but in sum, no, we don't want to get into doing floating point.
Hi Tom,
OK, I'll look for those discussions for more background. Just in case there's any misunderstanding, though, I wasn't advocating using floating point, I just meant that U-Boot code might want to perform operations such as long long integer division, which will invoke a libgcc function such as __udivdi3(), and for the linking to succeed we need to ensure that U-Boot and libgcc are using the same ABI. On a fully hard-float system, removing the -msoft-float compilation option seems a good way of achieving that.
Thanks, B.R.

Hi,
On 05-01-15 13:24, B.R. Oake wrote:
On 05/01/15 10:51, Hans de Goede wrote:
Ah, ok, thanks for figuring that out, so this only happens to people following my sunxi-wip branch, because that commit is not upstream yet.
So I guess I will need to fix this somehow without using 64 bit math, any suggestions?
EDID_DETAILED_TIMING_PIXEL_CLOCK() always returns a uint32 that is 10,000 times a uint16, so one way of avoiding 64-bit arithmetic would be to cancel out the 10,000 before the division:
--- a/drivers/video/videomodes.c 2015-01-05 10:18:58.745985034 +0000 +++ b/drivers/video/videomodes.c 2015-01-05 12:15:27.484150964 +0000 @@ -411,7 +411,8 @@ mode->refresh = EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) / (h_total * v_total);
- mode->pixclock = 1000000000000LL / EDID_DETAILED_TIMING_PIXEL_CLOCK(*t);
- mode->pixclock = 100000000L /
mode->pixclock_khz = (EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) + 500) / 1000;(EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) / 10000);
I still wonder though whether a nicer way would be for the configs to be refactored so that -msoft-float was not set on platforms where it wasn't appropriate.
Ah I did not realize that the EDID_DETAILED_TIMING_PIXEL_CLOCK did * 10000, that indeed makes things easier, I've done this instead (somewhat cleaner) :
- mode->pixclock = 1000000000000LL / EDID_DETAILED_TIMING_PIXEL_CLOCK(*t); - mode->pixclock_khz = (EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) + 500) / - 1000; + mode->pixclock_khz = EDID_DETAILED_TIMING_PIXEL_CLOCK(*t) / 1000; + mode->pixclock = 1000000000L / mode->pixclock_khz;
I've squashed this fix into my personal tree, sunxi-wip branch, so people building from there should not longer see those compile errors, and I'll preserve the fix when the patches move to u-boot-sunxi/next :)
Regards,
Hans
participants (5)
-
B.R. Oake
-
Hans de Goede
-
Michael Trimarchi
-
Michal Suchanek
-
Tom Rini