diff mbox

powerpc64le multilibs and multiarch dir

Message ID 20130822035750.GO3430@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Aug. 22, 2013, 3:57 a.m. UTC
This patch corrects the powerpc64le-linux multiarch directory, adds
opposite-endian multilibs, and chooses non-multiarch os dirs for the
new multilibs.

For multiarch, powerpc64le-linux now will use powerpc64le-linux-gnu.
Given a typical big-endian native toolchain with os dirs /lib and
/lib64, we'll use /lible and /lib64le if supporting little-endian as
well.  If you happen to use /lib and /lib32, then the little-endian
variants are /lible and /lib32le.  For completeness I also support
building big-endian multilibs on a little-endian host.

All of this is done with a dose of "make" string manipulation
functions guaranteed to make your eye glaze over, but there are just
too many combinations of different configurations to simply
enumerate them all.  I use ':=' assignment for the multilib make
variables because you can't have a recursively evaluated variable
(ie. one assigned with '=') reference itself, as is done with
MULTILIB_OSDIRNAMES, and we may as well use the same for all the
multilib vars.

I also remove fPIC from MULTILIB_EXTRA_OPTS because -fPIC is already
added where necessary by the library Makefiles.  Also,
MULTILIB_EXTRA_OPTS is only for options that apply to the non-default
multilibs.  It isn't used for the default multilib, so this isn't the
place to put options common to all multilibs.  (I've been building
gcc with this particular change for years.)

Bootstrapped and regression tested powerpc64-linux.  OK for mainline
and 4.8?

	* config.gcc (powerpc*-*-linux*): Add support for little-endian
	multilibs to big-endian target and vice versa.
	* config/rs6000/t-linux64: Use := assignment on all vars.
	(MULTILIB_EXTRA_OPTS): Remove fPIC.
	(MULTILIB_OSDIRNAMES): Specify using mapping from multilib_options.
	* config/rs6000/t-linux64le: New file.
	* config/rs6000/t-linux64bele: New file.
	* config/rs6000/t-linux64lebe: New file.

Comments

David Edelsohn Aug. 22, 2013, 2:06 p.m. UTC | #1
On Wed, Aug 21, 2013 at 11:57 PM, Alan Modra <amodra@gmail.com> wrote:

> Index: gcc/config/rs6000/t-linux64
> ===================================================================
> --- gcc/config/rs6000/t-linux64 (revision 201834)
> +++ gcc/config/rs6000/t-linux64 (working copy)
> @@ -25,8 +25,8 @@
>  # it doesn't tell anything about the 32bit libraries on those systems.  Set
>  # MULTILIB_OSDIRNAMES according to what is found on the target.
>
> -MULTILIB_OPTIONS        = m64/m32
> -MULTILIB_DIRNAMES       = 64 32
> -MULTILIB_EXTRA_OPTS     = fPIC
> -MULTILIB_OSDIRNAMES    = ../lib64$(call if_multiarch,:powerpc64-linux-gnu)
> -MULTILIB_OSDIRNAMES    += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
> +MULTILIB_OPTIONS    := m64/m32
> +MULTILIB_DIRNAMES   := 64 32
> +MULTILIB_EXTRA_OPTS :=
> +MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
> +MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)

What is the purpose of the change to MULTILIB_OSDIRNAMES? Why the
addition of m64= and m32=? A secondary tmake file is not always set to
post-process those macros, AFAICT.

Thanks, David
Alan Modra Aug. 22, 2013, 4:15 p.m. UTC | #2
On Thu, Aug 22, 2013 at 10:06:48AM -0400, David Edelsohn wrote:
> On Wed, Aug 21, 2013 at 11:57 PM, Alan Modra <amodra@gmail.com> wrote:
> 
> > Index: gcc/config/rs6000/t-linux64
> > ===================================================================
> > --- gcc/config/rs6000/t-linux64 (revision 201834)
> > +++ gcc/config/rs6000/t-linux64 (working copy)
> > @@ -25,8 +25,8 @@
> >  # it doesn't tell anything about the 32bit libraries on those systems.  Set
> >  # MULTILIB_OSDIRNAMES according to what is found on the target.
> >
> > -MULTILIB_OPTIONS        = m64/m32
> > -MULTILIB_DIRNAMES       = 64 32
> > -MULTILIB_EXTRA_OPTS     = fPIC
> > -MULTILIB_OSDIRNAMES    = ../lib64$(call if_multiarch,:powerpc64-linux-gnu)
> > -MULTILIB_OSDIRNAMES    += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
> > +MULTILIB_OPTIONS    := m64/m32
> > +MULTILIB_DIRNAMES   := 64 32
> > +MULTILIB_EXTRA_OPTS :=
> > +MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
> > +MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
> 
> What is the purpose of the change to MULTILIB_OSDIRNAMES? Why the
> addition of m64= and m32=? A secondary tmake file is not always set to
> post-process those macros, AFAICT.

That m64= is the newer syntax that specifies a mapping from a
MUTLILIB_OPTIONS selection.  And, yes, without another tmake file this
gives us exactly the same result as before.

I needed to use the new syntax to specify the correct os dirs when
adding cross-endian multilibs.
Alan Modra Aug. 22, 2013, 11:15 p.m. UTC | #3
On Fri, Aug 23, 2013 at 01:45:14AM +0930, Alan Modra wrote:
> On Thu, Aug 22, 2013 at 10:06:48AM -0400, David Edelsohn wrote:
> > What is the purpose of the change to MULTILIB_OSDIRNAMES? Why the
> > addition of m64= and m32=? A secondary tmake file is not always set to
> > post-process those macros, AFAICT.
> 
> That m64= is the newer syntax that specifies a mapping from a
> MUTLILIB_OPTIONS selection.  And, yes, without another tmake file this
> gives us exactly the same result as before.
> 
> I needed to use the new syntax to specify the correct os dirs when
> adding cross-endian multilibs.

Without another tmake file it really is exactly the same as before.

old, after applying "make" string gunk
MULTILIB_OPTIONS = m64/m32
MULTILIB_OSDIRNAMES = ../lib64 ../lib

new
MULTILIB_OPTIONS = m64/m32
MULTILIB_OSDIRNAMES = m64=../lib64 m32=../lib

Either way, -m64 objects use ../lib64 and -m32 ../lib.


new with le multilib
MULTILIB_OPTIONS = m64/m32 mlittle
MULTILIB_OSDIRNAMES = m64=../lib64 m32=../lib m64.mlittle=../lib64le m32.mlittle=../lible

Trying to do the same with the old syntax isn't possible, because you
must specify 3 elements in MULTILIB_OSDIRNAMES to match the
combinations given in MULTILIB_OPTIONS, then the multilib machinery
mashes them together.  For instance

MULTILIB_OPTIONS = m64/m32 le
MULTILIB_OSDIRNAMES = ../lib64 ../lib le

results in
-m64 code to ../lib64
-m32 code to ../lib
-m64 -mlittle code to le
-m32 -mlittle code to ../lible

The reason you don't get ../lib64le for -m64 -mlittle is related to
-m64 being the default, -m64 is therefore omitted when compiling, and
just the "le" string used for the os multilib dir.
David Edelsohn Aug. 23, 2013, 3:21 p.m. UTC | #4
On Thu, Aug 22, 2013 at 7:15 PM, Alan Modra <amodra@gmail.com> wrote:

> Without another tmake file it really is exactly the same as before.
>
> old, after applying "make" string gunk
> MULTILIB_OPTIONS = m64/m32
> MULTILIB_OSDIRNAMES = ../lib64 ../lib
>
> new
> MULTILIB_OPTIONS = m64/m32
> MULTILIB_OSDIRNAMES = m64=../lib64 m32=../lib
>
> Either way, -m64 objects use ../lib64 and -m32 ../lib.
>
>
> new with le multilib
> MULTILIB_OPTIONS = m64/m32 mlittle
> MULTILIB_OSDIRNAMES = m64=../lib64 m32=../lib m64.mlittle=../lib64le m32.mlittle=../lible

Okay, I see how it's duplicating the meaning of the positional arguments.

The patch is okay.

Thanks, David
Joseph Myers Aug. 23, 2013, 9:41 p.m. UTC | #5
On Thu, 22 Aug 2013, Alan Modra wrote:

> For multiarch, powerpc64le-linux now will use powerpc64le-linux-gnu.
> Given a typical big-endian native toolchain with os dirs /lib and
> /lib64, we'll use /lible and /lib64le if supporting little-endian as
> well.  If you happen to use /lib and /lib32, then the little-endian
> variants are /lible and /lib32le.  For completeness I also support
> building big-endian multilibs on a little-endian host.

Given those directory names, what are the defined dynamic linker paths for 
32-bit and 64-bit little-endian (which can't depend on which of the 
various directory arrangements may be in use)?

Does the Power Architecture support, in principle, a single system running 
both big-endian and little-endian processes at the same time, or is it a 
matter of hardware configuration or boot-time setup?  Unless both can run 
at once, it doesn't seem particularly useful to define separate 
directories for big and little endian since a particular system would be 
just one or the other.  Other architectures don't define separate 
directory names for endianness variants unless multiarch naming 
conventions are in use.

(ARM does support having processes with both endiannesses - indeed, a 
process can change its own endianness with the unprivileged SETEND 
instruction (deprecated in ARMv8) - although the Linux kernel has no 
support for this the last time I checked, and big-endian ARM is rarely 
used.)
Alan Modra Aug. 26, 2013, 3:32 a.m. UTC | #6
On Fri, Aug 23, 2013 at 09:41:28PM +0000, Joseph S. Myers wrote:
> On Thu, 22 Aug 2013, Alan Modra wrote:
> 
> > For multiarch, powerpc64le-linux now will use powerpc64le-linux-gnu.
> > Given a typical big-endian native toolchain with os dirs /lib and
> > /lib64, we'll use /lible and /lib64le if supporting little-endian as
> > well.  If you happen to use /lib and /lib32, then the little-endian
> > variants are /lible and /lib32le.  For completeness I also support
> > building big-endian multilibs on a little-endian host.
> 
> Given those directory names, what are the defined dynamic linker paths for 
> 32-bit and 64-bit little-endian (which can't depend on which of the 
> various directory arrangements may be in use)?

We haven't defined the little-endian ld.so variants yet.

> Does the Power Architecture support, in principle, a single system running 
> both big-endian and little-endian processes at the same time

It does.  

>, or is it a 
> matter of hardware configuration or boot-time setup?  Unless both can run 
> at once, it doesn't seem particularly useful to define separate 
> directories for big and little endian since a particular system would be 
> just one or the other.

We (IBM) don't intend to support running both big and little-endian
processes on the same system in the near future.  Perhaps I'm jumping
the gun in defining the multi-os dirs like /lible and /lib64le.  I did
that to make it easier for people ideologically opposed to multiarch
to set up a native powerpc64 compiler that supports both big and
little-endian compilation.  I know the multi-os dirs aren't strictly
needed to do that..  Should I not be defining them yet?
Mike Stump Aug. 26, 2013, 5:40 a.m. UTC | #7
On Aug 25, 2013, at 8:32 PM, Alan Modra <amodra@gmail.com> wrote:
> We (IBM) don't intend to support running both big and little-endian
> processes on the same system in the near future.  Perhaps I'm jumping
> the gun in defining the multi-os dirs like /lible and /lib64le.

I'd recommend against multilibs, unless you have a need for them…  Life is much simpler (and faster).  The usual people to add them are, say the linux people that do a distribution that want to support both, at that point, they'll add it.

Sometimes one might add multilib to enable easier, faster testing.  On targets where there are small numbers of users and the developers want to do a multilib to make testing easier (build once, test twice).  One can have all the beef in the tree, with the multilib in comments.  Easy to turn on, if one wants, but you don't pay the price otherwise.
Alan Modra Aug. 26, 2013, 7:35 a.m. UTC | #8
On Sun, Aug 25, 2013 at 10:40:30PM -0700, Mike Stump wrote:
> On Aug 25, 2013, at 8:32 PM, Alan Modra <amodra@gmail.com> wrote:
> > We (IBM) don't intend to support running both big and little-endian
> > processes on the same system in the near future.  Perhaps I'm jumping
> > the gun in defining the multi-os dirs like /lible and /lib64le.
> 
> I'd recommend against multilibs, unless you have a need for them…

These multlibs are only added if you ask for them via --enable-targets.
diff mbox

Patch

Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 201834)
+++ gcc/config.gcc	(working copy)
@@ -2139,7 +2139,7 @@ 
 	tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
 	case ${target} in
 	    powerpc*le-*-*)
-	    tm_file="${tm_file} rs6000/sysv4le.h" ;;
+		tm_file="${tm_file} rs6000/sysv4le.h" ;;
 	esac
 	maybe_biarch=yes
 	case ${target} in
@@ -2162,6 +2162,19 @@ 
 		fi
 		tm_file="rs6000/biarch64.h ${tm_file} rs6000/linux64.h glibc-stdint.h"
 		tmake_file="$tmake_file rs6000/t-linux64"
+		case ${target} in
+		    powerpc*le-*-*)
+			tmake_file="$tmake_file rs6000/t-linux64le"
+			case ${enable_targets} in
+			    all | *powerpc64-* | *powerpc-*)
+				tmake_file="$tmake_file rs6000/t-linux64lebe" ;;
+			esac ;;
+		    *)
+			case ${enable_targets} in
+			    all | *powerpc64le-* | *powerpcle-*)
+				tmake_file="$tmake_file rs6000/t-linux64bele" ;;
+			esac ;;
+		esac
 		extra_options="${extra_options} rs6000/linux64.opt"
 		;;
 	    *)
Index: gcc/config/rs6000/t-linux64
===================================================================
--- gcc/config/rs6000/t-linux64	(revision 201834)
+++ gcc/config/rs6000/t-linux64	(working copy)
@@ -25,8 +25,8 @@ 
 # it doesn't tell anything about the 32bit libraries on those systems.  Set
 # MULTILIB_OSDIRNAMES according to what is found on the target.
 
-MULTILIB_OPTIONS        = m64/m32
-MULTILIB_DIRNAMES       = 64 32
-MULTILIB_EXTRA_OPTS     = fPIC
-MULTILIB_OSDIRNAMES	= ../lib64$(call if_multiarch,:powerpc64-linux-gnu)
-MULTILIB_OSDIRNAMES    += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
+MULTILIB_OPTIONS    := m64/m32
+MULTILIB_DIRNAMES   := 64 32
+MULTILIB_EXTRA_OPTS := 
+MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
+MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
Index: gcc/config/rs6000/t-linux64le
===================================================================
--- gcc/config/rs6000/t-linux64le	(revision 0)
+++ gcc/config/rs6000/t-linux64le	(revision 0)
@@ -0,0 +1,3 @@ 
+#rs6000/t-linux64le
+
+MULTILIB_OSDIRNAMES = $(subst -linux,le-linux,$(MULTILIB_OSDIRNAMES))
Index: gcc/config/rs6000/t-linux64bele
===================================================================
--- gcc/config/rs6000/t-linux64bele	(revision 0)
+++ gcc/config/rs6000/t-linux64bele	(revision 0)
@@ -0,0 +1,7 @@ 
+#rs6000/t-linux64end
+
+MULTILIB_OPTIONS    += mlittle
+MULTILIB_DIRNAMES   += le
+MULTILIB_OSDIRNAMES += $(subst =,.mlittle=,$(subst lible32,lib32le,$(subst lible64,lib64le,$(subst lib,lible,$(subst -linux,le-linux,$(MULTILIB_OSDIRNAMES))))))
+MULTILIB_OSDIRNAMES += $(subst $(if $(findstring 64,$(target)),m64,m32).,,$(filter $(if $(findstring 64,$(target)),m64,m32).mlittle%,$(MULTILIB_OSDIRNAMES)))
+MULTILIB_MATCHES    := ${MULTILIB_MATCHES_ENDIAN}
Index: gcc/config/rs6000/t-linux64lebe
===================================================================
--- gcc/config/rs6000/t-linux64lebe	(revision 0)
+++ gcc/config/rs6000/t-linux64lebe	(revision 0)
@@ -0,0 +1,7 @@ 
+#rs6000/t-linux64leend
+
+MULTILIB_OPTIONS    += mbig
+MULTILIB_DIRNAMES   += be
+MULTILIB_OSDIRNAMES += $(subst =,.mbig=,$(subst libbe32,lib32be,$(subst libbe64,lib64be,$(subst lib,libbe,$(subst le-linux,-linux,$(MULTILIB_OSDIRNAMES))))))
+MULTILIB_OSDIRNAMES += $(subst $(if $(findstring 64,$(target)),m64,m32).,,$(filter $(if $(findstring 64,$(target)),m64,m32).mbig%,$(MULTILIB_OSDIRNAMES)))
+MULTILIB_MATCHES    := ${MULTILIB_MATCHES_ENDIAN}