diff mbox

powerpc64le-linux support

Message ID 20130505063930.GY5221@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra May 5, 2013, 6:39 a.m. UTC
This tidies endian selection.   Prior to this change, if you gave a
little-endian gcc the -mcall-aixdesc option, gcc would operate
big-endian but the assembler in little-endian.  Which was confusing to
say the least.

The sysv4.h changes below don't actually make any substantive changes
in the specs file, except to always add a default endian option to
ASM_SPEC.  I think that's wise given a bi-endian binutils can be built
with either endian default.  The linux64.h changes are a little more
substantive in order to cure the mixed endian problem.

The endian rules are:
a) Specify -mbig/-mlittle/-mbig-endian/-mlitte-endian and that's what
   you get, otherwise,
b) specify any of the -mcall options except the -mcall-sysv variants
   and you get an endian appropriate to the -mcall, mostly big,
   otherwise
c) you get the default endian for your toolchain which depends on
   configure options.

Something to consider for the future is making more of the -mcall
options endian agnostic, like -mcall-sysv.  Tested with a number of
powerpc ELF builds.

	* config/rs6000/sysv4.h (ENDIAN_SELECT): Define, extracted from
	(ASM_SPEC): ..here.  Emit DEFAULT_ASM_ENDIAN too.
	(DEFAULT_ASM_ENDIAN): Define.
	(CC1_SPEC, LINK_TARGET_SPEC): Use ENDIAN_SELECT.
	* config/rs6000/linux64.h (ASM_SPEC32): Remove endian options.
	Update -K PIC clause from sysv4.h.
	(ASM_SPEC_COMMON): Use ENDIAN_SELECT.
	(LINK_OS_LINUX_EMUL32, LINK_OS_LINUX_EMUL64): Likewise.

Comments

Joseph Myers May 5, 2013, 2:21 p.m. UTC | #1
On Sun, 5 May 2013, Alan Modra wrote:

> Something to consider for the future is making more of the -mcall
> options endian agnostic, like -mcall-sysv.  Tested with a number of
> powerpc ELF builds.

I'd like to suggest removing those -mcall-* options (as far as they affect 
specs, anyway).  No other architecture has that sort of arrangement of 
embedding specs for lots of different OSes into a single compiler driver, 
and I don't think that approach is any sort of useful partial progress 
towards generic multi-target compiler support.  Without this PowerPC 
peculiarity, I expect it would be possible to use config/gnu-user.h and 
config/linux.h the way all GNU/Linux architectures other than Alpha and 
PowerPC do, so eliminating an unnecessary source of complication in global 
changes.
David Edelsohn May 5, 2013, 3:16 p.m. UTC | #2
On Sun, May 5, 2013 at 10:21 AM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> On Sun, 5 May 2013, Alan Modra wrote:
>
>> Something to consider for the future is making more of the -mcall
>> options endian agnostic, like -mcall-sysv.  Tested with a number of
>> powerpc ELF builds.
>
> I'd like to suggest removing those -mcall-* options (as far as they affect
> specs, anyway).  No other architecture has that sort of arrangement of
> embedding specs for lots of different OSes into a single compiler driver,
> and I don't think that approach is any sort of useful partial progress
> towards generic multi-target compiler support.  Without this PowerPC
> peculiarity, I expect it would be possible to use config/gnu-user.h and
> config/linux.h the way all GNU/Linux architectures other than Alpha and
> PowerPC do, so eliminating an unnecessary source of complication in global
> changes.

The -mcall-* options are more about PPC eABI.

I'm also am hesitant to remove such a feature without a deprecation
round and the little-endian fixes cannot be delayed for the -mcall-*
options to be deprecated.

I do not have a strong desire to keep them, but I don't think we can drop them.

I suspect that -mcall-*bsd and -mcall-aixdesc can be removed, but
there may be uses of -mcall-linux and -mcall-sysv related to eABI.

Thanks, David
Joseph Myers May 5, 2013, 8:26 p.m. UTC | #3
On Sun, 5 May 2013, David Edelsohn wrote:

> The -mcall-* options are more about PPC eABI.

Where the options are about changing the function-calling ABI, I don't 
think they cause problems.  It's the way the options make spec handling 
different from other architectures that's problematic, and there are 
enough differences not covered by them that I doubt linking objects for 
one OS using a compiler built for another is actually going to work well.
diff mbox

Patch

Index: gcc/config/rs6000/sysv4.h
===================================================================
--- gcc/config/rs6000/sysv4.h	(revision 198274)
+++ gcc/config/rs6000/sysv4.h	(working copy)
@@ -517,19 +523,28 @@ 
   while (0)
 #endif
 
+/* Select one of BIG_OPT, LITTLE_OPT or DEFAULT_OPT depending
+   on various -mbig, -mlittle and -mcall- options.  */
+#define ENDIAN_SELECT(BIG_OPT, LITTLE_OPT, DEFAULT_OPT)	\
+"%{mlittle|mlittle-endian:"	LITTLE_OPT ";"	\
+  "mbig|mbig-endian:"		BIG_OPT    ";"	\
+  "mcall-aixdesc|mcall-freebsd|mcall-netbsd|"	\
+  "mcall-openbsd|mcall-linux:"	BIG_OPT    ";"	\
+  "mcall-i960-old:"		LITTLE_OPT ";"	\
+  ":"				DEFAULT_OPT "}"
+
+#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
+#define DEFAULT_ASM_ENDIAN " -mlittle"
+#else
+#define DEFAULT_ASM_ENDIAN " -mbig"
+#endif
+
 #undef	ASM_SPEC
 #define	ASM_SPEC "%(asm_cpu) \
 %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \
 %{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
-%{memb|msdata=eabi: -memb} \
-%{mlittle|mlittle-endian:-mlittle; \
-  mbig|mbig-endian      :-mbig;    \
-  mcall-aixdesc |		   \
-  mcall-freebsd |		   \
-  mcall-netbsd  |		   \
-  mcall-openbsd |		   \
-  mcall-linux           :-mbig;    \
-  mcall-i960-old        :-mlittle}"
+%{memb|msdata=eabi: -memb}" \
+ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
 
 #define	CC1_ENDIAN_BIG_SPEC ""
 
@@ -547,17 +562,10 @@ 
 #endif
 
 /* Pass -G xxx to the compiler and set correct endian mode.  */
-#define	CC1_SPEC "%{G*} %(cc1_cpu) \
-%{mlittle|mlittle-endian: %(cc1_endian_little);           \
-  mbig   |mbig-endian   : %(cc1_endian_big);              \
-  mcall-aixdesc |					  \
-  mcall-freebsd |					  \
-  mcall-netbsd  |					  \
-  mcall-openbsd |					  \
-  mcall-linux           : -mbig %(cc1_endian_big);        \
-  mcall-i960-old        : -mlittle %(cc1_endian_little);  \
-                        : %(cc1_endian_default)}          \
-%{meabi: %{!mcall-*: -mcall-sysv }} \
+#define	CC1_SPEC "%{G*} %(cc1_cpu)" \
+  ENDIAN_SELECT(" %(cc1_endian_big)", " %(cc1_endian_little)",	\
+		" %(cc1_endian_default)")			\
+"%{meabi: %{!mcall-*: -mcall-sysv }} \
 %{!meabi: %{!mno-eabi: \
     %{mrelocatable: -meabi } \
     %{mcall-freebsd: -mno-eabi } \
@@ -601,11 +609,8 @@ 
 %{symbolic:-Bsymbolic -G -dy -z text }"
 
 /* Override the default target of the linker.  */
-#define	LINK_TARGET_SPEC "\
-%{mlittle: --oformat elf32-powerpcle } %{mlittle-endian: --oformat elf32-powerpcle } \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
-    %{mcall-i960-old: --oformat elf32-powerpcle} \
-  }}}}"
+#define	LINK_TARGET_SPEC \
+  ENDIAN_SELECT("", " --oformat elf32-powerpcle", "")
 
 /* Any specific OS flags.  */
 #define LINK_OS_SPEC "\
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h	(revision 198274)
+++ gcc/config/rs6000/linux64.h	(working copy)
@@ -180,20 +183,14 @@ 
 #endif
 
 #define ASM_SPEC32 "-a32 \
-%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
-%{memb} %{!memb: %{msdata=eabi: -memb}} \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
-    %{mcall-freebsd: -mbig} \
-    %{mcall-i960-old: -mlittle} \
-    %{mcall-linux: -mbig} \
-    %{mcall-netbsd: -mbig} \
-}}}}"
+%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
+%{memb|msdata=eabi: -memb}"
 
 #define ASM_SPEC64 "-a64"
 
 #define ASM_SPEC_COMMON "%(asm_cpu) \
-%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
+  ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
 
 #undef	SUBSUBTARGET_EXTRA_SPECS
 #define SUBSUBTARGET_EXTRA_SPECS \
@@ -373,11 +376,19 @@ 
   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64)
 
 #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
-#define LINK_OS_LINUX_EMUL32 "%{!mbig: %{!mbig-endian: -m elf32lppclinux}}%{mbig|mbig-endian: -m elf32ppclinux}"
-#define LINK_OS_LINUX_EMUL64 "%{!mbig: %{!mbig-endian: -m elf64lppc}}%{mbig|mbig-endian: -m elf64ppc}"
+#define LINK_OS_LINUX_EMUL32 ENDIAN_SELECT(" -m elf32ppclinux",		\
+					   " -m elf32lppclinux",	\
+					   " -m elf32lppclinux")
+#define LINK_OS_LINUX_EMUL64 ENDIAN_SELECT(" -m elf64ppc",		\
+					   " -m elf64lppc",		\
+					   " -m elf64lppc")
 #else
-#define LINK_OS_LINUX_EMUL32 "%{!mlittle: %{!mlittle-endian: -m elf32ppclinux}}%{mlittle|mlittle-endian: -m elf32lppclinux}"
-#define LINK_OS_LINUX_EMUL64 "%{!mlittle: %{!mlittle-endian: -m elf64ppc}}%{mlittle|mlittle-endian: -m elf64lppc}"
+#define LINK_OS_LINUX_EMUL32 ENDIAN_SELECT(" -m elf32ppclinux",		\
+					   " -m elf32lppclinux",	\
+					   " -m elf32ppclinux")
+#define LINK_OS_LINUX_EMUL64 ENDIAN_SELECT(" -m elf64ppc",		\
+					   " -m elf64lppc",		\
+					   " -m elf64ppc")
 #endif
 
 #define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " %{!shared: %{!static: \