public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
@ 2013-11-11 14:48 Ulrich Weigand
  2013-11-11 15:08 ` Ulrich Weigand
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-11 14:48 UTC (permalink / raw)
  To: gcc-patches

Hello,

this is the first patch in the series to add support for the ELFv2 ABI.

The ELFv2 ABI is the intended ABI for the new powerpc64le-linux port.
However, it is not inherently tied to the byte order; it it possible
in principle to use the ELFv2 ABI in big-endian mode too.

Therefore, it is introduces via a new pair of options
   -mabi=elfv1 / -mabi=elfv2
where -mabi=elfv1 select the current Linux ABI, and -mabi=elfv2
selects the new one.

If neither option is given, the compiler defaults to whatever ABI
was specified at configure time using the
   --with-abi=elfv1 / --with-abi=elfv2
configure option.

If this was not specified either, every subtarget can provide a
master default by defining (or not) the LINUX64_DEFAULT_ABI_ELFv2
macro.

The patch series is structured as follows:

- This first patch adds the new enum rs6000_abi value ABI_ELFv2
  and all the configure logic needed to set it.  It is treated
  just like ABI_AIX (on a modern system) at this point; no change
  in generated code is expected yet.

- A series of follow on patches will add the various features
  defining the ELFv2 ABI.  Note that they will still not be
  active by default anywhere.

- The final patch will simply turn the switch to make ELFv2
  the default ABI on powerpc64le-linux.

The whole series was tested on:

  - powerpc64-linux with no regression, including no regression
    in an ALT_CC_UNDER_TEST/ALT_CXX_UNDER_TEST run of compat.exp
    and struct-layout-1.exp against a current compiler.

  - powerpc64-linux --with-abi=elfv2 in mock-up big-endian ELFv2
    environment running with some hacks on an existing system.

  - powerpc64le-linux, using the new default ELFv2 in a rebuilt
    small OS image using the new ABI everywhere.
 
(Of course, patches to binutils, glibc, and libffi to support the
new ELFv2 ABI are also required.)

The tests were using all languages (including Java, Go, and
Objective-C++; on powerpc64le-linux also Ada), and all target
libraries except libsanitizer (which currently seems broken
on mainline).

There is a small number of regressions on powerpc64le-linux
which seem to be due to unrelated issues:

- FAIL: g++.dg/cpp1y/vla-initlist1.C execution test
  This is an invalid assumption in the test case

- FAIL: go.test/test/fixedbugs/bug296.go execution,  -O2 -g
  The ELFv2 ABI  seems to be exposing a Go frontend bug here

- FAIL: runtime/pprof   (in libgo)
  This is due to a glibc problem with unwinding through a
  context created via makecontext

I'll address those separately.  (Of course, there are also
other pre-existing regressions on powerpc64le-linux simply
due to little-endian issues.  Those are unaffected by ELFv2.)


I'll add more detailed descriptions of the actual ABI features
with the various follow-on patches that implement those.

This patch specifically only adds the options as described above.
ABI_ELFv2 is implemented to be equivalent to ABI_AIX on a modern
system; since the ABI is new, there is no need to continue to
support legacy features.  This means specifically:
- DOT_SYMBOLS is assumed to be false
- rs6000_compat_align_parm is assumed to be false
- code in linux-unwind.h that handles old kernels/linkers is removed

The patch also adds two new pre-defined macros:
- _CALL_ELF is set to 1 or 2 to denote the ELFv1 / ELFv2 ABI
- __STRUCT_PARM_ALIGN__ is set to 16 if aggregates passed by value
  are aligned to 16 if their native alignment requires that
  (this is necessary to implement libffi, for example)

In addition, the patch adds a testsuite effective target check
for the ELFv2 ABI, and disables the pr57949 tests (these verify
the operation of the -mcompat-align-parm option, which is no
longer useful in the ELFv2 ABI).


To avoid having a partial ABI implementation in tree, it seems best
to commit this whole patch series as a single commit.

Is the series OK for mainline?

Bye,
Ulrich




gcc/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config.gcc [powerpc*-*-* | rs6000-*-*]: Support --with-abi=elfv1
	and --with-abi=elfv2.
	* config/rs6000/option-defaults.h (OPTION_DEFAULT_SPECS): Add "abi".
	* config/rs6000/rs6000.opt (mabi=elfv1): New option.
	(mabi=elfv2): Likewise.
	* config/rs6000/rs6000-opts.h (enum rs6000_abi): Add ABI_ELFv2.
	* config/rs6000/linux64.h (DEFAULT_ABI): Do not hard-code to AIX_ABI
	if !RS6000_BI_ARCH.
	(ELFv2_ABI_CHECK): New macro.
	(SUBSUBTARGET_OVERRIDE_OPTIONS): Use it to decide whether to set
	rs6000_current_abi to ABI_AIX or ABI_ELFv2.
	(GLIBC_DYNAMIC_LINKER64): Support ELFv2 ld.so version.
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Predefine
	_CALL_ELF and __STRUCT_PARM_ALIGN__ if appropriate.

	* config/rs6000/rs6000.c (rs6000_debug_reg_global): Handle ABI_ELFv2.
	(debug_stack_info): Likewise.
	(rs6000_file_start): Treat ABI_ELFv2 the same as ABI_AIX.
	(rs6000_legitimize_tls_address): Likewise.
	(rs6000_conditional_register_usage): Likewise.
	(rs6000_emit_move): Likewise.
	(init_cumulative_args): Likewise.
	(rs6000_function_arg_advance_1): Likewise.
	(rs6000_function_arg): Likewise.
	(rs6000_arg_partial_bytes): Likewise.
	(rs6000_output_function_entry): Likewise.
	(rs6000_assemble_integer): Likewise.
	(rs6000_savres_strategy): Likewise.
	(rs6000_stack_info): Likewise.
	(rs6000_function_ok_for_sibcall): Likewise.
	(rs6000_emit_load_toc_table): Likewise.
	(rs6000_savres_routine_name): Likewise.
	(ptr_regno_for_savres): Likewise.
	(rs6000_emit_prologue): Likewise.
	(rs6000_emit_epilogue): Likewise.
	(rs6000_output_function_epilogue): Likewise.
	(output_profile_hook): Likewise.
	(output_function_profiler): Likewise.
	(rs6000_trampoline_size): Likewise.
	(rs6000_trampoline_init): Likewise.
	(rs6000_elf_output_toc_section_asm_op): Likewise.
	(rs6000_elf_encode_section_info): Likewise.
	(rs6000_elf_reloc_rw_mask): Likewise.
	(rs6000_elf_declare_function_name): Likewise.
	(rs6000_function_arg_boundary): Treat ABI_ELFv2 the same as ABI_AIX,
	except that rs6000_compat_align_parm is always assumed false.
	(rs6000_gimplify_va_arg): Likewise.
	(rs6000_call_aix): Update comment.
	(rs6000_sibcall_aix): Likewise.
	* config/rs6000/rs6000.md ("tls_gd_aix<TLSmode:tls_abi_suffix>"):
	Treat ABI_ELFv2 the same as ABI_AIX.
	("*tls_gd_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
	("tls_ld_aix<TLSmode:tls_abi_suffix>"): Likewise.
	("*tls_ld_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
	("load_toc_aix_si"): Likewise.
	("load_toc_aix_di"): Likewise.
	("call"): Likewise.
	("call_value"): Likewise.
	("*call_local_aix<mode>"): Likewise.
	("*call_value_local_aix<mode>"): Likewise.
	("*call_nonlocal_aix<mode>"): Likewise.
	("*call_value_nonlocal_aix<mode>"): Likewise.
	("*call_indirect_aix<mode>"): Likewise.
	("*call_value_indirect_aix<mode>"): Likewise.
	("sibcall"): Likewise.
	("sibcall_value"): Likewise.
	("*sibcall_aix<mode>"): Likewise.
	("*sibcall_value_aix<mode>"): Likewise.
	* config/rs6000/predicates.md ("symbol_ref_operand"): Likewise.
	("current_file_function_operand"): Likewise.

libgcc/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
	    Alan Modra  <amodra@gmail.com>

	* config/rs6000/linux-unwind.h (get_regs): Do not support
	old kernel versions if _CALL_ELF == 2.
	(frob_update_context): Do not support PLT stub variants only
	generated by old linkers if _CALL_ELF == 2.

gcc/testsuite/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* lib/target-supports.exp (check_effective_target_powerpc_elfv2):
	New function.
	* gcc.target/powerpc/pr57949-1.c: Disable for powerpc_elfv2.
	* gcc.target/powerpc/pr57949-2.c: Likewise.


Index: gcc/gcc/config.gcc
===================================================================
--- gcc.orig/gcc/config.gcc
+++ gcc/gcc/config.gcc
@@ -3805,7 +3805,7 @@ case "${target}" in
 		;;
 
 	powerpc*-*-* | rs6000-*-*)
-		supported_defaults="cpu cpu_32 cpu_64 float tune tune_32 tune_64"
+		supported_defaults="abi cpu cpu_32 cpu_64 float tune tune_32 tune_64"
 
 		for which in cpu cpu_32 cpu_64 tune tune_32 tune_64; do
 			eval "val=\$with_$which"
@@ -3842,6 +3842,16 @@ case "${target}" in
 				;;
 			esac
 		done
+
+		case "$with_abi" in
+		"" | elfv1 | elfv2 )
+			#OK
+			;;
+		*)
+			echo "Unknown ABI used in --with-abi=$with_abi"
+			exit 1
+			;;
+		esac
 		;;
 
 	s390*-*-*)
Index: gcc/gcc/config/rs6000/option-defaults.h
===================================================================
--- gcc.orig/gcc/config/rs6000/option-defaults.h
+++ gcc/gcc/config/rs6000/option-defaults.h
@@ -54,6 +54,7 @@
    --with-float is ignored if -mhard-float or -msoft-float are
      specified.  */
 #define OPTION_DEFAULT_SPECS \
+  {"abi", "%{!mabi=elfv*:-mabi=%(VALUE)}" }, \
   {"tune", "%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}" }, \
   {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \
   {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \
Index: gcc/gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.opt
+++ gcc/gcc/config/rs6000/rs6000.opt
@@ -369,6 +369,14 @@ mabi=no-spe
 Target RejectNegative Var(rs6000_spe_abi, 0)
 Do not use the SPE ABI extensions
 
+mabi=elfv1
+Target RejectNegative Var(rs6000_elf_abi, 1) Save
+Use the ELFv1 ABI
+
+mabi=elfv2
+Target RejectNegative Var(rs6000_elf_abi, 2)
+Use the ELFv2 ABI
+
 ; These are here for testing during development only, do not document
 ; in the manual please.
 
Index: gcc/gcc/config/rs6000/rs6000-opts.h
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000-opts.h
+++ gcc/gcc/config/rs6000/rs6000-opts.h
@@ -107,7 +107,8 @@ enum group_termination
 /* Enumeration to give which calling sequence to use.  */
 enum rs6000_abi {
   ABI_NONE,
-  ABI_AIX,			/* IBM's AIX */
+  ABI_AIX,			/* IBM's AIX, or Linux ELFv1 */
+  ABI_ELFv2,			/* Linux ELFv2 ABI */
   ABI_V4,			/* System V.4/eabi */
   ABI_DARWIN			/* Apple's Darwin (OS X kernel) */
 };
Index: gcc/gcc/config/rs6000/linux64.h
===================================================================
--- gcc.orig/gcc/config/rs6000/linux64.h
+++ gcc/gcc/config/rs6000/linux64.h
@@ -25,9 +25,6 @@
 
 #ifndef RS6000_BI_ARCH
 
-#undef	DEFAULT_ABI
-#define	DEFAULT_ABI ABI_AIX
-
 #undef	TARGET_64BIT
 #define	TARGET_64BIT 1
 
@@ -88,6 +85,12 @@ extern int dot_symbols;
 #define INVALID_64BIT "-m%s not supported in this configuration"
 #define INVALID_32BIT INVALID_64BIT
 
+#ifdef LINUX64_DEFAULT_ABI_ELFv2
+#define ELFv2_ABI_CHECK (rs6000_elf_abi != 1)
+#else
+#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2)
+#endif
+
 #undef	SUBSUBTARGET_OVERRIDE_OPTIONS
 #define	SUBSUBTARGET_OVERRIDE_OPTIONS				\
   do								\
@@ -102,6 +105,12 @@ extern int dot_symbols;
 	      error (INVALID_64BIT, "call");			\
 	    }							\
 	  dot_symbols = !strcmp (rs6000_abi_name, "aixdesc");	\
+	  if (ELFv2_ABI_CHECK)					\
+	    {							\
+	      rs6000_current_abi = ABI_ELFv2;			\
+	      if (dot_symbols)					\
+		error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \
+	    }							\
 	  if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE)	\
 	    {							\
 	      rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;	\
@@ -355,7 +364,11 @@ extern int dot_symbols;
 #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
 
 #define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
+#ifdef LINUX64_DEFAULT_ABI_ELFv2
+#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
+#else
+#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
+#endif
 #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
 #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
 #if DEFAULT_LIBC == LIBC_UCLIBC
Index: gcc/gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000-c.c
+++ gcc/gcc/config/rs6000/rs6000-c.c
@@ -461,6 +461,10 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     case ABI_AIX:
       builtin_define ("_CALL_AIXDESC");
       builtin_define ("_CALL_AIX");
+      builtin_define ("_CALL_ELF=1");
+      break;
+    case ABI_ELFv2:
+      builtin_define ("_CALL_ELF=2");
       break;
     case ABI_DARWIN:
       builtin_define ("_CALL_DARWIN");
@@ -473,6 +477,13 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
   if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
     builtin_define ("__NO_FPRS__");
 
+  /* Whether aggregates passed by value are aligned to a 16 byte boundary
+     if their alignment is 16 bytes or larger.  */
+  if ((TARGET_MACHO && rs6000_darwin64_abi)
+      || DEFAULT_ABI == ABI_ELFv2
+      || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
+    builtin_define ("__STRUCT_PARM_ALIGN__=16");
+
   /* Generate defines for Xilinx FPU. */
   if (rs6000_xilinx_fpu) 
     {
Index: gcc/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.c
+++ gcc/gcc/config/rs6000/rs6000.c
@@ -2231,6 +2231,7 @@ rs6000_debug_reg_global (void)
     {
     case ABI_NONE:	abi_str = "none";	break;
     case ABI_AIX:	abi_str = "aix";	break;
+    case ABI_ELFv2:	abi_str = "ELFv2";	break;
     case ABI_V4:	abi_str = "V4";		break;
     case ABI_DARWIN:	abi_str = "darwin";	break;
     default:		abi_str = "unknown";	break;
@@ -4761,7 +4762,8 @@ rs6000_file_start (void)
 	putc ('\n', file);
     }
 
-  if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2
+      || (TARGET_ELF && flag_pic == 2))
     {
       switch_to_section (toc_section);
       switch_to_section (text_section);
@@ -6971,10 +6973,13 @@ rs6000_legitimize_tls_address (rtx addr,
 				   1, const0_rtx, Pmode);
 
 	  r3 = gen_rtx_REG (Pmode, 3);
-	  if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
-	    insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
-	  else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
-	    insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+	  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	    {
+	      if (TARGET_64BIT)
+		insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
+	      else
+		insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+	    }
 	  else if (DEFAULT_ABI == ABI_V4)
 	    insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
 	  else
@@ -6993,10 +6998,13 @@ rs6000_legitimize_tls_address (rtx addr,
 				   1, const0_rtx, Pmode);
 
 	  r3 = gen_rtx_REG (Pmode, 3);
-	  if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
-	    insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
-	  else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
-	    insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+	  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	    {
+	      if (TARGET_64BIT)
+		insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
+	      else
+		insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+	    }
 	  else if (DEFAULT_ABI == ABI_V4)
 	    insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
 	  else
@@ -7623,7 +7631,7 @@ rs6000_conditional_register_usage (void)
 
   /* The TOC register is not killed across calls in a way that is
      visible to the compiler.  */
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     call_really_used_regs[2] = 0;
 
   if (DEFAULT_ABI == ABI_V4
@@ -8274,7 +8282,7 @@ rs6000_emit_move (rtx dest, rtx source, 
 
 	  /* If this is a function address on -mcall-aixdesc,
 	     convert it to the address of the descriptor.  */
-	  if (DEFAULT_ABI == ABI_AIX
+	  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 	      && GET_CODE (operands[1]) == SYMBOL_REF
 	      && XSTR (operands[1], 0)[0] == '.')
 	    {
@@ -8665,7 +8673,7 @@ init_cumulative_args (CUMULATIVE_ARGS *c
 static bool
 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
 {
-  if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 || TARGET_64BIT)
     return must_pass_in_stack_var_size (mode, type);
   else
     return must_pass_in_stack_var_size_or_pad (mode, type);
@@ -8762,6 +8770,7 @@ rs6000_function_arg_boundary (enum machi
 	       && int_size_in_bytes (type) >= 16))
     return 128;
   else if (((TARGET_MACHO && rs6000_darwin64_abi)
+	    || DEFAULT_ABI == ABI_ELFv2
             || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
  	   && mode == BLKmode
 	   && type && TYPE_ALIGN (type) > 64)
@@ -9004,7 +9013,8 @@ rs6000_function_arg_advance_1 (CUMULATIV
 	  /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
 	     even if it is going to be passed in a vector register.
 	     Darwin does the same for variable-argument functions.  */
-	  if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+	  if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	       && TARGET_64BIT)
 	      || (cum->stdarg && DEFAULT_ABI != ABI_V4))
 	    stack = true;
 	}
@@ -9787,7 +9797,7 @@ rs6000_function_arg (cumulative_args_t c
 	  /* Do we also need to pass this argument in the parameter
 	     save area?  */
 	  if (type && (cum->nargs_prototype <= 0
-		       || (DEFAULT_ABI == ABI_AIX
+		       || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 			   && TARGET_XL_COMPAT
 			   && align_words >= GP_ARG_NUM_REG)))
 	    k = rs6000_psave_function_arg (mode, type, align_words, rvec);
@@ -9871,7 +9881,7 @@ rs6000_arg_partial_bytes (cumulative_arg
 	 PARALLEL including a memory element as necessary.  */
       if (type
 	  && (cum->nargs_prototype <= 0
-	      || (DEFAULT_ABI == ABI_AIX
+	      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 		  && TARGET_XL_COMPAT
 		  && align_words >= GP_ARG_NUM_REG)))
 	return 0;
@@ -10343,6 +10353,7 @@ rs6000_gimplify_va_arg (tree valist, tre
 
   if (((TARGET_MACHO
         && rs6000_darwin64_abi)
+       || DEFAULT_ABI == ABI_ELFv2
        || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
       && integer_zerop (TYPE_SIZE (type)))
     {
@@ -16667,6 +16678,7 @@ rs6000_output_function_entry (FILE *file
 	  gcc_unreachable ();
 
 	case ABI_AIX:
+	case ABI_ELFv2:
 	  if (DOT_SYMBOLS)
 	    putc ('.', file);
 	  else
@@ -17470,7 +17482,7 @@ rs6000_assemble_integer (rtx x, unsigned
 	 itself.  */
       else if (GET_CODE (x) == SYMBOL_REF
 	       && XSTR (x, 0)[0] == '.'
-	       && DEFAULT_ABI == ABI_AIX)
+	       && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2))
 	{
 	  const char *name = XSTR (x, 0);
 	  while (*name == '.')
@@ -19625,7 +19637,7 @@ rs6000_savres_strategy (rs6000_stack_t *
     }
   else
     {
-      gcc_checking_assert (DEFAULT_ABI == ABI_AIX);
+      gcc_checking_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
       if (info->first_fp_reg_save > 61)
 	strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
       strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
@@ -19962,6 +19974,7 @@ rs6000_stack_info (void)
       gcc_unreachable ();
 
     case ABI_AIX:
+    case ABI_ELFv2:
     case ABI_DARWIN:
       info_ptr->fp_save_offset   = - info_ptr->fp_size;
       info_ptr->gp_save_offset   = info_ptr->fp_save_offset - info_ptr->gp_size;
@@ -20066,7 +20079,7 @@ rs6000_stack_info (void)
 
   /* Determine if we need to save the link register.  */
   if (info_ptr->calls_p
-      || (DEFAULT_ABI == ABI_AIX
+      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 	  && crtl->profile
 	  && !TARGET_PROFILE_KERNEL)
       || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
@@ -20212,6 +20225,7 @@ debug_stack_info (rs6000_stack_t *info)
     default:		 abi_string = "Unknown";	break;
     case ABI_NONE:	 abi_string = "NONE";		break;
     case ABI_AIX:	 abi_string = "AIX";		break;
+    case ABI_ELFv2:	 abi_string = "ELFv2";		break;
     case ABI_DARWIN:	 abi_string = "Darwin";		break;
     case ABI_V4:	 abi_string = "V.4";		break;
     }
@@ -20393,13 +20407,13 @@ rs6000_function_ok_for_sibcall (tree dec
 	return false;
     }
 
-  /* Under the AIX ABI we can't allow calls to non-local functions,
-     because the callee may have a different TOC pointer to the
-     caller and there's no way to ensure we restore the TOC when we
-     return.  With the secure-plt SYSV ABI we can't make non-local
+  /* Under the AIX or ELFv2 ABIs we can't allow calls to non-local
+     functions, because the callee may have a different TOC pointer to
+     the caller and there's no way to ensure we restore the TOC when
+     we return.  With the secure-plt SYSV ABI we can't make non-local
      calls when -fpic/PIC because the plt call stubs use r30.  */
   if (DEFAULT_ABI == ABI_DARWIN
-      || (DEFAULT_ABI == ABI_AIX
+      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 	  && decl
 	  && !DECL_EXTERNAL (decl)
 	  && (*targetm.binds_local_p) (decl))
@@ -20558,7 +20572,7 @@ rs6000_emit_load_toc_table (int fromprol
     }
   else
     {
-      gcc_assert (DEFAULT_ABI == ABI_AIX);
+      gcc_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
 
       if (TARGET_32BIT)
 	emit_insn (gen_load_toc_aix_si (dest));
@@ -21277,7 +21291,7 @@ rs6000_savres_routine_name (rs6000_stack
       if ((sel & SAVRES_LR))
 	suffix = "_x";
     }
-  else if (DEFAULT_ABI == ABI_AIX)
+  else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
 #if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
       /* No out-of-line save/restore routines for GPRs on AIX.  */
@@ -21418,7 +21432,7 @@ rs6000_emit_stack_reset (rs6000_stack_t 
 static inline unsigned
 ptr_regno_for_savres (int sel)
 {
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     return (sel & SAVRES_REG) == SAVRES_FPR || (sel & SAVRES_LR) ? 1 : 12;
   return DEFAULT_ABI == ABI_DARWIN && (sel & SAVRES_REG) == SAVRES_FPR ? 1 : 11;
 }
@@ -21785,7 +21799,7 @@ rs6000_emit_prologue (void)
 
   /* If we need to save CR, put it into r12 or r11.  Choose r12 except when
      r12 will be needed by out-of-line gpr restore.  */
-  cr_save_regno = (DEFAULT_ABI == ABI_AIX
+  cr_save_regno = ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 		   && !(strategy & (SAVE_INLINE_GPRS
 				    | SAVE_NOINLINE_GPRS_SAVES_LR))
 		   ? 11 : 12);
@@ -22301,7 +22315,8 @@ rs6000_emit_prologue (void)
 	 be using r12 as frame_reg_rtx and r11 as the static chain
 	 pointer for nested functions.  */
       save_regno = 12;
-      if (DEFAULT_ABI == ABI_AIX && !using_static_chain_p)
+      if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	  && !using_static_chain_p)
 	save_regno = 11;
       else if (REGNO (frame_reg_rtx) == 12)
 	{
@@ -23392,6 +23407,7 @@ rs6000_emit_epilogue (int sibcall)
       if (! restoring_FPRs_inline)
 	{
 	  int i;
+	  int reg;
 	  rtx sym;
 
 	  if (flag_shrink_wrap)
@@ -23400,10 +23416,9 @@ rs6000_emit_epilogue (int sibcall)
 	  sym = rs6000_savres_routine_sym (info,
 					   SAVRES_FPR | (lr ? SAVRES_LR : 0));
 	  RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
-	  RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
-					  gen_rtx_REG (Pmode,
-						       DEFAULT_ABI == ABI_AIX
-						       ? 1 : 11));
+	  reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11;
+	  RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
+
 	  for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	    {
 	      rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
@@ -23481,7 +23496,8 @@ rs6000_output_function_epilogue (FILE *f
 
      System V.4 Powerpc's (and the embedded ABI derived from it) use a
      different traceback table.  */
-  if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
+  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+      && ! flag_inhibit_size_directive
       && rs6000_traceback != traceback_none && !cfun->is_thunk)
     {
       const char *fname = NULL;
@@ -24484,7 +24500,7 @@ output_profile_hook (int labelno ATTRIBU
   if (TARGET_PROFILE_KERNEL)
     return;
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
 #ifndef NO_PROFILE_COUNTERS
 # define NO_PROFILE_COUNTERS 0
@@ -24628,6 +24644,7 @@ output_function_profiler (FILE *file, in
       break;
 
     case ABI_AIX:
+    case ABI_ELFv2:
     case ABI_DARWIN:
       if (!TARGET_PROFILE_KERNEL)
 	{
@@ -26583,6 +26600,7 @@ rs6000_trampoline_size (void)
       gcc_unreachable ();
 
     case ABI_AIX:
+    case ABI_ELFv2:
       ret = (TARGET_32BIT) ? 12 : 24;
       break;
 
@@ -26614,6 +26632,7 @@ rs6000_trampoline_init (rtx m_tramp, tre
 
     /* Under AIX, just build the 3 word function descriptor */
     case ABI_AIX:
+    case ABI_ELFv2:
       {
 	rtx fnmem, fn_reg, toc_reg;
 
@@ -26935,7 +26954,7 @@ rs6000_ms_bitfield_layout_p (const_tree 
 static void
 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 {
-  if (DEFAULT_ABI == ABI_AIX
+  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
       && TARGET_MINIMAL_TOC
       && !TARGET_RELOCATABLE)
     {
@@ -26956,7 +26975,8 @@ rs6000_elf_output_toc_section_asm_op (co
       else
 	fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
     }
-  else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
+  else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	   && !TARGET_RELOCATABLE)
     fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
   else
     {
@@ -27012,7 +27032,7 @@ rs6000_elf_encode_section_info (tree dec
   if (first
       && TREE_CODE (decl) == FUNCTION_DECL
       && !TARGET_AIX
-      && DEFAULT_ABI == ABI_AIX)
+      && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2))
     {
       rtx sym_ref = XEXP (rtl, 0);
       size_t len = strlen (XSTR (sym_ref, 0));
@@ -27506,7 +27526,7 @@ rs6000_elf_reloc_rw_mask (void)
 {
   if (flag_pic)
     return 3;
-  else if (DEFAULT_ABI == ABI_AIX)
+  else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     return 2;
   else
     return 0;
@@ -27632,7 +27652,7 @@ rs6000_elf_declare_function_name (FILE *
   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
   ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       const char *desc_name, *orig_name;
 
@@ -30632,7 +30652,7 @@ rs6000_legitimate_constant_p (enum machi
 
 \f
 
-/* Expand code to perform a call under the AIX ABI.  */
+/* Expand code to perform a call under the AIX or ELFv2 ABI.  */
 
 void
 rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
@@ -30738,7 +30758,7 @@ rs6000_call_aix (rtx value, rtx func_des
     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg);
 }
 
-/* Expand code to perform a sibling call under the AIX ABI.  */
+/* Expand code to perform a sibling call under the AIX or ELFv2 ABI.  */
 
 void
 rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
Index: gcc/gcc/config/rs6000/rs6000.md
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.md
+++ gcc/gcc/config/rs6000/rs6000.md
@@ -11201,7 +11201,7 @@
 	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		   UNSPEC_TLSGD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
 {
   if (TARGET_CMODEL != CMODEL_SMALL)
     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
@@ -11310,7 +11310,8 @@
    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
 		   UNSPEC_TLSGD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS
+   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
   "bl %z1(%3@tlsgd)\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -11342,7 +11343,7 @@
    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
 		   UNSPEC_TLSLD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
 {
   if (TARGET_CMODEL != CMODEL_SMALL)
     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
@@ -11445,7 +11446,8 @@
 	      (match_operand 2 "" "g")))
    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS
+   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
   "bl %z1(%&@tlsld)\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -11816,7 +11818,7 @@
   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
 	      (use (reg:SI 2))])]
-  "DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
   "*
 {
   char buf[30];
@@ -11831,7 +11833,7 @@
   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
 	      (use (reg:DI 2))])]
-  "DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
   "*
 {
   char buf[30];
@@ -12097,7 +12099,7 @@
 
   operands[0] = XEXP (operands[0], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
@@ -12141,7 +12143,7 @@
 
   operands[1] = XEXP (operands[1], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
       DONE;
@@ -12440,7 +12442,7 @@
   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
 	 (match_operand 1 "" "g"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z0"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -12450,7 +12452,7 @@
 	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
 	      (match_operand 2 "" "g")))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -12462,7 +12464,7 @@
   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
 	 (match_operand 1 "" "g"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z0\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -12472,7 +12474,7 @@
 	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
 	      (match_operand 2 "" "g")))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z1\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -12488,7 +12490,7 @@
    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
    (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
@@ -12500,7 +12502,7 @@
    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
    (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
@@ -12554,7 +12556,7 @@
 
   operands[0] = XEXP (operands[0], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
@@ -12581,7 +12583,7 @@
 
   operands[1] = XEXP (operands[1], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
       DONE;
@@ -12741,7 +12743,7 @@
   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
 	 (match_operand 1 "" "g,g"))
    (simple_return)]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "@
    b %z0
    b%T0"
@@ -12753,7 +12755,7 @@
 	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
 	      (match_operand 2 "" "g,g")))
    (simple_return)]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "@
    b %z1
    b%T1"
Index: gcc/gcc/config/rs6000/predicates.md
===================================================================
--- gcc.orig/gcc/config/rs6000/predicates.md
+++ gcc/gcc/config/rs6000/predicates.md
@@ -1018,7 +1018,8 @@
 (define_predicate "symbol_ref_operand"
   (and (match_code "symbol_ref")
        (match_test "(mode == VOIDmode || GET_MODE (op) == mode)
-		    && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))")))
+		    && ((DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_ELFv2)
+			|| SYMBOL_REF_FUNCTION_P (op))")))
 
 ;; Return 1 if op is an operand that can be loaded via the GOT.
 ;; or non-special register register field no cr0
@@ -1048,9 +1049,11 @@
 ;; this file.
 (define_predicate "current_file_function_operand"
   (and (match_code "symbol_ref")
-       (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
+       (match_test "((DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_ELFv2)
+		     || SYMBOL_REF_FUNCTION_P (op))
 		    && ((SYMBOL_REF_LOCAL_P (op)
-			 && (DEFAULT_ABI != ABI_AIX
+			 && ((DEFAULT_ABI != ABI_AIX
+			      && DEFAULT_ABI != ABI_ELFv2)
 			     || !SYMBOL_REF_EXTERNAL_P (op)))
 		        || (op == XEXP (DECL_RTL (current_function_decl),
 						  0)))")))
Index: gcc/libgcc/config/rs6000/linux-unwind.h
===================================================================
--- gcc.orig/libgcc/config/rs6000/linux-unwind.h
+++ gcc/libgcc/config/rs6000/linux-unwind.h
@@ -107,6 +107,8 @@ get_regs (struct _Unwind_Context *contex
     }
   else if (pc[1] == 0x380000AC)
     {
+#if _CALL_ELF != 2
+      /* These old kernel versions never supported ELFv2.  */
       /* This works for 2.4 kernels, but not for 2.6 kernels with vdso
 	 because pc isn't pointing into the stack.  Can be removed when
 	 no one is running 2.4.19 or 2.4.20, the first two ppc64
@@ -121,6 +123,7 @@ get_regs (struct _Unwind_Context *contex
       if ((long) frame24->puc != -21 * 8)
 	return frame24->puc->regs;
       else
+#endif
 	{
 	  /* This works for 2.4.21 and later kernels.  */
 	  struct rt_sigframe {
@@ -298,8 +301,12 @@ frob_update_context (struct _Unwind_Cont
 	 code that does the save/restore is generated by the linker, so
 	 we have no good way to determine at compile time what to do.  */
       if (pc[0] == 0xF8410028
+#if _CALL_ELF != 2
+	  /* The ELFv2 linker never generates the old PLT stub form.  */
 	  || ((pc[0] & 0xFFFF0000) == 0x3D820000
-	      && pc[1] == 0xF8410028))
+	      && pc[1] == 0xF8410028)
+#endif
+	  )
 	{
 	  /* We are in a plt call stub or r2 adjusting long branch stub,
 	     before r2 has been saved.  Keep REG_UNSAVED.  */
Index: gcc/gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc.orig/gcc/testsuite/lib/target-supports.exp
+++ gcc/gcc/testsuite/lib/target-supports.exp
@@ -3019,6 +3019,22 @@ proc check_effective_target_powerpc_405_
     }
 }
 
+# Return 1 if this is a PowerPC target using the ELFv2 ABI.
+
+proc check_effective_target_powerpc_elfv2 { } {
+    if { [istarget powerpc*-*-*] } {
+	return [check_no_compiler_messages powerpc_elfv2 object {
+	    #if _CALL_ELF != 2
+	    #error not ELF v2 ABI
+	    #else
+	    int dummy;
+	    #endif
+	}]
+    } else {
+	return 0
+    }
+}
+
 # Return 1 if this is a SPU target with a toolchain that
 # supports automatic overlay generation.
 
Index: gcc/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
+++ gcc/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
@@ -1,5 +1,6 @@
 /* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
 /* { dg-options "-O2 -mcpu=power7" } */
 
 /* Verify that vs is 16-byte aligned in the absence of -mcompat-align-parm.  */
Index: gcc/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
+++ gcc/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
@@ -1,5 +1,6 @@
 /* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
 /* { dg-options "-O2 -mcpu=power7 -mcompat-align-parm" } */
 
 /* Verify that vs is not 16-byte aligned with -mcompat-align-parm.  */
-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-11 14:48 [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Ulrich Weigand
@ 2013-11-11 15:08 ` Ulrich Weigand
  2013-11-12  3:01 ` Joseph S. Myers
  2013-11-12  4:31 ` [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Jakub Jelinek
  2 siblings, 0 replies; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-11 15:08 UTC (permalink / raw)
  To: gcc-patches

Hello,

this is the first patch in the series to add support for the ELFv2 ABI.

The ELFv2 ABI is the intended ABI for the new powerpc64le-linux port.
However, it is not inherently tied to the byte order; it it possible
in principle to use the ELFv2 ABI in big-endian mode too.

Therefore, it is introduces via a new pair of options
   -mabi=elfv1 / -mabi=elfv2
where -mabi=elfv1 select the current Linux ABI, and -mabi=elfv2
selects the new one.

If neither option is given, the compiler defaults to whatever ABI
was specified at configure time using the
   --with-abi=elfv1 / --with-abi=elfv2
configure option.

If this was not specified either, every subtarget can provide a
master default by defining (or not) the LINUX64_DEFAULT_ABI_ELFv2
macro.

The patch series is structured as follows:

- This first patch adds the new enum rs6000_abi value ABI_ELFv2
  and all the configure logic needed to set it.  It is treated
  just like ABI_AIX (on a modern system) at this point; no change
  in generated code is expected yet.

- A series of follow on patches will add the various features
  defining the ELFv2 ABI.  Note that they will still not be
  active by default anywhere.

- The final patch will simply turn the switch to make ELFv2
  the default ABI on powerpc64le-linux.

The whole series was tested on:

  - powerpc64-linux with no regression, including no regression
    in an ALT_CC_UNDER_TEST/ALT_CXX_UNDER_TEST run of compat.exp
    and struct-layout-1.exp against a current compiler.

  - powerpc64-linux --with-abi=elfv2 in mock-up big-endian ELFv2
    environment running with some hacks on an existing system.

  - powerpc64le-linux, using the new default ELFv2 in a rebuilt
    small OS image using the new ABI everywhere.
 
(Of course, patches to binutils, glibc, and libffi to support the
new ELFv2 ABI are also required.)

The tests were using all languages (including Java, Go, and
Objective-C++; on powerpc64le-linux also Ada), and all target
libraries except libsanitizer (which currently seems broken
on mainline).

There is a small number of regressions on powerpc64le-linux
which seem to be due to unrelated issues:

- FAIL: g++.dg/cpp1y/vla-initlist1.C execution test
  This is an invalid assumption in the test case

- FAIL: go.test/test/fixedbugs/bug296.go execution,  -O2 -g
  The ELFv2 ABI  seems to be exposing a Go frontend bug here

- FAIL: runtime/pprof   (in libgo)
  This is due to a glibc problem with unwinding through a
  context created via makecontext

I'll address those separately.  (Of course, there are also
other pre-existing regressions on powerpc64le-linux simply
due to little-endian issues.  Those are unaffected by ELFv2.)


I'll add more detailed descriptions of the actual ABI features
with the various follow-on patches that implement those.

This patch specifically only adds the options as described above.
ABI_ELFv2 is implemented to be equivalent to ABI_AIX on a modern
system; since the ABI is new, there is no need to continue to
support legacy features.  This means specifically:
- DOT_SYMBOLS is assumed to be false
- rs6000_compat_align_parm is assumed to be false
- code in linux-unwind.h that handles old kernels/linkers is removed

The patch also adds two new pre-defined macros:
- _CALL_ELF is set to 1 or 2 to denote the ELFv1 / ELFv2 ABI
- __STRUCT_PARM_ALIGN__ is set to 16 if aggregates passed by value
  are aligned to 16 if their native alignment requires that
  (this is necessary to implement libffi, for example)

In addition, the patch adds a testsuite effective target check
for the ELFv2 ABI, and disables the pr57949 tests (these verify
the operation of the -mcompat-align-parm option, which is no
longer useful in the ELFv2 ABI).


To avoid having a partial ABI implementation in tree, it seems best
to commit this whole patch series as a single commit.

Is the series OK for mainline?

Bye,
Ulrich




gcc/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config.gcc [powerpc*-*-* | rs6000-*-*]: Support --with-abi=elfv1
	and --with-abi=elfv2.
	* config/rs6000/option-defaults.h (OPTION_DEFAULT_SPECS): Add "abi".
	* config/rs6000/rs6000.opt (mabi=elfv1): New option.
	(mabi=elfv2): Likewise.
	* config/rs6000/rs6000-opts.h (enum rs6000_abi): Add ABI_ELFv2.
	* config/rs6000/linux64.h (DEFAULT_ABI): Do not hard-code to AIX_ABI
	if !RS6000_BI_ARCH.
	(ELFv2_ABI_CHECK): New macro.
	(SUBSUBTARGET_OVERRIDE_OPTIONS): Use it to decide whether to set
	rs6000_current_abi to ABI_AIX or ABI_ELFv2.
	(GLIBC_DYNAMIC_LINKER64): Support ELFv2 ld.so version.
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Predefine
	_CALL_ELF and __STRUCT_PARM_ALIGN__ if appropriate.

	* config/rs6000/rs6000.c (rs6000_debug_reg_global): Handle ABI_ELFv2.
	(debug_stack_info): Likewise.
	(rs6000_file_start): Treat ABI_ELFv2 the same as ABI_AIX.
	(rs6000_legitimize_tls_address): Likewise.
	(rs6000_conditional_register_usage): Likewise.
	(rs6000_emit_move): Likewise.
	(init_cumulative_args): Likewise.
	(rs6000_function_arg_advance_1): Likewise.
	(rs6000_function_arg): Likewise.
	(rs6000_arg_partial_bytes): Likewise.
	(rs6000_output_function_entry): Likewise.
	(rs6000_assemble_integer): Likewise.
	(rs6000_savres_strategy): Likewise.
	(rs6000_stack_info): Likewise.
	(rs6000_function_ok_for_sibcall): Likewise.
	(rs6000_emit_load_toc_table): Likewise.
	(rs6000_savres_routine_name): Likewise.
	(ptr_regno_for_savres): Likewise.
	(rs6000_emit_prologue): Likewise.
	(rs6000_emit_epilogue): Likewise.
	(rs6000_output_function_epilogue): Likewise.
	(output_profile_hook): Likewise.
	(output_function_profiler): Likewise.
	(rs6000_trampoline_size): Likewise.
	(rs6000_trampoline_init): Likewise.
	(rs6000_elf_output_toc_section_asm_op): Likewise.
	(rs6000_elf_encode_section_info): Likewise.
	(rs6000_elf_reloc_rw_mask): Likewise.
	(rs6000_elf_declare_function_name): Likewise.
	(rs6000_function_arg_boundary): Treat ABI_ELFv2 the same as ABI_AIX,
	except that rs6000_compat_align_parm is always assumed false.
	(rs6000_gimplify_va_arg): Likewise.
	(rs6000_call_aix): Update comment.
	(rs6000_sibcall_aix): Likewise.
	* config/rs6000/rs6000.md ("tls_gd_aix<TLSmode:tls_abi_suffix>"):
	Treat ABI_ELFv2 the same as ABI_AIX.
	("*tls_gd_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
	("tls_ld_aix<TLSmode:tls_abi_suffix>"): Likewise.
	("*tls_ld_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
	("load_toc_aix_si"): Likewise.
	("load_toc_aix_di"): Likewise.
	("call"): Likewise.
	("call_value"): Likewise.
	("*call_local_aix<mode>"): Likewise.
	("*call_value_local_aix<mode>"): Likewise.
	("*call_nonlocal_aix<mode>"): Likewise.
	("*call_value_nonlocal_aix<mode>"): Likewise.
	("*call_indirect_aix<mode>"): Likewise.
	("*call_value_indirect_aix<mode>"): Likewise.
	("sibcall"): Likewise.
	("sibcall_value"): Likewise.
	("*sibcall_aix<mode>"): Likewise.
	("*sibcall_value_aix<mode>"): Likewise.
	* config/rs6000/predicates.md ("symbol_ref_operand"): Likewise.
	("current_file_function_operand"): Likewise.

libgcc/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
	    Alan Modra  <amodra@gmail.com>

	* config/rs6000/linux-unwind.h (get_regs): Do not support
	old kernel versions if _CALL_ELF == 2.
	(frob_update_context): Do not support PLT stub variants only
	generated by old linkers if _CALL_ELF == 2.

gcc/testsuite/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* lib/target-supports.exp (check_effective_target_powerpc_elfv2):
	New function.
	* gcc.target/powerpc/pr57949-1.c: Disable for powerpc_elfv2.
	* gcc.target/powerpc/pr57949-2.c: Likewise.


Index: gcc/gcc/config.gcc
===================================================================
--- gcc.orig/gcc/config.gcc
+++ gcc/gcc/config.gcc
@@ -3805,7 +3805,7 @@ case "${target}" in
 		;;
 
 	powerpc*-*-* | rs6000-*-*)
-		supported_defaults="cpu cpu_32 cpu_64 float tune tune_32 tune_64"
+		supported_defaults="abi cpu cpu_32 cpu_64 float tune tune_32 tune_64"
 
 		for which in cpu cpu_32 cpu_64 tune tune_32 tune_64; do
 			eval "val=\$with_$which"
@@ -3842,6 +3842,16 @@ case "${target}" in
 				;;
 			esac
 		done
+
+		case "$with_abi" in
+		"" | elfv1 | elfv2 )
+			#OK
+			;;
+		*)
+			echo "Unknown ABI used in --with-abi=$with_abi"
+			exit 1
+			;;
+		esac
 		;;
 
 	s390*-*-*)
Index: gcc/gcc/config/rs6000/option-defaults.h
===================================================================
--- gcc.orig/gcc/config/rs6000/option-defaults.h
+++ gcc/gcc/config/rs6000/option-defaults.h
@@ -54,6 +54,7 @@
    --with-float is ignored if -mhard-float or -msoft-float are
      specified.  */
 #define OPTION_DEFAULT_SPECS \
+  {"abi", "%{!mabi=elfv*:-mabi=%(VALUE)}" }, \
   {"tune", "%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}" }, \
   {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \
   {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \
Index: gcc/gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.opt
+++ gcc/gcc/config/rs6000/rs6000.opt
@@ -369,6 +369,14 @@ mabi=no-spe
 Target RejectNegative Var(rs6000_spe_abi, 0)
 Do not use the SPE ABI extensions
 
+mabi=elfv1
+Target RejectNegative Var(rs6000_elf_abi, 1) Save
+Use the ELFv1 ABI
+
+mabi=elfv2
+Target RejectNegative Var(rs6000_elf_abi, 2)
+Use the ELFv2 ABI
+
 ; These are here for testing during development only, do not document
 ; in the manual please.
 
Index: gcc/gcc/config/rs6000/rs6000-opts.h
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000-opts.h
+++ gcc/gcc/config/rs6000/rs6000-opts.h
@@ -107,7 +107,8 @@ enum group_termination
 /* Enumeration to give which calling sequence to use.  */
 enum rs6000_abi {
   ABI_NONE,
-  ABI_AIX,			/* IBM's AIX */
+  ABI_AIX,			/* IBM's AIX, or Linux ELFv1 */
+  ABI_ELFv2,			/* Linux ELFv2 ABI */
   ABI_V4,			/* System V.4/eabi */
   ABI_DARWIN			/* Apple's Darwin (OS X kernel) */
 };
Index: gcc/gcc/config/rs6000/linux64.h
===================================================================
--- gcc.orig/gcc/config/rs6000/linux64.h
+++ gcc/gcc/config/rs6000/linux64.h
@@ -25,9 +25,6 @@
 
 #ifndef RS6000_BI_ARCH
 
-#undef	DEFAULT_ABI
-#define	DEFAULT_ABI ABI_AIX
-
 #undef	TARGET_64BIT
 #define	TARGET_64BIT 1
 
@@ -88,6 +85,12 @@ extern int dot_symbols;
 #define INVALID_64BIT "-m%s not supported in this configuration"
 #define INVALID_32BIT INVALID_64BIT
 
+#ifdef LINUX64_DEFAULT_ABI_ELFv2
+#define ELFv2_ABI_CHECK (rs6000_elf_abi != 1)
+#else
+#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2)
+#endif
+
 #undef	SUBSUBTARGET_OVERRIDE_OPTIONS
 #define	SUBSUBTARGET_OVERRIDE_OPTIONS				\
   do								\
@@ -102,6 +105,12 @@ extern int dot_symbols;
 	      error (INVALID_64BIT, "call");			\
 	    }							\
 	  dot_symbols = !strcmp (rs6000_abi_name, "aixdesc");	\
+	  if (ELFv2_ABI_CHECK)					\
+	    {							\
+	      rs6000_current_abi = ABI_ELFv2;			\
+	      if (dot_symbols)					\
+		error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \
+	    }							\
 	  if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE)	\
 	    {							\
 	      rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;	\
@@ -355,7 +364,11 @@ extern int dot_symbols;
 #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
 
 #define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
+#ifdef LINUX64_DEFAULT_ABI_ELFv2
+#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
+#else
+#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
+#endif
 #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
 #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
 #if DEFAULT_LIBC == LIBC_UCLIBC
Index: gcc/gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000-c.c
+++ gcc/gcc/config/rs6000/rs6000-c.c
@@ -461,6 +461,10 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     case ABI_AIX:
       builtin_define ("_CALL_AIXDESC");
       builtin_define ("_CALL_AIX");
+      builtin_define ("_CALL_ELF=1");
+      break;
+    case ABI_ELFv2:
+      builtin_define ("_CALL_ELF=2");
       break;
     case ABI_DARWIN:
       builtin_define ("_CALL_DARWIN");
@@ -473,6 +477,13 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
   if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
     builtin_define ("__NO_FPRS__");
 
+  /* Whether aggregates passed by value are aligned to a 16 byte boundary
+     if their alignment is 16 bytes or larger.  */
+  if ((TARGET_MACHO && rs6000_darwin64_abi)
+      || DEFAULT_ABI == ABI_ELFv2
+      || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
+    builtin_define ("__STRUCT_PARM_ALIGN__=16");
+
   /* Generate defines for Xilinx FPU. */
   if (rs6000_xilinx_fpu) 
     {
Index: gcc/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.c
+++ gcc/gcc/config/rs6000/rs6000.c
@@ -2231,6 +2231,7 @@ rs6000_debug_reg_global (void)
     {
     case ABI_NONE:	abi_str = "none";	break;
     case ABI_AIX:	abi_str = "aix";	break;
+    case ABI_ELFv2:	abi_str = "ELFv2";	break;
     case ABI_V4:	abi_str = "V4";		break;
     case ABI_DARWIN:	abi_str = "darwin";	break;
     default:		abi_str = "unknown";	break;
@@ -4761,7 +4762,8 @@ rs6000_file_start (void)
 	putc ('\n', file);
     }
 
-  if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2
+      || (TARGET_ELF && flag_pic == 2))
     {
       switch_to_section (toc_section);
       switch_to_section (text_section);
@@ -6971,10 +6973,13 @@ rs6000_legitimize_tls_address (rtx addr,
 				   1, const0_rtx, Pmode);
 
 	  r3 = gen_rtx_REG (Pmode, 3);
-	  if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
-	    insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
-	  else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
-	    insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+	  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	    {
+	      if (TARGET_64BIT)
+		insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
+	      else
+		insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+	    }
 	  else if (DEFAULT_ABI == ABI_V4)
 	    insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
 	  else
@@ -6993,10 +6998,13 @@ rs6000_legitimize_tls_address (rtx addr,
 				   1, const0_rtx, Pmode);
 
 	  r3 = gen_rtx_REG (Pmode, 3);
-	  if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
-	    insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
-	  else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
-	    insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+	  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	    {
+	      if (TARGET_64BIT)
+		insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
+	      else
+		insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+	    }
 	  else if (DEFAULT_ABI == ABI_V4)
 	    insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
 	  else
@@ -7623,7 +7631,7 @@ rs6000_conditional_register_usage (void)
 
   /* The TOC register is not killed across calls in a way that is
      visible to the compiler.  */
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     call_really_used_regs[2] = 0;
 
   if (DEFAULT_ABI == ABI_V4
@@ -8274,7 +8282,7 @@ rs6000_emit_move (rtx dest, rtx source, 
 
 	  /* If this is a function address on -mcall-aixdesc,
 	     convert it to the address of the descriptor.  */
-	  if (DEFAULT_ABI == ABI_AIX
+	  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 	      && GET_CODE (operands[1]) == SYMBOL_REF
 	      && XSTR (operands[1], 0)[0] == '.')
 	    {
@@ -8665,7 +8673,7 @@ init_cumulative_args (CUMULATIVE_ARGS *c
 static bool
 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
 {
-  if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 || TARGET_64BIT)
     return must_pass_in_stack_var_size (mode, type);
   else
     return must_pass_in_stack_var_size_or_pad (mode, type);
@@ -8762,6 +8770,7 @@ rs6000_function_arg_boundary (enum machi
 	       && int_size_in_bytes (type) >= 16))
     return 128;
   else if (((TARGET_MACHO && rs6000_darwin64_abi)
+	    || DEFAULT_ABI == ABI_ELFv2
             || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
  	   && mode == BLKmode
 	   && type && TYPE_ALIGN (type) > 64)
@@ -9004,7 +9013,8 @@ rs6000_function_arg_advance_1 (CUMULATIV
 	  /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
 	     even if it is going to be passed in a vector register.
 	     Darwin does the same for variable-argument functions.  */
-	  if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+	  if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	       && TARGET_64BIT)
 	      || (cum->stdarg && DEFAULT_ABI != ABI_V4))
 	    stack = true;
 	}
@@ -9787,7 +9797,7 @@ rs6000_function_arg (cumulative_args_t c
 	  /* Do we also need to pass this argument in the parameter
 	     save area?  */
 	  if (type && (cum->nargs_prototype <= 0
-		       || (DEFAULT_ABI == ABI_AIX
+		       || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 			   && TARGET_XL_COMPAT
 			   && align_words >= GP_ARG_NUM_REG)))
 	    k = rs6000_psave_function_arg (mode, type, align_words, rvec);
@@ -9871,7 +9881,7 @@ rs6000_arg_partial_bytes (cumulative_arg
 	 PARALLEL including a memory element as necessary.  */
       if (type
 	  && (cum->nargs_prototype <= 0
-	      || (DEFAULT_ABI == ABI_AIX
+	      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 		  && TARGET_XL_COMPAT
 		  && align_words >= GP_ARG_NUM_REG)))
 	return 0;
@@ -10343,6 +10353,7 @@ rs6000_gimplify_va_arg (tree valist, tre
 
   if (((TARGET_MACHO
         && rs6000_darwin64_abi)
+       || DEFAULT_ABI == ABI_ELFv2
        || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
       && integer_zerop (TYPE_SIZE (type)))
     {
@@ -16667,6 +16678,7 @@ rs6000_output_function_entry (FILE *file
 	  gcc_unreachable ();
 
 	case ABI_AIX:
+	case ABI_ELFv2:
 	  if (DOT_SYMBOLS)
 	    putc ('.', file);
 	  else
@@ -17470,7 +17482,7 @@ rs6000_assemble_integer (rtx x, unsigned
 	 itself.  */
       else if (GET_CODE (x) == SYMBOL_REF
 	       && XSTR (x, 0)[0] == '.'
-	       && DEFAULT_ABI == ABI_AIX)
+	       && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2))
 	{
 	  const char *name = XSTR (x, 0);
 	  while (*name == '.')
@@ -19625,7 +19637,7 @@ rs6000_savres_strategy (rs6000_stack_t *
     }
   else
     {
-      gcc_checking_assert (DEFAULT_ABI == ABI_AIX);
+      gcc_checking_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
       if (info->first_fp_reg_save > 61)
 	strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
       strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
@@ -19962,6 +19974,7 @@ rs6000_stack_info (void)
       gcc_unreachable ();
 
     case ABI_AIX:
+    case ABI_ELFv2:
     case ABI_DARWIN:
       info_ptr->fp_save_offset   = - info_ptr->fp_size;
       info_ptr->gp_save_offset   = info_ptr->fp_save_offset - info_ptr->gp_size;
@@ -20066,7 +20079,7 @@ rs6000_stack_info (void)
 
   /* Determine if we need to save the link register.  */
   if (info_ptr->calls_p
-      || (DEFAULT_ABI == ABI_AIX
+      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 	  && crtl->profile
 	  && !TARGET_PROFILE_KERNEL)
       || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
@@ -20212,6 +20225,7 @@ debug_stack_info (rs6000_stack_t *info)
     default:		 abi_string = "Unknown";	break;
     case ABI_NONE:	 abi_string = "NONE";		break;
     case ABI_AIX:	 abi_string = "AIX";		break;
+    case ABI_ELFv2:	 abi_string = "ELFv2";		break;
     case ABI_DARWIN:	 abi_string = "Darwin";		break;
     case ABI_V4:	 abi_string = "V.4";		break;
     }
@@ -20393,13 +20407,13 @@ rs6000_function_ok_for_sibcall (tree dec
 	return false;
     }
 
-  /* Under the AIX ABI we can't allow calls to non-local functions,
-     because the callee may have a different TOC pointer to the
-     caller and there's no way to ensure we restore the TOC when we
-     return.  With the secure-plt SYSV ABI we can't make non-local
+  /* Under the AIX or ELFv2 ABIs we can't allow calls to non-local
+     functions, because the callee may have a different TOC pointer to
+     the caller and there's no way to ensure we restore the TOC when
+     we return.  With the secure-plt SYSV ABI we can't make non-local
      calls when -fpic/PIC because the plt call stubs use r30.  */
   if (DEFAULT_ABI == ABI_DARWIN
-      || (DEFAULT_ABI == ABI_AIX
+      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 	  && decl
 	  && !DECL_EXTERNAL (decl)
 	  && (*targetm.binds_local_p) (decl))
@@ -20558,7 +20572,7 @@ rs6000_emit_load_toc_table (int fromprol
     }
   else
     {
-      gcc_assert (DEFAULT_ABI == ABI_AIX);
+      gcc_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
 
       if (TARGET_32BIT)
 	emit_insn (gen_load_toc_aix_si (dest));
@@ -21277,7 +21291,7 @@ rs6000_savres_routine_name (rs6000_stack
       if ((sel & SAVRES_LR))
 	suffix = "_x";
     }
-  else if (DEFAULT_ABI == ABI_AIX)
+  else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
 #if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
       /* No out-of-line save/restore routines for GPRs on AIX.  */
@@ -21418,7 +21432,7 @@ rs6000_emit_stack_reset (rs6000_stack_t 
 static inline unsigned
 ptr_regno_for_savres (int sel)
 {
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     return (sel & SAVRES_REG) == SAVRES_FPR || (sel & SAVRES_LR) ? 1 : 12;
   return DEFAULT_ABI == ABI_DARWIN && (sel & SAVRES_REG) == SAVRES_FPR ? 1 : 11;
 }
@@ -21785,7 +21799,7 @@ rs6000_emit_prologue (void)
 
   /* If we need to save CR, put it into r12 or r11.  Choose r12 except when
      r12 will be needed by out-of-line gpr restore.  */
-  cr_save_regno = (DEFAULT_ABI == ABI_AIX
+  cr_save_regno = ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
 		   && !(strategy & (SAVE_INLINE_GPRS
 				    | SAVE_NOINLINE_GPRS_SAVES_LR))
 		   ? 11 : 12);
@@ -22301,7 +22315,8 @@ rs6000_emit_prologue (void)
 	 be using r12 as frame_reg_rtx and r11 as the static chain
 	 pointer for nested functions.  */
       save_regno = 12;
-      if (DEFAULT_ABI == ABI_AIX && !using_static_chain_p)
+      if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	  && !using_static_chain_p)
 	save_regno = 11;
       else if (REGNO (frame_reg_rtx) == 12)
 	{
@@ -23392,6 +23407,7 @@ rs6000_emit_epilogue (int sibcall)
       if (! restoring_FPRs_inline)
 	{
 	  int i;
+	  int reg;
 	  rtx sym;
 
 	  if (flag_shrink_wrap)
@@ -23400,10 +23416,9 @@ rs6000_emit_epilogue (int sibcall)
 	  sym = rs6000_savres_routine_sym (info,
 					   SAVRES_FPR | (lr ? SAVRES_LR : 0));
 	  RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
-	  RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
-					  gen_rtx_REG (Pmode,
-						       DEFAULT_ABI == ABI_AIX
-						       ? 1 : 11));
+	  reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11;
+	  RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
+
 	  for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	    {
 	      rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
@@ -23481,7 +23496,8 @@ rs6000_output_function_epilogue (FILE *f
 
      System V.4 Powerpc's (and the embedded ABI derived from it) use a
      different traceback table.  */
-  if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
+  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+      && ! flag_inhibit_size_directive
       && rs6000_traceback != traceback_none && !cfun->is_thunk)
     {
       const char *fname = NULL;
@@ -24484,7 +24500,7 @@ output_profile_hook (int labelno ATTRIBU
   if (TARGET_PROFILE_KERNEL)
     return;
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
 #ifndef NO_PROFILE_COUNTERS
 # define NO_PROFILE_COUNTERS 0
@@ -24628,6 +24644,7 @@ output_function_profiler (FILE *file, in
       break;
 
     case ABI_AIX:
+    case ABI_ELFv2:
     case ABI_DARWIN:
       if (!TARGET_PROFILE_KERNEL)
 	{
@@ -26583,6 +26600,7 @@ rs6000_trampoline_size (void)
       gcc_unreachable ();
 
     case ABI_AIX:
+    case ABI_ELFv2:
       ret = (TARGET_32BIT) ? 12 : 24;
       break;
 
@@ -26614,6 +26632,7 @@ rs6000_trampoline_init (rtx m_tramp, tre
 
     /* Under AIX, just build the 3 word function descriptor */
     case ABI_AIX:
+    case ABI_ELFv2:
       {
 	rtx fnmem, fn_reg, toc_reg;
 
@@ -26935,7 +26954,7 @@ rs6000_ms_bitfield_layout_p (const_tree 
 static void
 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 {
-  if (DEFAULT_ABI == ABI_AIX
+  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
       && TARGET_MINIMAL_TOC
       && !TARGET_RELOCATABLE)
     {
@@ -26956,7 +26975,8 @@ rs6000_elf_output_toc_section_asm_op (co
       else
 	fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
     }
-  else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
+  else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+	   && !TARGET_RELOCATABLE)
     fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
   else
     {
@@ -27012,7 +27032,7 @@ rs6000_elf_encode_section_info (tree dec
   if (first
       && TREE_CODE (decl) == FUNCTION_DECL
       && !TARGET_AIX
-      && DEFAULT_ABI == ABI_AIX)
+      && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2))
     {
       rtx sym_ref = XEXP (rtl, 0);
       size_t len = strlen (XSTR (sym_ref, 0));
@@ -27506,7 +27526,7 @@ rs6000_elf_reloc_rw_mask (void)
 {
   if (flag_pic)
     return 3;
-  else if (DEFAULT_ABI == ABI_AIX)
+  else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     return 2;
   else
     return 0;
@@ -27632,7 +27652,7 @@ rs6000_elf_declare_function_name (FILE *
   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
   ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       const char *desc_name, *orig_name;
 
@@ -30632,7 +30652,7 @@ rs6000_legitimate_constant_p (enum machi
 
 \f
 
-/* Expand code to perform a call under the AIX ABI.  */
+/* Expand code to perform a call under the AIX or ELFv2 ABI.  */
 
 void
 rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
@@ -30738,7 +30758,7 @@ rs6000_call_aix (rtx value, rtx func_des
     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg);
 }
 
-/* Expand code to perform a sibling call under the AIX ABI.  */
+/* Expand code to perform a sibling call under the AIX or ELFv2 ABI.  */
 
 void
 rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
Index: gcc/gcc/config/rs6000/rs6000.md
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.md
+++ gcc/gcc/config/rs6000/rs6000.md
@@ -11201,7 +11201,7 @@
 	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		   UNSPEC_TLSGD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
 {
   if (TARGET_CMODEL != CMODEL_SMALL)
     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
@@ -11310,7 +11310,8 @@
    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
 		   UNSPEC_TLSGD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS
+   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
   "bl %z1(%3@tlsgd)\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -11342,7 +11343,7 @@
    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
 		   UNSPEC_TLSLD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
 {
   if (TARGET_CMODEL != CMODEL_SMALL)
     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
@@ -11445,7 +11446,8 @@
 	      (match_operand 2 "" "g")))
    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
    (clobber (reg:SI LR_REGNO))]
-  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS
+   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
   "bl %z1(%&@tlsld)\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -11816,7 +11818,7 @@
   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
 	      (use (reg:SI 2))])]
-  "DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
   "*
 {
   char buf[30];
@@ -11831,7 +11833,7 @@
   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
 	      (use (reg:DI 2))])]
-  "DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
   "*
 {
   char buf[30];
@@ -12097,7 +12099,7 @@
 
   operands[0] = XEXP (operands[0], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
@@ -12141,7 +12143,7 @@
 
   operands[1] = XEXP (operands[1], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
       DONE;
@@ -12440,7 +12442,7 @@
   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
 	 (match_operand 1 "" "g"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z0"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -12450,7 +12452,7 @@
 	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
 	      (match_operand 2 "" "g")))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -12462,7 +12464,7 @@
   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
 	 (match_operand 1 "" "g"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z0\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -12472,7 +12474,7 @@
 	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
 	      (match_operand 2 "" "g")))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z1\;nop"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
@@ -12488,7 +12490,7 @@
    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
    (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
@@ -12500,7 +12502,7 @@
    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
    (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
@@ -12554,7 +12556,7 @@
 
   operands[0] = XEXP (operands[0], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
@@ -12581,7 +12583,7 @@
 
   operands[1] = XEXP (operands[1], 0);
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     {
       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
       DONE;
@@ -12741,7 +12743,7 @@
   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
 	 (match_operand 1 "" "g,g"))
    (simple_return)]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "@
    b %z0
    b%T0"
@@ -12753,7 +12755,7 @@
 	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
 	      (match_operand 2 "" "g,g")))
    (simple_return)]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "@
    b %z1
    b%T1"
Index: gcc/gcc/config/rs6000/predicates.md
===================================================================
--- gcc.orig/gcc/config/rs6000/predicates.md
+++ gcc/gcc/config/rs6000/predicates.md
@@ -1018,7 +1018,8 @@
 (define_predicate "symbol_ref_operand"
   (and (match_code "symbol_ref")
        (match_test "(mode == VOIDmode || GET_MODE (op) == mode)
-		    && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))")))
+		    && ((DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_ELFv2)
+			|| SYMBOL_REF_FUNCTION_P (op))")))
 
 ;; Return 1 if op is an operand that can be loaded via the GOT.
 ;; or non-special register register field no cr0
@@ -1048,9 +1049,11 @@
 ;; this file.
 (define_predicate "current_file_function_operand"
   (and (match_code "symbol_ref")
-       (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
+       (match_test "((DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_ELFv2)
+		     || SYMBOL_REF_FUNCTION_P (op))
 		    && ((SYMBOL_REF_LOCAL_P (op)
-			 && (DEFAULT_ABI != ABI_AIX
+			 && ((DEFAULT_ABI != ABI_AIX
+			      && DEFAULT_ABI != ABI_ELFv2)
 			     || !SYMBOL_REF_EXTERNAL_P (op)))
 		        || (op == XEXP (DECL_RTL (current_function_decl),
 						  0)))")))
Index: gcc/libgcc/config/rs6000/linux-unwind.h
===================================================================
--- gcc.orig/libgcc/config/rs6000/linux-unwind.h
+++ gcc/libgcc/config/rs6000/linux-unwind.h
@@ -107,6 +107,8 @@ get_regs (struct _Unwind_Context *contex
     }
   else if (pc[1] == 0x380000AC)
     {
+#if _CALL_ELF != 2
+      /* These old kernel versions never supported ELFv2.  */
       /* This works for 2.4 kernels, but not for 2.6 kernels with vdso
 	 because pc isn't pointing into the stack.  Can be removed when
 	 no one is running 2.4.19 or 2.4.20, the first two ppc64
@@ -121,6 +123,7 @@ get_regs (struct _Unwind_Context *contex
       if ((long) frame24->puc != -21 * 8)
 	return frame24->puc->regs;
       else
+#endif
 	{
 	  /* This works for 2.4.21 and later kernels.  */
 	  struct rt_sigframe {
@@ -298,8 +301,12 @@ frob_update_context (struct _Unwind_Cont
 	 code that does the save/restore is generated by the linker, so
 	 we have no good way to determine at compile time what to do.  */
       if (pc[0] == 0xF8410028
+#if _CALL_ELF != 2
+	  /* The ELFv2 linker never generates the old PLT stub form.  */
 	  || ((pc[0] & 0xFFFF0000) == 0x3D820000
-	      && pc[1] == 0xF8410028))
+	      && pc[1] == 0xF8410028)
+#endif
+	  )
 	{
 	  /* We are in a plt call stub or r2 adjusting long branch stub,
 	     before r2 has been saved.  Keep REG_UNSAVED.  */
Index: gcc/gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc.orig/gcc/testsuite/lib/target-supports.exp
+++ gcc/gcc/testsuite/lib/target-supports.exp
@@ -3019,6 +3019,22 @@ proc check_effective_target_powerpc_405_
     }
 }
 
+# Return 1 if this is a PowerPC target using the ELFv2 ABI.
+
+proc check_effective_target_powerpc_elfv2 { } {
+    if { [istarget powerpc*-*-*] } {
+	return [check_no_compiler_messages powerpc_elfv2 object {
+	    #if _CALL_ELF != 2
+	    #error not ELF v2 ABI
+	    #else
+	    int dummy;
+	    #endif
+	}]
+    } else {
+	return 0
+    }
+}
+
 # Return 1 if this is a SPU target with a toolchain that
 # supports automatic overlay generation.
 
Index: gcc/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
+++ gcc/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
@@ -1,5 +1,6 @@
 /* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
 /* { dg-options "-O2 -mcpu=power7" } */
 
 /* Verify that vs is 16-byte aligned in the absence of -mcompat-align-parm.  */
Index: gcc/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
+++ gcc/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
@@ -1,5 +1,6 @@
 /* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
 /* { dg-options "-O2 -mcpu=power7 -mcompat-align-parm" } */
 
 /* Verify that vs is not 16-byte aligned with -mcompat-align-parm.  */
-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-11 14:48 [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Ulrich Weigand
  2013-11-11 15:08 ` Ulrich Weigand
@ 2013-11-12  3:01 ` Joseph S. Myers
  2013-11-12 22:22   ` Ulrich Weigand
  2013-11-12  4:31 ` [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Jakub Jelinek
  2 siblings, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2013-11-12  3:01 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On Mon, 11 Nov 2013, Ulrich Weigand wrote:

> Hello,
> 
> this is the first patch in the series to add support for the ELFv2 ABI.
> 
> The ELFv2 ABI is the intended ABI for the new powerpc64le-linux port.
> However, it is not inherently tied to the byte order; it it possible
> in principle to use the ELFv2 ABI in big-endian mode too.

I'd rather, from a glibc perspective, keep down the number of variant ABIs 
available - and in particular, disallow the (ELFv1, little-endian 
combination) - have a compiler error given for it.  And, similarly, have 
the (ELFv2, big-endian) combination only if the plan is for it to obsolete 
the old ABI and for support for the old ABI for powerpc64-linux to be 
removed from GCC and glibc in a few years' time (similarly to how the ARM 
EABI superseded the old arm-linux-gnu ABI).  If you don't have such errors 
in GCC, then you should have configure-time errors in glibc to disallow 
the unsupported combinations.

(Any new supported glibc configuration should of course set minimum symbol 
version to GLIBC_2.19, or whatever the version is of the first release 
supporting it - and the dynamic linker / ldconfig should distinguish 
shared libraries for the two variants.)

I didn't see anything in this series regarding the ELFv1 ABI feature 
that's the greatest pain from a glibc perspective - the use of IBM long 
double.  The idea of moving to IEEE binary128 was floated in 
<https://sourceware.org/ml/libc-alpha/2013-10/msg00597.html> - have you 
abandoned that idea?  Obviously it would be bad to end up having two 
variants of ELFv2 with different long double formats.  (Though we can't 
actually eliminate IBM long double support from glibc unless all ABIs with 
it are obsoleted, including 32-bit.)  If you do move to IEEE binary128 I'd 
advise simply using soft-fp in libgcc for the functions that normally go 
in libgcc, given that 64-bit implies hard float, rather than the 
arrangements some targets have of putting their binary128 functions in 
glibc.

> Therefore, it is introduces via a new pair of options
>    -mabi=elfv1 / -mabi=elfv2
> where -mabi=elfv1 select the current Linux ABI, and -mabi=elfv2
> selects the new one.

New command-line options need invoke.texi documentation.

> (Of course, patches to binutils, glibc, and libffi to support the
> new ELFv2 ABI are also required.)

And GDB - GDB needs to know how to call functions, how to pass arguments 
to them and how to find the return value.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-11 14:48 [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Ulrich Weigand
  2013-11-11 15:08 ` Ulrich Weigand
  2013-11-12  3:01 ` Joseph S. Myers
@ 2013-11-12  4:31 ` Jakub Jelinek
  2013-11-12 22:33   ` Ulrich Weigand
  2 siblings, 1 reply; 13+ messages in thread
From: Jakub Jelinek @ 2013-11-12  4:31 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On Mon, Nov 11, 2013 at 03:40:48PM +0100, Ulrich Weigand wrote:
> @@ -355,7 +364,11 @@ extern int dot_symbols;
>  #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
>  
>  #define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
> -#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
> +#ifdef LINUX64_DEFAULT_ABI_ELFv2
> +#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
> +#else
> +#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
> +#endif

I agree with Joseph that it would be nice to keep the number of supported
ABIs down, if it could be old powerpc64-linux big-endian ELFv1 and powerpc64le-linux
ELFv2 only, that would be ideal.  Can little-endian and big-endian binaries
coexist on the same kernel, or will there be big endian only kernels vs.
little endian only kernels?  If they can coexist, perhaps it would be better
to use different libQUAL suffix from lib64 (lib64be?), if they can't, using lib64
is fine.  If they can coexist, then there is certainly an issue with various
shared binary files that typically some way handle different word size these
days, but not endianity (utmp/wtmp, ld.so.cache, locale-archive, various
other files).

	Jakub

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-12  3:01 ` Joseph S. Myers
@ 2013-11-12 22:22   ` Ulrich Weigand
  2013-11-12 23:47     ` Joseph S. Myers
  0 siblings, 1 reply; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-12 22:22 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

Joseph Myers wrote:
> On Mon, 11 Nov 2013, Ulrich Weigand wrote:
> > The ELFv2 ABI is the intended ABI for the new powerpc64le-linux port.
> > However, it is not inherently tied to the byte order; it it possible
> > in principle to use the ELFv2 ABI in big-endian mode too.
> 
> I'd rather, from a glibc perspective, keep down the number of variant ABIs 
> available - and in particular, disallow the (ELFv1, little-endian 
> combination) - have a compiler error given for it.  And, similarly, have 
> the (ELFv2, big-endian) combination only if the plan is for it to obsolete 
> the old ABI and for support for the old ABI for powerpc64-linux to be 
> removed from GCC and glibc in a few years' time (similarly to how the ARM 
> EABI superseded the old arm-linux-gnu ABI).  If you don't have such errors 
> in GCC, then you should have configure-time errors in glibc to disallow 
> the unsupported combinations.

Right now, we're only planning to support the existing ELFv1 big-endian
and the new ELFv2 little-endian versions.  The others are really only
present for testing purposes; note that rs6000 GCC already has a number
of ABI options that are really not intended for the end-user to play with.

It's indeed probably better to move the options to the formally undefined
category so that every use gets you a warning ...

> (Any new supported glibc configuration should of course set minimum symbol 
> version to GLIBC_2.19, or whatever the version is of the first release 
> supporting it - and the dynamic linker / ldconfig should distinguish 
> shared libraries for the two variants.)

I've just posted the ELFv2 ABI glibc patch set to libc-alpha.
 
> I didn't see anything in this series regarding the ELFv1 ABI feature 
> that's the greatest pain from a glibc perspective - the use of IBM long 
> double.  The idea of moving to IEEE binary128 was floated in 
> <https://sourceware.org/ml/libc-alpha/2013-10/msg00597.html> - have you 
> abandoned that idea?  Obviously it would be bad to end up having two 
> variants of ELFv2 with different long double formats.  (Though we can't 
> actually eliminate IBM long double support from glibc unless all ABIs with 
> it are obsoleted, including 32-bit.)  If you do move to IEEE binary128 I'd 
> advise simply using soft-fp in libgcc for the functions that normally go 
> in libgcc, given that 64-bit implies hard float, rather than the 
> arrangements some targets have of putting their binary128 functions in 
> glibc.

Well, we had been thinking about this, but right now it seems we're not
going to be able to make that change throughout the ecosystem quickly
enough, so for now, it'll probably have to remain the IBM long double.

> > Therefore, it is introduces via a new pair of options
> >    -mabi=elfv1 / -mabi=elfv2
> > where -mabi=elfv1 select the current Linux ABI, and -mabi=elfv2
> > selects the new one.
> 
> New command-line options need invoke.texi documentation.

As mentioned above, it's probably best to mark it undocumented.

> > (Of course, patches to binutils, glibc, and libffi to support the
> > new ELFv2 ABI are also required.)
> 
> And GDB - GDB needs to know how to call functions, how to pass arguments 
> to them and how to find the return value.

Yes, of course; GDB is next on the list, once the core toolchain is
operational :-)

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-12  4:31 ` [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Jakub Jelinek
@ 2013-11-12 22:33   ` Ulrich Weigand
  2013-11-12 22:34     ` Ulrich Weigand
  0 siblings, 1 reply; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-12 22:33 UTC (permalink / raw)
  To: jakub; +Cc: gcc-patches

Jakub Jelinek wrote:
> On Mon, Nov 11, 2013 at 03:40:48PM +0100, Ulrich Weigand wrote:
> > @@ -355,7 +364,11 @@ extern int dot_symbols;
> >  #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
> >  
> >  #define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
> > -#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
> > +#ifdef LINUX64_DEFAULT_ABI_ELFv2
> > +#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
> > +#else
> > +#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
> > +#endif
> 
> I agree with Joseph that it would be nice to keep the number of supported
> ABIs down, if it could be old powerpc64-linux big-endian ELFv1 and powerpc64le-linux
> ELFv2 only, that would be ideal.

Those are the only two we plan to support.

> Can little-endian and big-endian binaries
> coexist on the same kernel, or will there be big endian only kernels vs.
> little endian only kernels?  If they can coexist, perhaps it would be better
> to use different libQUAL suffix from lib64 (lib64be?), if they can't, using lib64
> is fine.  If they can coexist, then there is certainly an issue with various
> shared binary files that typically some way handle different word size these
> days, but not endianity (utmp/wtmp, ld.so.cache, locale-archive, various
> other files).

While the architecute in theory supports running big-endian and little-endian
processes at the same time, this would also require Linux kernel support;
basically, an endian-swapping system call translation layer.  We have no
plan to implement anything like this.

The kernel will be able to start up both ELFv1 and ELFv2 binaries (of the
same byte order).  However, this is only relevant for testing and possibly
bringup/transition period purposes, since we're not planning on actually
officially supporting both ABI versions in the same byte order, see above.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-12 22:33   ` Ulrich Weigand
@ 2013-11-12 22:34     ` Ulrich Weigand
  0 siblings, 0 replies; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-12 22:34 UTC (permalink / raw)
  To: jakub; +Cc: gcc-patches

Jakub Jelinek wrote:
> On Mon, Nov 11, 2013 at 03:40:48PM +0100, Ulrich Weigand wrote:
> > @@ -355,7 +364,11 @@ extern int dot_symbols;
> >  #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
> >  
> >  #define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
> > -#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
> > +#ifdef LINUX64_DEFAULT_ABI_ELFv2
> > +#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
> > +#else
> > +#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
> > +#endif
> 
> I agree with Joseph that it would be nice to keep the number of supported
> ABIs down, if it could be old powerpc64-linux big-endian ELFv1 and powerpc64le-linux
> ELFv2 only, that would be ideal.

Those are the only two we plan to support.

> Can little-endian and big-endian binaries
> coexist on the same kernel, or will there be big endian only kernels vs.
> little endian only kernels?  If they can coexist, perhaps it would be better
> to use different libQUAL suffix from lib64 (lib64be?), if they can't, using lib64
> is fine.  If they can coexist, then there is certainly an issue with various
> shared binary files that typically some way handle different word size these
> days, but not endianity (utmp/wtmp, ld.so.cache, locale-archive, various
> other files).

While the architecute in theory supports running big-endian and little-endian
processes at the same time, this would also require Linux kernel support;
basically, an endian-swapping system call translation layer.  We have no
plan to implement anything like this.

The kernel will be able to start up both ELFv1 and ELFv2 binaries (of the
same byte order).  However, this is only relevant for testing and possibly
bringup/transition period purposes, since we're not planning on actually
officially supporting both ABI versions in the same byte order, see above.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-12 22:22   ` Ulrich Weigand
@ 2013-11-12 23:47     ` Joseph S. Myers
  2013-11-14  8:00       ` Alan Modra
  2013-11-14 23:46       ` [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure) Ulrich Weigand
  0 siblings, 2 replies; 13+ messages in thread
From: Joseph S. Myers @ 2013-11-12 23:47 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On Tue, 12 Nov 2013, Ulrich Weigand wrote:

> > I didn't see anything in this series regarding the ELFv1 ABI feature 
> > that's the greatest pain from a glibc perspective - the use of IBM long 
> > double.  The idea of moving to IEEE binary128 was floated in 
> > <https://sourceware.org/ml/libc-alpha/2013-10/msg00597.html> - have you 
> > abandoned that idea?  Obviously it would be bad to end up having two 
> > variants of ELFv2 with different long double formats.  (Though we can't 
> > actually eliminate IBM long double support from glibc unless all ABIs with 
> > it are obsoleted, including 32-bit.)  If you do move to IEEE binary128 I'd 
> > advise simply using soft-fp in libgcc for the functions that normally go 
> > in libgcc, given that 64-bit implies hard float, rather than the 
> > arrangements some targets have of putting their binary128 functions in 
> > glibc.
> 
> Well, we had been thinking about this, but right now it seems we're not
> going to be able to make that change throughout the ecosystem quickly
> enough, so for now, it'll probably have to remain the IBM long double.

What's the difficulty?  GCC is supposed to support IEEE binary128 long 
double already for Power, and IEEE binary128 works much better than IBM 
long double in glibc.  The time a new ABI is being introduced is the time 
to get things right rather than suggesting yet another ABI change in 
future.

> > > Therefore, it is introduces via a new pair of options
> > >    -mabi=elfv1 / -mabi=elfv2
> > > where -mabi=elfv1 select the current Linux ABI, and -mabi=elfv2
> > > selects the new one.
> > 
> > New command-line options need invoke.texi documentation.
> 
> As mentioned above, it's probably best to mark it undocumented.

No, even always-warning options like -mabi=ibmlongdouble are documented.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-12 23:47     ` Joseph S. Myers
@ 2013-11-14  8:00       ` Alan Modra
  2013-11-14 15:22         ` Joseph S. Myers
  2013-11-14 23:46       ` [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure) Ulrich Weigand
  1 sibling, 1 reply; 13+ messages in thread
From: Alan Modra @ 2013-11-14  8:00 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Ulrich Weigand, gcc-patches

On Tue, Nov 12, 2013 at 10:33:46PM +0000, Joseph S. Myers wrote:
> On Tue, 12 Nov 2013, Ulrich Weigand wrote:
> > Well, we had been thinking about this, but right now it seems we're not
> > going to be able to make that change throughout the ecosystem quickly
> > enough, so for now, it'll probably have to remain the IBM long double.
> 
> What's the difficulty?  GCC is supposed to support IEEE binary128 long 
> double already for Power, and IEEE binary128 works much better than IBM 
> long double in glibc.  The time a new ABI is being introduced is the time 
> to get things right rather than suggesting yet another ABI change in 
> future.

The major difficulty is that we don't want to use the existing
powerpc32 parameter passing and return scheme for ieee128 (ie. pass
pointers to memory).  The thought was to pass ieee128 in vsx
registers.  This means work in gcc, in glibc, in gdb, and likely other
places, and as Uli has already said, we have time and resource
constraints.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure
  2013-11-14  8:00       ` Alan Modra
@ 2013-11-14 15:22         ` Joseph S. Myers
  0 siblings, 0 replies; 13+ messages in thread
From: Joseph S. Myers @ 2013-11-14 15:22 UTC (permalink / raw)
  To: Alan Modra; +Cc: Ulrich Weigand, gcc-patches

On Thu, 14 Nov 2013, Alan Modra wrote:

> On Tue, Nov 12, 2013 at 10:33:46PM +0000, Joseph S. Myers wrote:
> > On Tue, 12 Nov 2013, Ulrich Weigand wrote:
> > > Well, we had been thinking about this, but right now it seems we're not
> > > going to be able to make that change throughout the ecosystem quickly
> > > enough, so for now, it'll probably have to remain the IBM long double.
> > 
> > What's the difficulty?  GCC is supposed to support IEEE binary128 long 
> > double already for Power, and IEEE binary128 works much better than IBM 
> > long double in glibc.  The time a new ABI is being introduced is the time 
> > to get things right rather than suggesting yet another ABI change in 
> > future.
> 
> The major difficulty is that we don't want to use the existing
> powerpc32 parameter passing and return scheme for ieee128 (ie. pass
> pointers to memory).  The thought was to pass ieee128 in vsx
> registers.  This means work in gcc, in glibc, in gdb, and likely other
> places, and as Uli has already said, we have time and resource
> constraints.

Thanks for the explanation.  Unfortunately it seems such constraints mean 
the IBM long double support in libgcc and glibc is also undermaintained 
compared to that for all IEEE floating-point formats as used by other 
architectures (see the large pile of glibc libm test failures resulting 
from libgcc bugs, or missing features such as fmal).

(Although in theory you could use long double the same as double until 
there's time to implement binary128 support, I wouldn't really recommend 
doing that.  It's very likely new symbols involving long double have been 
added to the glibc ABI since 2.4 without the required special handling for 
symbol versioning compatibility for architectures changing long double 
format, and doing another long double transition would require identifying 
all such symbols.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure)
  2013-11-12 23:47     ` Joseph S. Myers
  2013-11-14  8:00       ` Alan Modra
@ 2013-11-14 23:46       ` Ulrich Weigand
  2013-11-15  4:28         ` David Edelsohn
  1 sibling, 1 reply; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-14 23:46 UTC (permalink / raw)
  To: Joseph S. Myers, dje.gcc; +Cc: gcc-patches

Joseph Myers wrote:
> On Tue, 12 Nov 2013, Ulrich Weigand wrote:
> > > > Therefore, it is introduces via a new pair of options
> > > >    -mabi=elfv1 / -mabi=elfv2
> > > > where -mabi=elfv1 select the current Linux ABI, and -mabi=elfv2
> > > > selects the new one.
> > > 
> > > New command-line options need invoke.texi documentation.
> > 
> > As mentioned above, it's probably best to mark it undocumented.
> 
> No, even always-warning options like -mabi=ibmlongdouble are documented.

Ah, indeed; thanks for pointing that out.  Well, that's certainly
fine with me too.

Here's a patch to add documentation along the lines of what we have
for the longdouble switches.

Doc build tested on powerpc64-linux.

David, would that be OK for mainline, or do have other suggestions?

Bye,
Ulrich

ChangeLog:

	* doc/invoke.texi (-mabi=elfv1, -mabi=elfv2): Document.

Index: gcc/gcc/doc/invoke.texi
===================================================================
--- gcc.orig/gcc/doc/invoke.texi
+++ gcc/gcc/doc/invoke.texi
@@ -18846,7 +18846,8 @@ SVR4 ABI)@.
 @opindex mabi
 Extend the current ABI with a particular extension, or remove such extension.
 Valid values are @var{altivec}, @var{no-altivec}, @var{spe},
-@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble}@.
+@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble},
+@var{elfv1}, @var{elfv2}@.
 
 @item -mabi=spe
 @opindex mabi=spe
@@ -18868,6 +18869,16 @@ This is a PowerPC 32-bit SYSV ABI option
 Change the current ABI to use IEEE extended-precision long double.
 This is a PowerPC 32-bit Linux ABI option.
 
+@item -mabi=elfv1
+@opindex mabi=elfv1
+Change the current ABI to use the ELFv1 ABI.
+This is a little-endian PowerPC 64-bit Linux ABI option.
+
+@item -mabi=elfv2
+@opindex mabi=elfv2
+Change the current ABI to use the ELFv2 ABI.
+This is a big-endian PowerPC 64-bit Linux ABI option.
+
 @item -mprototype
 @itemx -mno-prototype
 @opindex mprototype

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure)
  2013-11-14 23:46       ` [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure) Ulrich Weigand
@ 2013-11-15  4:28         ` David Edelsohn
  2013-11-15 15:28           ` Ulrich Weigand
  0 siblings, 1 reply; 13+ messages in thread
From: David Edelsohn @ 2013-11-15  4:28 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Joseph S. Myers, GCC Patches

On Thu, Nov 14, 2013 at 5:07 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote:

> Here's a patch to add documentation along the lines of what we have
> for the longdouble switches.
>
> Doc build tested on powerpc64-linux.
>
> David, would that be OK for mainline, or do have other suggestions?

I don't think that the wording is correct because -mabi=elfv1 and
-mabi=elfv2 are "options" for either endian.

> ChangeLog:
>
>         * doc/invoke.texi (-mabi=elfv1, -mabi=elfv2): Document.
>
> Index: gcc/gcc/doc/invoke.texi
> ===================================================================
> --- gcc.orig/gcc/doc/invoke.texi
> +++ gcc/gcc/doc/invoke.texi
> @@ -18846,7 +18846,8 @@ SVR4 ABI)@.
>  @opindex mabi
>  Extend the current ABI with a particular extension, or remove such extension.
>  Valid values are @var{altivec}, @var{no-altivec}, @var{spe},
> -@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble}@.
> +@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble},
> +@var{elfv1}, @var{elfv2}@.
>
>  @item -mabi=spe
>  @opindex mabi=spe
> @@ -18868,6 +18869,16 @@ This is a PowerPC 32-bit SYSV ABI option
>  Change the current ABI to use IEEE extended-precision long double.
>  This is a PowerPC 32-bit Linux ABI option.
>
> +@item -mabi=elfv1
> +@opindex mabi=elfv1
> +Change the current ABI to use the ELFv1 ABI.
> +This is a little-endian PowerPC 64-bit Linux ABI option.

Delete the second line and replace it with something like

"This is the default ABI for big-endian PowerPC 64-bit Linux.
Overriding the default ABI requires special system support and is
likely to fail in spectacular ways."

> +
> +@item -mabi=elfv2
> +@opindex mabi=elfv2
> +Change the current ABI to use the ELFv2 ABI.
> +This is a big-endian PowerPC 64-bit Linux ABI option.

Similarly, delete the second line and replace it with something like

"This is the default ABI for little-endian PowerPC 64-bit Linux.
Overriding the default ABI requires special system support and is
likely to fail in spectacular ways."

> +
>  @item -mprototype
>  @itemx -mno-prototype
>  @opindex mprototype

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure)
  2013-11-15  4:28         ` David Edelsohn
@ 2013-11-15 15:28           ` Ulrich Weigand
  0 siblings, 0 replies; 13+ messages in thread
From: Ulrich Weigand @ 2013-11-15 15:28 UTC (permalink / raw)
  To: David Edelsohn; +Cc: Joseph S. Myers, GCC Patches

David Edelsohn wrote:
> On Thu, Nov 14, 2013 at 5:07 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> 
> > Here's a patch to add documentation along the lines of what we have
> > for the longdouble switches.
> >
> > Doc build tested on powerpc64-linux.
> >
> > David, would that be OK for mainline, or do have other suggestions?
> 
> I don't think that the wording is correct because -mabi=elfv1 and
> -mabi=elfv2 are "options" for either endian.

I've checked in the following patch using your wording.

Thanks,
Ulrich

ChangeLog:

	* doc/invoke.texi (-mabi=elfv1, -mabi=elfv2): Document.

Index: gcc/gcc/doc/invoke.texi
===================================================================
--- gcc.orig/gcc/doc/invoke.texi
+++ gcc/gcc/doc/invoke.texi
@@ -18846,7 +18846,8 @@ SVR4 ABI)@.
 @opindex mabi
 Extend the current ABI with a particular extension, or remove such extension.
 Valid values are @var{altivec}, @var{no-altivec}, @var{spe},
-@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble}@.
+@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble},
+@var{elfv1}, @var{elfv2}@.
 
 @item -mabi=spe
 @opindex mabi=spe
@@ -18868,6 +18869,20 @@ This is a PowerPC 32-bit SYSV ABI option
 Change the current ABI to use IEEE extended-precision long double.
 This is a PowerPC 32-bit Linux ABI option.
 
+@item -mabi=elfv1
+@opindex mabi=elfv1
+Change the current ABI to use the ELFv1 ABI.
+This is the default ABI for big-endian PowerPC 64-bit Linux.
+Overriding the default ABI requires special system support and is
+likely to fail in spectacular ways.
+
+@item -mabi=elfv2
+@opindex mabi=elfv2
+Change the current ABI to use the ELFv2 ABI.
+This is the default ABI for little-endian PowerPC 64-bit Linux.
+Overriding the default ABI requires special system support and is
+likely to fail in spectacular ways.
+
 @item -mprototype
 @itemx -mno-prototype
 @opindex mprototype

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-11-15 14:25 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-11 14:48 [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Ulrich Weigand
2013-11-11 15:08 ` Ulrich Weigand
2013-11-12  3:01 ` Joseph S. Myers
2013-11-12 22:22   ` Ulrich Weigand
2013-11-12 23:47     ` Joseph S. Myers
2013-11-14  8:00       ` Alan Modra
2013-11-14 15:22         ` Joseph S. Myers
2013-11-14 23:46       ` [PATCH] Document -mabi=elfv[12] (Re: [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure) Ulrich Weigand
2013-11-15  4:28         ` David Edelsohn
2013-11-15 15:28           ` Ulrich Weigand
2013-11-12  4:31 ` [PATCH, rs6000] ELFv2 ABI 1/8: Add options and infrastructure Jakub Jelinek
2013-11-12 22:33   ` Ulrich Weigand
2013-11-12 22:34     ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).