[U-Boot] powerpc: FOO uses hard float, BAR uses soft float

Hi,
I'm looking for help to get rid of linker warnigns like these:
-> ./MAKEALL sequoia Configuring for sequoia - Board: sequoia, Options: SEQUOIA powerpc-linux-ld: Warning: 20010226-1.o uses hard float, libpostpowerpcfpu.o uses soft float powerpc-linux-ld: Warning: acc1.o uses hard float, libpostpowerpcfpu.o uses soft float powerpc-linux-ld: Warning: /opt/eldk-5.1/powerpc/sysroots/powerpc-linux/usr/lib/powerpc-linux/4.6.1/libgcc.a(darwin-ldouble.o) uses hard float, u-boot uses soft float
These warnings are cause by the fact that we always build U-Boot with "-msoft-float", but boards that have POST enabled may pull in the FPU test code, which naturally will have to be compiled with "-mhard-float" instead.
Is there any way to silence these warnings (ideally only for these specific set of files, where we know they are to be expected) ?
I tried playing tricks to get rid of them - the information about using the FPU is envoded in the ".gnu.attributes" section of the ELF file:
-> readelf -A /work/wd/tmp-ppc/post/lib_powerpc/fpu/acc1.o Attribute Section: gnu File Attributes Tag_GNU_Power_ABI_FP: Hard float
-> readelf -e /work/wd/tmp-ppc/post/lib_powerpc/fpu/acc1.o | grep gnu.attributes [129] .gnu.attributes LOOS+ffffff5 00000000 004e5c 000010 00 0 0 1
We can remove this information using brute force, like
${CROSS_COMPILE}objcopy -R .gnu.attributes
which indeed gets rid of most of the warnings - but it will still result in the
powerpc-linux-ld: Warning: /opt/eldk-5.1/powerpc/sysroots/powerpc-linux/usr/lib/powerpc-linux/4.6.1/libgcc.a(darwin-ldouble.o) uses hard float, u-boot uses soft float
warning.
Anybody any ideas?
Best regards,
Wolfgang Denk

On 12/08/2011 03:09 PM, Wolfgang Denk wrote:
Hi,
I'm looking for help to get rid of linker warnigns like these:
-> ./MAKEALL sequoia Configuring for sequoia - Board: sequoia, Options: SEQUOIA powerpc-linux-ld: Warning: 20010226-1.o uses hard float, libpostpowerpcfpu.o uses soft float powerpc-linux-ld: Warning: acc1.o uses hard float, libpostpowerpcfpu.o uses soft float powerpc-linux-ld: Warning: /opt/eldk-5.1/powerpc/sysroots/powerpc-linux/usr/lib/powerpc-linux/4.6.1/libgcc.a(darwin-ldouble.o) uses hard float, u-boot uses soft float
These warnings are cause by the fact that we always build U-Boot with "-msoft-float", but boards that have POST enabled may pull in the FPU test code, which naturally will have to be compiled with "-mhard-float" instead.
Is there any way to silence these warnings (ideally only for these specific set of files, where we know they are to be expected) ?
I'm not familiar with PPC, but below I describe the situation for ARM; if it's similar, this should be useful...
soft and hard float are incompatible ABIs. You can't mix code that's compiled with different ABIs. That's what the linker is complaining about.
The solution may be to build U-Boot with -mfloat-abi=hard, but disallow FP usage through some other means (I /think/ there's a separate gcc flag for this).
Alternatively, the FPU test code could be built with -mfloat-abi=softfp. That allows FPU usage (especially true if it's via inline assembler etc.!), but has an ABI compatible with -mfloat-abi=soft.
I wrote up more background notes on this for our internal wiki:
Not all ARM CPUs have a floating-point co-processor (FPU), and hence not all ARM CPUs have the FPU's set of dedicated floating-point (FP) registers.
Historically, this has meant that:
* The calling convention does not pass FP values in the dedicated FP registers (FPRs), but rather uses the main ARM CPU's regular register set. * Compilers don't emit FP instructions into code, but rather emit calls to utility functions to perform FP operations, such as add or multiply. The implementation of those utility functions may contain hand-coded assembler that uses the FPU, or call an FP emulation library; the choice is up to the system/OS builder based on their knowledge of the actual CPU's capabilities.
The above combination yields the FP ABI known as "soft"; gcc option -mfloat-abi=soft.
When it is known that code will run on CPU(s) with a real FPU, the compiler may be instructed to emit FP instructions directly into the code. This benefits performance since a function call is no longer needed for each FP operation. However, for backwards-compatibility, when passing FP values between functions, the calling convention is not changed, and hence the values need to be moved back and forth between CPU registers and FPRs. This yields the floating point ABI known as "softfp"; gcc option -mfloat-abi=softfp.
Code using either the "soft" or "softfp" "ABIs" is 100% compatible (given a CPU that actually has an FPU); the actual ABI is identical between these two cases, the difference simply being whether FP operations use FPU instructions directly or not.
Most recent CPUs do actually contain an FPU. In this case, it is inefficient to constantly move FP values back and forth between CPU register and FPRs. To address this, a new calling convention was created, which uses FPRs to pass FP values between functions. This yields the floating point ABI known as "hard"; gcc option -mfloat-abi=hard.
Code using the "hard" ABI is incompatible with code using either the "soft" or "softfp" ABIs. The entire system (C library, all shared libraries, all applications) must be rebuilt using the hard ABI for it to function correctly because FP values are passed in the FP hardware registers in the hard ABI.
The user-space <-> kernel-space divide provides a barrier between ABI requirements. The kernel specifies a completely different syscall-based ABI and this is not be affected by whether user-space uses the soft or hard ABI for function calls. This is largely moot as syscalls generally do not pass or return floating point numbers.

On Dec 8, 2011, at 4:09 PM, Wolfgang Denk wrote:
Hi,
I'm looking for help to get rid of linker warnigns like these:
-> ./MAKEALL sequoia Configuring for sequoia - Board: sequoia, Options: SEQUOIA powerpc-linux-ld: Warning: 20010226-1.o uses hard float, libpostpowerpcfpu.o uses soft float powerpc-linux-ld: Warning: acc1.o uses hard float, libpostpowerpcfpu.o uses soft float powerpc-linux-ld: Warning: /opt/eldk-5.1/powerpc/sysroots/powerpc-linux/usr/lib/powerpc-linux/4.6.1/libgcc.a(darwin-ldouble.o) uses hard float, u-boot uses soft float
These warnings are cause by the fact that we always build U-Boot with "-msoft-float", but boards that have POST enabled may pull in the FPU test code, which naturally will have to be compiled with "-mhard-float" instead.
Is there any way to silence these warnings (ideally only for these specific set of files, where we know they are to be expected) ?
I tried playing tricks to get rid of them - the information about using the FPU is envoded in the ".gnu.attributes" section of the ELF file:
-> readelf -A /work/wd/tmp-ppc/post/lib_powerpc/fpu/acc1.o Attribute Section: gnu File Attributes Tag_GNU_Power_ABI_FP: Hard float
-> readelf -e /work/wd/tmp-ppc/post/lib_powerpc/fpu/acc1.o | grep gnu.attributes [129] .gnu.attributes LOOS+ffffff5 00000000 004e5c 000010 00 0 0 1
We can remove this information using brute force, like
${CROSS_COMPILE}objcopy -R .gnu.attributes
which indeed gets rid of most of the warnings - but it will still result in the
powerpc-linux-ld: Warning: /opt/eldk-5.1/powerpc/sysroots/powerpc-linux/usr/lib/powerpc-linux/4.6.1/libgcc.a(darwin-ldouble.o) uses hard float, u-boot uses soft float
warning.
Anybody any ideas?
Look at commit, we dealt with this in the past
commit ce82ff05388b5ddafdf6082ef0776cce72c40b1c Author: Yuri Tikhonov yur@emcraft.com Date: Sat Dec 20 14:54:21 2008 +0300
FPU POST: fix warnings when building with 2.18 binutils
Also:
commit e009cdeb63308f291c54b173484401aab4a3fe54 Author: Kumar Gala galak@kernel.crashing.org Date: Tue Jan 25 03:00:08 2011 -0600
powerpc: Fix FPU post related link warnings
- k

Dear Kumar,
In message 4421AD7B-D8AA-455E-B67D-328C3E7427BD@kernel.crashing.org you wrote:
Look at commit, we dealt with this in the past
commit ce82ff05388b5ddafdf6082ef0776cce72c40b1c Author: Yuri Tikhonov yur@emcraft.com Date: Sat Dec 20 14:54:21 2008 +0300
FPU POST: fix warnings when building with 2.18 binutils
Also:
commit e009cdeb63308f291c54b173484401aab4a3fe54 Author: Kumar Gala galak@kernel.crashing.org Date: Tue Jan 25 03:00:08 2011 -0600
powerpc: Fix FPU post related link warnings
Thanks for pointing out. I have to admit that I had completely forgotten about these.
Hm, unfortunately this appears to have stopped working.
The two objects that are flagged as "Tag_GNU_Power_ABI_FP: Hard float" are post/lib_powerpc/fpu/acc1.o and post/lib_powerpc/fpu/20010226-1.o
Both corresponding source files have the GNU_FPOST_ATTR macro...
It appears with GCC 4.6.1 the explicit "-mhard-float" command line option takes precedence over the ``asm(".gnu_attribute 4, 2");'' in the source file :-(
Is there any way to manually edit the attribute in the object file, using ld or elfedit or ... ?
Best regards,
Wolfgang Denk

It appears that with recent versions of GCC the explicit "-mhard-float" command line option takes precedence over the ``asm(".gnu_attribute 4, 2");'' in the source file, so this no longer helps to avoid the warnings we get when linking code that uses FP instructions with other code that was built using soft-float.
We can remove the ".gnu_attribute" (which appears to carry no other information, at least so far) from the object files, but we also have to make sure we don't pull in the __gcc_qsub() and __gcc_qmul() functions from the standard libgcc, as these would again "infect" our linking. We copy this code from: gcc-4.2.2/gcc/config/rs6000/darwin-ldouble.c This old version was chosen because it was still available under a compatible license (GCC v2+). The file was stripped down to the needed parts, and reformatted so it passes checkpatch with only one warning (do not add new typedefs).
Signed-off-by: Wolfgang Denk wd@denx.de Cc: Kumar Gala galak@kernel.crashing.org Cc: Stefan Roese sr@denx.de Cc: Andy Fleming afleming@gmail.com Cc: Kim Phillips kim.phillips@freescale.com --- This patch silences build warnings for the following boards: aev BC3450 charon, cm5200 fo300 korat korat_perm lwmon5 MiniFAP PMC440 sacsng sequoia sequoia_nand sequoia_ramboot TB5200 TB5200_B TQM5200 TQM5200_B TQM5200_B_HIGHBOOT TQM5200S TQM5200S_HIGHBOOT TQM5200_STK100
post/lib_powerpc/fpu/Makefile | 17 ++++- post/lib_powerpc/fpu/darwin-ldouble.c | 141 +++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 post/lib_powerpc/fpu/darwin-ldouble.c
diff --git a/post/lib_powerpc/fpu/Makefile b/post/lib_powerpc/fpu/Makefile index b97ad6f..5d0e52d 100644 --- a/post/lib_powerpc/fpu/Makefile +++ b/post/lib_powerpc/fpu/Makefile @@ -24,10 +24,23 @@ include $(TOPDIR)/config.mk
LIB = libpost$(ARCH)fpu.o
-COBJS-$(CONFIG_HAS_POST) += fpu.o 20001122-1.o 20010114-2.o 20010226-1.o 980619-1.o -COBJS-$(CONFIG_HAS_POST) += acc1.o compare-fp-1.o mul-subnormal-single-1.o +COBJS-$(CONFIG_HAS_POST) += 20001122-1.o +COBJS-$(CONFIG_HAS_POST) += 20010114-2.o +COBJS-$(CONFIG_HAS_POST) += 20010226-1.o +COBJS-$(CONFIG_HAS_POST) += 980619-1.o +COBJS-$(CONFIG_HAS_POST) += acc1.o +COBJS-$(CONFIG_HAS_POST) += compare-fp-1.o +COBJS-$(CONFIG_HAS_POST) += fpu.o +COBJS-$(CONFIG_HAS_POST) += mul-subnormal-single-1.o + +COBJS-$(CONFIG_HAS_POST) += darwin-ldouble.o
include $(TOPDIR)/post/rules.mk
CFLAGS := $(shell echo $(CFLAGS) | sed s/-msoft-float//) CFLAGS += -mhard-float -fkeep-inline-functions + +$(obj)%.o: %.c + $(CC) $(ALL_CFLAGS) -o $@.fp $< -c + $(OBJCOPY) -R .gnu.attributes $@.fp $@ + rm -f $@.fp diff --git a/post/lib_powerpc/fpu/darwin-ldouble.c b/post/lib_powerpc/fpu/darwin-ldouble.c new file mode 100644 index 0000000..41ae202 --- /dev/null +++ b/post/lib_powerpc/fpu/darwin-ldouble.c @@ -0,0 +1,141 @@ +/* + * Borrowed from GCC 4.2.2 (which still was GPL v2+) + */ +/* 128-bit long double support routines for Darwin. + Copyright (C) 1993, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ + +/* + * Implementations of floating-point long double basic arithmetic + * functions called by the IBM C compiler when generating code for + * PowerPC platforms. In particular, the following functions are + * implemented: __gcc_qadd, __gcc_qsub, __gcc_qmul, and __gcc_qdiv. + * Double-double algorithms are based on the paper "Doubled-Precision + * IEEE Standard 754 Floating-Point Arithmetic" by W. Kahan, February 26, + * 1987. An alternative published reference is "Software for + * Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa, + * ACM TOMS vol 7 no 3, September 1981, pages 272-283. + */ + +/* + * Each long double is made up of two IEEE doubles. The value of the + * long double is the sum of the values of the two parts. The most + * significant part is required to be the value of the long double + * rounded to the nearest double, as specified by IEEE. For Inf + * values, the least significant part is required to be one of +0.0 or + * -0.0. No other requirements are made; so, for example, 1.0 may be + * represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a + * NaN is don't-care. + * + * This code currently assumes big-endian. + */ + +#define fabs(x) __builtin_fabs(x) +#define isless(x, y) __builtin_isless(x, y) +#define inf() __builtin_inf() +#define unlikely(x) __builtin_expect((x), 0) +#define nonfinite(a) unlikely(!isless(fabs(a), inf())) + +typedef union { + long double ldval; + double dval[2]; +} longDblUnion; + +/* Add two 'long double' values and return the result. */ +long double __gcc_qadd(double a, double aa, double c, double cc) +{ + longDblUnion x; + double z, q, zz, xh; + + z = a + c; + + if (nonfinite(z)) { + z = cc + aa + c + a; + if (nonfinite(z)) + return z; + x.dval[0] = z; /* Will always be DBL_MAX. */ + zz = aa + cc; + if (fabs(a) > fabs(c)) + x.dval[1] = a - z + c + zz; + else + x.dval[1] = c - z + a + zz; + } else { + q = a - z; + zz = q + c + (a - (q + z)) + aa + cc; + + /* Keep -0 result. */ + if (zz == 0.0) + return z; + + xh = z + zz; + if (nonfinite(xh)) + return xh; + + x.dval[0] = xh; + x.dval[1] = z - xh + zz; + } + return x.ldval; +} + +long double __gcc_qsub(double a, double b, double c, double d) +{ + return __gcc_qadd(a, b, -c, -d); +} + +long double __gcc_qmul(double a, double b, double c, double d) +{ + longDblUnion z; + double t, tau, u, v, w; + + t = a * c; /* Highest order double term. */ + + if (unlikely(t == 0) /* Preserve -0. */ + || nonfinite(t)) + return t; + + /* Sum terms of two highest orders. */ + + /* Use fused multiply-add to get low part of a * c. */ +#ifndef __NO_FPRS__ + asm("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t)); +#else + tau = fmsub(a, c, t); +#endif + v = a * d; + w = b * c; + tau += v + w; /* Add in other second-order terms. */ + u = t + tau; + + /* Construct long double result. */ + if (nonfinite(u)) + return u; + z.dval[0] = u; + z.dval[1] = (t - u) + tau; + return z.ldval; +}

Hi Wolfgang,
On Thursday 22 December 2011 15:29:41 Wolfgang Denk wrote:
It appears that with recent versions of GCC the explicit "-mhard-float" command line option takes precedence over the ``asm(".gnu_attribute 4, 2");'' in the source file, so this no longer helps to avoid the warnings we get when linking code that uses FP instructions with other code that was built using soft-float.
We can remove the ".gnu_attribute" (which appears to carry no other information, at least so far) from the object files, but we also have to make sure we don't pull in the __gcc_qsub() and __gcc_qmul() functions from the standard libgcc, as these would again "infect" our linking. We copy this code from: gcc-4.2.2/gcc/config/rs6000/darwin-ldouble.c This old version was chosen because it was still available under a compatible license (GCC v2+). The file was stripped down to the needed parts, and reformatted so it passes checkpatch with only one warning (do not add new typedefs).
Signed-off-by: Wolfgang Denk wd@denx.de Cc: Kumar Gala galak@kernel.crashing.org Cc: Stefan Roese sr@denx.de Cc: Andy Fleming afleming@gmail.com Cc: Kim Phillips kim.phillips@freescale.com
Tested successfully on sequoia, so:
Tested-by: Stefan Roese sr@denx.de
Best regards, Stefan
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-0 Fax: (+49)-8142-66989-80 Email: office@denx.de

Hi Wolfgang,
On Thu, 22 Dec 2011 15:29:41 +0100 Wolfgang Denk wd@denx.de wrote:
It appears that with recent versions of GCC the explicit "-mhard-float" command line option takes precedence over the ``asm(".gnu_attribute 4, 2");'' in the source file, so this no longer helps to avoid the warnings we get when linking code that uses FP instructions with other code that was built using soft-float.
We can remove the ".gnu_attribute" (which appears to carry no other information, at least so far) from the object files, but we also have to make sure we don't pull in the __gcc_qsub() and __gcc_qmul() functions from the standard libgcc, as these would again "infect" our linking. We copy this code from: gcc-4.2.2/gcc/config/rs6000/darwin-ldouble.c This old version was chosen because it was still available under a compatible license (GCC v2+). The file was stripped down to the needed parts, and reformatted so it passes checkpatch with only one warning (do not add new typedefs).
Signed-off-by: Wolfgang Denk wd@denx.de Cc: Kumar Gala galak@kernel.crashing.org Cc: Stefan Roese sr@denx.de Cc: Andy Fleming afleming@gmail.com Cc: Kim Phillips kim.phillips@freescale.com
Tested on TQM5200.
Tested-by: Anatolij Gustschin agust@denx.de
Anatolij

Dear Wolfgang Denk,
In message 1324564181-8949-1-git-send-email-wd@denx.de you wrote:
It appears that with recent versions of GCC the explicit "-mhard-float" command line option takes precedence over the ``asm(".gnu_attribute 4, 2");'' in the source file, so this no longer helps to avoid the warnings we get when linking code that uses FP instructions with other code that was built using soft-float.
We can remove the ".gnu_attribute" (which appears to carry no other information, at least so far) from the object files, but we also have to make sure we don't pull in the __gcc_qsub() and __gcc_qmul() functions from the standard libgcc, as these would again "infect" our linking. We copy this code from: gcc-4.2.2/gcc/config/rs6000/darwin-ldouble.c This old version was chosen because it was still available under a compatible license (GCC v2+). The file was stripped down to the needed parts, and reformatted so it passes checkpatch with only one warning (do not add new typedefs).
Signed-off-by: Wolfgang Denk wd@denx.de Cc: Kumar Gala galak@kernel.crashing.org Cc: Stefan Roese sr@denx.de Cc: Andy Fleming afleming@gmail.com Cc: Kim Phillips kim.phillips@freescale.com
This patch silences build warnings for the following boards: aev BC3450 charon, cm5200 fo300 korat korat_perm lwmon5 MiniFAP PMC440 sacsng sequoia sequoia_nand sequoia_ramboot TB5200 TB5200_B TQM5200 TQM5200_B TQM5200_B_HIGHBOOT TQM5200S TQM5200S_HIGHBOOT TQM5200_STK100
post/lib_powerpc/fpu/Makefile | 17 ++++- post/lib_powerpc/fpu/darwin-ldouble.c | 141 +++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 post/lib_powerpc/fpu/darwin-ldouble.c
Applied, thanks.
Best regards,
Wolfgang Denk
participants (5)
-
Anatolij Gustschin
-
Kumar Gala
-
Stefan Roese
-
Stephen Warren
-
Wolfgang Denk