Skip to content

Commit

Permalink
sh: Fix FPU tuning on toolchains with mismatched multilib targets.
Browse files Browse the repository at this point in the history
Presently there is very little standing in the way of using an SH-4
toolchain for building an SH-2 kernel, and vice versa. Binutils itself
has no limitations whatsoever and supports explicit ISA hinting, which
we already use with varying degrees of success today.

This leaves GCC as the odd one out, due to a rather dubious policy
decision by the GCC folks to not include all of the CPU family variants
in the default list of multilib targets in GCC4. Despite best efforts to
the contrary, libgcc itself already contains awareness of the various CPU
types and remains generally usable, allowing it to safely be referenced
even on a mismatched target (and indeed, explicit ISA tuning by binutils
keeps us honest in terms of ensuring that we do not link incompatible
objects in).

In order to support this, a couple of changes had to be made. Firstly,
the introduction of MAYBE_DECLARE_EXPORT(), which provides a __weak
extern reference for libgcc resident routines when finer-grained
-m<cpu-family> based tuning is not supported by the toolchain. This
fixes up the __sdivsi3_i4i and __udivsi3_i4i references when dealing
with SH-2 kernels linked with an SH-4 libgcc. Secondly, in case where we
are unable to find a suitable match for CPU family tuning but still
have a toolchain that defaults to FP instruction generation, a suitable
nofpu target must be selected. This is accomplished by selecting the
first nofpu multilib target supported by the toolchain, which is
also necessary for selecting the proper libgcc to link against.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Paul Mundt committed Oct 28, 2008
1 parent 49fdf67 commit 8a2fd5f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
16 changes: 16 additions & 0 deletions arch/sh/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \
$(call cc-option,-m4a-nofpu,)
cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,)

ifeq ($(cflags-y),)
#
# In the case where we are stuck with a compiler that has been uselessly
# restricted to a particular ISA, a favourite default of newer GCCs when
# extensive multilib targets are not provided, ensure we get the best fit
# regarding FP generation. This is necessary to avoid references to FP
# variants in libgcc where integer variants exist, which otherwise result
# in link errors. This is intentionally stupid (albeit many orders of
# magnitude less than GCC's default behaviour), as anything with a large
# number of multilib targets better have been built correctly for
# the target in mind.
#
cflags-y += $(shell $(CC) $(KBUILD_CFLAGS) -print-multi-lib | \
grep nofpu | sed q | sed -e 's/^/-/;s/;.*$$//')
endif

cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml

Expand Down
11 changes: 6 additions & 5 deletions arch/sh/kernel/sh_ksyms_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__ndelay);
EXPORT_SYMBOL(__const_udelay);

#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
#define DECLARE_EXPORT(name) \
extern void name(void);EXPORT_SYMBOL(name)
#define MAYBE_DECLARE_EXPORT(name) \
extern void name(void) __weak;EXPORT_SYMBOL(name)

/* These symbols are generated by the compiler itself */
DECLARE_EXPORT(__udivsi3);
Expand Down Expand Up @@ -109,10 +112,8 @@ DECLARE_EXPORT(__movmemSI12_i4);
* compiler which include backported patches.
*/
DECLARE_EXPORT(__udiv_qrnnd_16);
#if !defined(CONFIG_CPU_SH2)
DECLARE_EXPORT(__sdivsi3_i4i);
DECLARE_EXPORT(__udivsi3_i4i);
#endif
MAYBE_DECLARE_EXPORT(__sdivsi3_i4i);
MAYBE_DECLARE_EXPORT(__udivsi3_i4i);
#endif
#else /* GCC 3.x */
DECLARE_EXPORT(__movstr_i4_even);
Expand Down

0 comments on commit 8a2fd5f

Please sign in to comment.