Commit 139e1875d3b3dc31a6ea964f6ff3912fed32c4a2

Authored by Wolfgang Denk
1 parent af44f4b2a5

PPC: fix "Warning: FOO uses hard float, BAR uses soft float".

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-by: Stefan Roese <sr@denx.de>
Tested-by: Anatolij Gustschin <agust@denx.de>

Showing 2 changed files with 156 additions and 2 deletions Side-by-side Diff

post/lib_powerpc/fpu/Makefile
... ... @@ -24,11 +24,24 @@
24 24  
25 25 LIB = libpost$(ARCH)fpu.o
26 26  
27   -COBJS-$(CONFIG_HAS_POST) += fpu.o 20001122-1.o 20010114-2.o 20010226-1.o 980619-1.o
28   -COBJS-$(CONFIG_HAS_POST) += acc1.o compare-fp-1.o mul-subnormal-single-1.o
  27 +COBJS-$(CONFIG_HAS_POST) += 20001122-1.o
  28 +COBJS-$(CONFIG_HAS_POST) += 20010114-2.o
  29 +COBJS-$(CONFIG_HAS_POST) += 20010226-1.o
  30 +COBJS-$(CONFIG_HAS_POST) += 980619-1.o
  31 +COBJS-$(CONFIG_HAS_POST) += acc1.o
  32 +COBJS-$(CONFIG_HAS_POST) += compare-fp-1.o
  33 +COBJS-$(CONFIG_HAS_POST) += fpu.o
  34 +COBJS-$(CONFIG_HAS_POST) += mul-subnormal-single-1.o
29 35  
  36 +COBJS-$(CONFIG_HAS_POST) += darwin-ldouble.o
  37 +
30 38 include $(TOPDIR)/post/rules.mk
31 39  
32 40 CFLAGS := $(shell echo $(CFLAGS) | sed s/-msoft-float//)
33 41 CFLAGS += -mhard-float -fkeep-inline-functions
  42 +
  43 +$(obj)%.o: %.c
  44 + $(CC) $(ALL_CFLAGS) -o $@.fp $< -c
  45 + $(OBJCOPY) -R .gnu.attributes $@.fp $@
  46 + rm -f $@.fp
post/lib_powerpc/fpu/darwin-ldouble.c
  1 +/*
  2 + * Borrowed from GCC 4.2.2 (which still was GPL v2+)
  3 + */
  4 +/* 128-bit long double support routines for Darwin.
  5 + Copyright (C) 1993, 2003, 2004, 2005, 2006, 2007
  6 + Free Software Foundation, Inc.
  7 +
  8 +This file is part of GCC.
  9 +
  10 +GCC is free software; you can redistribute it and/or modify it under
  11 +the terms of the GNU General Public License as published by the Free
  12 +Software Foundation; either version 2, or (at your option) any later
  13 +version.
  14 +
  15 +In addition to the permissions in the GNU General Public License, the
  16 +Free Software Foundation gives you unlimited permission to link the
  17 +compiled version of this file into combinations with other programs,
  18 +and to distribute those combinations without any restriction coming
  19 +from the use of this file. (The General Public License restrictions
  20 +do apply in other respects; for example, they cover modification of
  21 +the file, and distribution when not linked into a combine
  22 +executable.)
  23 +
  24 +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  25 +WARRANTY; without even the implied warranty of MERCHANTABILITY or
  26 +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  27 +for more details.
  28 +
  29 +You should have received a copy of the GNU General Public License
  30 +along with GCC; see the file COPYING. If not, write to the Free
  31 +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
  32 +02110-1301, USA. */
  33 +
  34 +/*
  35 + * Implementations of floating-point long double basic arithmetic
  36 + * functions called by the IBM C compiler when generating code for
  37 + * PowerPC platforms. In particular, the following functions are
  38 + * implemented: __gcc_qadd, __gcc_qsub, __gcc_qmul, and __gcc_qdiv.
  39 + * Double-double algorithms are based on the paper "Doubled-Precision
  40 + * IEEE Standard 754 Floating-Point Arithmetic" by W. Kahan, February 26,
  41 + * 1987. An alternative published reference is "Software for
  42 + * Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa,
  43 + * ACM TOMS vol 7 no 3, September 1981, pages 272-283.
  44 + */
  45 +
  46 +/*
  47 + * Each long double is made up of two IEEE doubles. The value of the
  48 + * long double is the sum of the values of the two parts. The most
  49 + * significant part is required to be the value of the long double
  50 + * rounded to the nearest double, as specified by IEEE. For Inf
  51 + * values, the least significant part is required to be one of +0.0 or
  52 + * -0.0. No other requirements are made; so, for example, 1.0 may be
  53 + * represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
  54 + * NaN is don't-care.
  55 + *
  56 + * This code currently assumes big-endian.
  57 + */
  58 +
  59 +#define fabs(x) __builtin_fabs(x)
  60 +#define isless(x, y) __builtin_isless(x, y)
  61 +#define inf() __builtin_inf()
  62 +#define unlikely(x) __builtin_expect((x), 0)
  63 +#define nonfinite(a) unlikely(!isless(fabs(a), inf()))
  64 +
  65 +typedef union {
  66 + long double ldval;
  67 + double dval[2];
  68 +} longDblUnion;
  69 +
  70 +/* Add two 'long double' values and return the result. */
  71 +long double __gcc_qadd(double a, double aa, double c, double cc)
  72 +{
  73 + longDblUnion x;
  74 + double z, q, zz, xh;
  75 +
  76 + z = a + c;
  77 +
  78 + if (nonfinite(z)) {
  79 + z = cc + aa + c + a;
  80 + if (nonfinite(z))
  81 + return z;
  82 + x.dval[0] = z; /* Will always be DBL_MAX. */
  83 + zz = aa + cc;
  84 + if (fabs(a) > fabs(c))
  85 + x.dval[1] = a - z + c + zz;
  86 + else
  87 + x.dval[1] = c - z + a + zz;
  88 + } else {
  89 + q = a - z;
  90 + zz = q + c + (a - (q + z)) + aa + cc;
  91 +
  92 + /* Keep -0 result. */
  93 + if (zz == 0.0)
  94 + return z;
  95 +
  96 + xh = z + zz;
  97 + if (nonfinite(xh))
  98 + return xh;
  99 +
  100 + x.dval[0] = xh;
  101 + x.dval[1] = z - xh + zz;
  102 + }
  103 + return x.ldval;
  104 +}
  105 +
  106 +long double __gcc_qsub(double a, double b, double c, double d)
  107 +{
  108 + return __gcc_qadd(a, b, -c, -d);
  109 +}
  110 +
  111 +long double __gcc_qmul(double a, double b, double c, double d)
  112 +{
  113 + longDblUnion z;
  114 + double t, tau, u, v, w;
  115 +
  116 + t = a * c; /* Highest order double term. */
  117 +
  118 + if (unlikely(t == 0) /* Preserve -0. */
  119 + || nonfinite(t))
  120 + return t;
  121 +
  122 + /* Sum terms of two highest orders. */
  123 +
  124 + /* Use fused multiply-add to get low part of a * c. */
  125 +#ifndef __NO_FPRS__
  126 + asm("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
  127 +#else
  128 + tau = fmsub(a, c, t);
  129 +#endif
  130 + v = a * d;
  131 + w = b * c;
  132 + tau += v + w; /* Add in other second-order terms. */
  133 + u = t + tau;
  134 +
  135 + /* Construct long double result. */
  136 + if (nonfinite(u))
  137 + return u;
  138 + z.dval[0] = u;
  139 + z.dval[1] = (t - u) + tau;
  140 + return z.ldval;
  141 +}