rpms/gcc/devel gcc41-atomic-builtins.patch, NONE, 1.1 gcc41-ppc32-ldbl.patch, NONE, 1.1 gcc41-s390-ldbl.patch, NONE, 1.1 .cvsignore, 1.127, 1.128 gcc41.spec, 1.18, 1.19 sources, 1.129, 1.130 gcc41-ppc64-sync.patch, 1.1, NONE gcc41-pr25324.patch, 1.2, NONE gcc41-pr25717.patch, 1.2, NONE gcc41-s390-atomic1.patch, 1.1, NONE

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Sat Jan 28 10:00:04 UTC 2006


Author: jakub

Update of /cvs/dist/rpms/gcc/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv14987

Modified Files:
	.cvsignore gcc41.spec sources 
Added Files:
	gcc41-atomic-builtins.patch gcc41-ppc32-ldbl.patch 
	gcc41-s390-ldbl.patch 
Removed Files:
	gcc41-ppc64-sync.patch gcc41-pr25324.patch gcc41-pr25717.patch 
	gcc41-s390-atomic1.patch 
Log Message:
4.1.0-0.17


gcc41-atomic-builtins.patch:
 alias.c              |    9 +++++++
 alias.h              |    6 ++++
 builtins.c           |   62 ++++++++++++++++++++++++---------------------------
 config/s390/s390.c   |    1 
 config/sparc/sparc.c |    1 
 5 files changed, 47 insertions(+), 32 deletions(-)

--- NEW FILE gcc41-atomic-builtins.patch ---
2006-01-28  Jakub Jelinek  <jakub at redhat.com>

	* config/s390/s390.c (init_alignment_context): Set
	ALIAS_SET_MEMORY_BARRIER on the MEM.
	* config/sparc/sparc.c (sparc_expand_compare_and_swap_12): Likewise.

2006-01-25  Richard Henderson <rth at redhat.com>

	* alias.h (ALIAS_SET_MEMORY_BARRIER): New.
	* alias.c (true_dependence): Respect it.
	(canon_true_dependence, write_dependence_p): Likewise.
	* builtins.c (get_builtin_sync_mem): Set it.

2006-01-03  Adrian Straetling  <straetling at de.ibm.com>

	* gcc/builtins.c (get_builtin_sync_mem): New function.
	(expand_builtin_sync_operation, expand_builtin_compare_and_swap,
	expand_builtin_lock_test_and_set, expand_builtin_lock_release):
	Call get_builtin_sync_mem to generate mem rtx.

--- gcc/config/s390/s390.c.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/config/s390/s390.c	2006-01-28 10:29:03.000000000 +0100
@@ -4030,6 +4030,7 @@ init_alignment_context (struct alignment
       /* Generate MEM.  */
       ac->memsi = gen_rtx_MEM (SImode, align);
       MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
+      set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
       set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
 
       /* Calculate shiftcount.  */
--- gcc/config/sparc/sparc.c.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/config/sparc/sparc.c	2006-01-28 10:29:46.000000000 +0100
@@ -8734,6 +8734,7 @@ sparc_expand_compare_and_swap_12 (rtx re
 			  gen_rtx_AND (SImode, addr1, GEN_INT (3))));
 
   memsi = gen_rtx_MEM (SImode, addr);
+  set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
   MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
 
   val = force_reg (SImode, memsi);
--- gcc/builtins.c.jj	2006-01-28 09:54:07.000000000 +0100
+++ gcc/builtins.c	2006-01-28 10:25:33.000000000 +0100
@@ -5425,6 +5425,28 @@ get_builtin_sync_mode (int fcode_diff)
   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
 }
 
+/* Expand the memory expression LOC and return the appropriate memory operand
+   for the builtin_sync operations.  */
+
+static rtx
+get_builtin_sync_mem (tree loc, enum machine_mode mode)
+{
+  rtx addr, mem;
+
+  addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
+
+  /* Note that we explicitly do not want any alias information for this
+     memory, so that we kill all other live memories.  Otherwise we don't
+     satisfy the full barrier semantics of the intrinsic.  */
+  mem = validize_mem (gen_rtx_MEM (mode, addr));
+
+  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
+  set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
+  MEM_VOLATILE_P (mem) = 1;
+
+  return mem;
+}
+
 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
    ARGLIST is the operands list to the function.  CODE is the rtx code 
    that corresponds to the arithmetic or logical operation from the name;
@@ -5438,20 +5460,14 @@ expand_builtin_sync_operation (enum mach
 			       enum rtx_code code, bool after,
 			       rtx target, bool ignore)
 {
-  rtx addr, val, mem;
+  rtx val, mem;
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
+  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
 
   arglist = TREE_CHAIN (arglist);
   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
 
-  /* Note that we explicitly do not want any alias information for this
-     memory, so that we kill all other live memories.  Otherwise we don't
-     satisfy the full barrier semantics of the intrinsic.  */
-  mem = validize_mem (gen_rtx_MEM (mode, addr));
-  MEM_VOLATILE_P (mem) = 1;
-
   if (ignore)
     return expand_sync_operation (mem, val, code);
   else
@@ -5467,10 +5483,10 @@ static rtx
 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
 				 bool is_bool, rtx target)
 {
-  rtx addr, old_val, new_val, mem;
+  rtx old_val, new_val, mem;
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
+  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
 
   arglist = TREE_CHAIN (arglist);
   old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
@@ -5478,12 +5494,6 @@ expand_builtin_compare_and_swap (enum ma
   arglist = TREE_CHAIN (arglist);
   new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
 
-  /* Note that we explicitly do not want any alias information for this
-     memory, so that we kill all other live memories.  Otherwise we don't
-     satisfy the full barrier semantics of the intrinsic.  */
-  mem = validize_mem (gen_rtx_MEM (mode, addr));
-  MEM_VOLATILE_P (mem) = 1;
-
   if (is_bool)
     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
   else
@@ -5500,20 +5510,14 @@ static rtx
 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
 				  rtx target)
 {
-  rtx addr, val, mem;
+  rtx val, mem;
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
+  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
 
   arglist = TREE_CHAIN (arglist);
   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
 
-  /* Note that we explicitly do not want any alias information for this
-     memory, so that we kill all other live memories.  Otherwise we don't
-     satisfy the barrier semantics of the intrinsic.  */
-  mem = validize_mem (gen_rtx_MEM (mode, addr));
-  MEM_VOLATILE_P (mem) = 1;
-
   return expand_sync_lock_test_and_set (mem, val, target);
 }
 
@@ -5547,17 +5551,11 @@ static void
 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
 {
   enum insn_code icode;
-  rtx addr, mem, insn;
+  rtx mem, insn;
   rtx val = const0_rtx;
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
-
-  /* Note that we explicitly do not want any alias information for this
-     memory, so that we kill all other live memories.  Otherwise we don't
-     satisfy the barrier semantics of the intrinsic.  */
-  mem = validize_mem (gen_rtx_MEM (mode, addr));
-  MEM_VOLATILE_P (mem) = 1;
+  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
 
   /* If there is an explicit operation in the md file, use it.  */
   icode = sync_lock_release[mode];
--- gcc/alias.c.jj	2006-01-28 09:54:07.000000000 +0100
+++ gcc/alias.c	2006-01-28 10:25:33.000000000 +0100
@@ -2209,6 +2209,9 @@ true_dependence (rtx mem, enum machine_m
     return 1;
   if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return 1;
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
 
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
@@ -2282,6 +2285,9 @@ canon_true_dependence (rtx mem, enum mac
     return 1;
   if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return 1;
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
 
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
@@ -2341,6 +2347,9 @@ write_dependence_p (rtx mem, rtx x, int 
     return 1;
   if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return 1;
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
 
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
--- gcc/alias.h.jj	2006-01-28 09:54:07.000000000 +0100
+++ gcc/alias.h	2006-01-28 10:25:33.000000000 +0100
@@ -27,4 +27,10 @@ extern HOST_WIDE_INT get_frame_alias_set
 extern void record_base_value (unsigned int, rtx, int);
 extern bool component_uses_parent_alias_set (tree);
 
+/* This alias set can be used to force a memory to conflict with all
+   other memories, creating a barrier across which no memory reference
+   can move.  Note that there are other legacy ways to create such
+   memory barriers, including an address of SCRATCH.  */
+#define ALIAS_SET_MEMORY_BARRIER	((HOST_WIDE_INT) -1)
+
 #endif /* GCC_ALIAS_H */

gcc41-ppc32-ldbl.patch:
 config/fp-bit.h                    |    4 +
 config/rs6000/aix.h                |    2 
 config/rs6000/darwin-ldouble.c     |    5 +
 config/rs6000/darwin.h             |    2 
 config/rs6000/libgcc-ppc-glibc.ver |   31 ++++++++++
 config/rs6000/linux.h              |    2 
 config/rs6000/linux64.h            |    2 
 config/rs6000/ppc64-fp.c           |    1 
 config/rs6000/rs6000.c             |  107 ++++++++++++++++++++++---------------
 config/rs6000/rs6000.h             |    6 +-
 config/rs6000/rs6000.md            |   36 ++++++------
 config/rs6000/sysv4.h              |    7 ++
 config/rs6000/t-linux64            |   14 ----
 config/rs6000/t-ppccomm            |   14 ++++
 doc/invoke.texi                    |   32 +++++++----
 libgcc-std.ver                     |    4 +
 mklibgcc.in                        |    2 
 17 files changed, 181 insertions(+), 90 deletions(-)

--- NEW FILE gcc41-ppc32-ldbl.patch ---
2006-01-27  Jakub Jelinek  <jakub at redhat.com>

	PR target/25864
	* libgcc-std.ver: Add GCC_4.1.0 symbol version.
	* config/rs6000/t-linux64 (TARGET_LIBGCC2_CFLAGS): Only append
	-mno-minimal-toc to previous content.
	(bispecs): Remove goal.
	* config/rs6000/ppc64-fp.c: Define TMODES before including fp-bit.h.
	* config/rs6000/darwin-ldouble.c: Don't provide _xlq*@GCC_3.4
	compatibility aliases on powerpc-*-*gnu*.
	* config/rs6000/libgcc-ppc-glibc.ver: New file.
	* config/rs6000/t-ppccomm (SHLIB_MAPFILES): Append
	libgcc-ppc-glibc.ver on powerpc*-*-*gnu*.
	(TARGET_LIBGCC2_CFLAGS): Append -specs=ldblspecs.
	(ldblspecs): New goal.
	* config/rs6000/t-linux64 (SHLIB_MAPFILES): Removed.
	* mklibgcc.in: If $TPBIT is empty, don't compile _sf_to_tf and
	_df_to_tf.
	* config/fp-bit.h (TMODES): Don't define if none of TFLOAT,
	L_sf_to_tf or L_df_to_tf is defined.

2006-01-27  David Edelsohn  <edelsohn at gnu.org>
	    Alan Modra  <amodra at bigpond.net.au>

	PR target/25864
	* config/rs6000/linux.h (POWERPC_LINUX): Define.
	* config/rs6000/linux64.h (POWERPC_LINUX): Define.
	* config/rs6000/darwin-ldouble.c: Build on 32-bit PowerPC.
	* config/rs6000/darwin.h (TARGET_IEEEQUAD): Define to zero.
	* config/rs6000/aix.h (TARGET_IEEEQUAD): Define to zero.
	* config/rs6000/rs6000.c (rs6000_ieeequad): New variable.
	(rs6000_override_options): Initialize rs6000_ieeequad.
	Initialize TFmode format to ibm_extended_format if not
	TARGET_IEEEQUAD.
	(rs6000_handle_option): Accept -mabi= ibmlongdouble and
	ieeelongdouble.
	(rs6000_emit_move): Move !TARGET_IEEEQUAD as two parts.
	(rs6000_return_in_memory): Only return IEEEQUAD in memory.
	(function_arg_advance): IBM long double passed in two FPRs, not
	split.
	(function_arg): IBM long double passed in FPRs.
	(rs6000_pass_by_reference): Only IEEEQUAD passed by reference.
	(rs6000_gimplify_va_arg): IBM long double passed in two FPRs.
	Only multireg GPR aligned.
	(rs6000_init_libfuncs): Enable IBM long double functions if not
	IEEEQUAD.
	(rs6000_generate_compare): Use IBM long double compare if not
	TARGET_IEEEQUAD.
	* config/rs6000/rs6000.h (rs6000_ieeequad): Declare.
	(TARGET_IEEEQUAD): Define.
	(CANNOT_CHANGE_MODE_CLASS): Any mode larger than doubleword if
	not TARGET_IEEEQUAD.
	* config/rs6000/rs6000.md: Enable TFmode patterns if
	!TARGET_IEEEQUAD.
	* config/rs6000/t-ppccomm (LIB2FUNCS_EXTRA): Add darwin-ldouble.c.
	* config/rs6000/svr4.h (SUBTARGET_OVERRIDE_OPTIONS): -msoft-float
	and -mlong-double-128 are incompatible.
	* doc/invoke.texi (-mabi): Collect options together.  Add
	ibmlongdouble and ieeelongdouble.

--- gcc/doc/invoke.texi.jj	2006-01-28 09:53:43.000000000 +0100
+++ gcc/doc/invoke.texi	2006-01-28 10:33:14.000000000 +0100
@@ -11032,16 +11032,6 @@ enhancements.
 @opindex mno-vrsave
 Generate VRSAVE instructions when generating AltiVec code.
 
- at item -mabi=spe
- at opindex mabi=spe
-Extend the current ABI with SPE ABI extensions.  This does not change
-the default ABI, instead it adds the SPE ABI extensions to the current
-ABI at .
-
- at item -mabi=no-spe
- at opindex mabi=no-spe
-Disable Booke SPE ABI extensions for the current ABI at .
-
 @item -msecure-plt
 @opindex msecure-plt
 Generate code that allows ld and ld.so to build executables and shared
@@ -11395,7 +11385,27 @@ 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},
- at var{no-spe}@.
+ at var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble}@.
+
+ at item -mabi=spe
+ at opindex mabi=spe
+Extend the current ABI with SPE ABI extensions.  This does not change
+the default ABI, instead it adds the SPE ABI extensions to the current
+ABI at .
+
+ at item -mabi=no-spe
+ at opindex mabi=no-spe
+Disable Booke SPE ABI extensions for the current ABI at .
+
+ at item -mabi=ibmlongdouble
+ at opindex mabi=ibmlongdouble
+Change the current ABI to use IBM extended precision long double.
+This is a PowerPC 32-bit SYSV ABI option.
+
+ at item -mabi=ieeelongdouble
+ at opindex mabi=ieeelongdouble
+Change the current ABI to use IEEE extended precision long double.
+This is a PowerPC 32-bit Linux ABI option.
 
 @item -mprototype
 @itemx -mno-prototype
--- gcc/config/rs6000/darwin.h.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/darwin.h	2006-01-28 10:33:14.000000000 +0100
@@ -313,6 +313,8 @@ do {									\
 /* Darwin only runs on PowerPC, so short-circuit POWER patterns.  */
 #undef  TARGET_POWER
 #define TARGET_POWER 0
+#undef  TARGET_IEEEQUAD
+#define TARGET_IEEEQUAD 0
 
 /* Since Darwin doesn't do TOCs, stub this out.  */
 
--- gcc/config/rs6000/libgcc-ppc-glibc.ver.jj	2006-01-28 10:33:14.000000000 +0100
+++ gcc/config/rs6000/libgcc-ppc-glibc.ver	2006-01-28 10:33:14.000000000 +0100
@@ -0,0 +1,31 @@
+%ifndef _SOFT_FLOAT
+%ifndef __powerpc64__
+%exclude {
+  __multc3
+  __divtc3
+  __powitf2
+  __fixtfdi
+  __fixunstfdi
+  __floatditf
+}
+
+GCC_4.1.0 {
+  # long double support
+  __multc3
+  __divtc3
+  __powitf2
+  __fixtfdi
+  __fixunstfdi
+  __floatditf
+
+%else
+GCC_3.4.4 {
+%endif
+
+  # long double support
+  __gcc_qadd
+  __gcc_qsub
+  __gcc_qmul
+  __gcc_qdiv
+}
+%endif
--- gcc/config/rs6000/rs6000.c.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2006-01-28 10:33:14.000000000 +0100
@@ -158,10 +158,13 @@ enum rs6000_nop_insertion rs6000_sched_i
 /* Support targetm.vectorize.builtin_mask_for_load.  */
 static GTY(()) tree altivec_builtin_mask_for_load;
 
-/* Size of long double */
+/* Size of long double.  */
 int rs6000_long_double_type_size;
 
-/* Whether -mabi=altivec has appeared */
+/* IEEE quad extended precision long double. */
+int rs6000_ieeequad;
+
+/* Whether -mabi=altivec has appeared.  */
 int rs6000_altivec_abi;
 
 /* Nonzero if we want SPE ABI extensions.  */
@@ -1286,6 +1289,11 @@ rs6000_override_options (const char *def
   if (!rs6000_explicit_options.long_double)
     rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
 
+#ifndef POWERPC_LINUX
+  if (!rs6000_explicit_options.abi)
+    rs6000_ieeequad = 1;
+#endif
+
   /* Set Altivec ABI as default for powerpc64 linux.  */
   if (TARGET_ELF && TARGET_64BIT)
     {
@@ -1399,8 +1407,7 @@ rs6000_override_options (const char *def
   if (!rs6000_explicit_options.aix_struct_ret)
     aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
 
-  if (TARGET_LONG_DOUBLE_128
-      && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
+  if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
     REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
 
   /* Allocate an alias set for register saves & restores from stack.  */
@@ -1772,6 +1779,17 @@ rs6000_handle_option (size_t code, const
 	  warning (0, "Using old darwin ABI");
 	}
 
+      else if (! strcmp (arg, "ibmlongdouble"))
+	{
+	  rs6000_ieeequad = 0;
+	  warning (0, "Using IBM extended precision long double");
+	}
+      else if (! strcmp (arg, "ieeelongdouble"))
+	{
+	  rs6000_ieeequad = 1;
+	  warning (0, "Using IEEE extended precision long double");
+	}
+
       else
 	{
 	  error ("unknown ABI specified: '%s'", arg);
@@ -3885,7 +3903,7 @@ rs6000_emit_move (rtx dest, rtx source, 
 
   /* 128-bit constant floating-point values on Darwin should really be
      loaded as two parts.  */
-  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  if (!TARGET_IEEEQUAD
       && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
       && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
     {
@@ -4209,7 +4227,7 @@ rs6000_return_in_memory (tree type, tree
       return true;
     }
 
-  if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
+  if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
     return true;
 
   return false;
@@ -4596,13 +4614,15 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode))
+	  && (mode == SFmode || mode == DFmode
+	      || (mode == TFmode && !TARGET_IEEEQUAD)))
 	{
-	  if (cum->fregno <= FP_ARG_V4_MAX_REG)
-	    cum->fregno++;
+	  if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
+	    cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
 	  else
 	    {
-	      if (mode == DFmode)
+	      cum->fregno = FP_ARG_V4_MAX_REG + 1;
+	      if (mode == DFmode || mode == TFmode)
 		cum->words += cum->words & 1;
 	      cum->words += rs6000_arg_size (mode, type);
 	    }
@@ -5127,9 +5147,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode))
+	  && (mode == SFmode || mode == DFmode
+	      || (mode == TFmode && !TARGET_IEEEQUAD)))
 	{
-	  if (cum->fregno <= FP_ARG_V4_MAX_REG)
+	  if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
 	    return gen_rtx_REG (mode, cum->fregno);
 	  else
 	    return NULL_RTX;
@@ -5332,7 +5353,7 @@ rs6000_pass_by_reference (CUMULATIVE_ARG
 			  enum machine_mode mode, tree type,
 			  bool named ATTRIBUTE_UNUSED)
 {
-  if (DEFAULT_ABI == ABI_V4 && mode == TFmode)
+  if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
     {
       if (TARGET_DEBUG_ARG)
 	fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
@@ -5783,14 +5804,16 @@ rs6000_gimplify_va_arg (tree valist, tre
   align = 1;
 
   if (TARGET_HARD_FLOAT && TARGET_FPRS
-      && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
+      && (TYPE_MODE (type) == SFmode
+	  || TYPE_MODE (type) == DFmode
+	  || TYPE_MODE (type) == TFmode))
     {
       /* FP args go in FP registers, if present.  */
       reg = fpr;
-      n_reg = 1;
+      n_reg = (size + 7) / 8;
       sav_ofs = 8*4;
       sav_scale = 8;
-      if (TYPE_MODE (type) == DFmode)
+      if (TYPE_MODE (type) != SFmode)
 	align = 8;
     }
   else
@@ -5822,7 +5845,7 @@ rs6000_gimplify_va_arg (tree valist, tre
 	 As are any other 2 gpr item such as complex int due to a
 	 historical mistake.  */
       u = reg;
-      if (n_reg == 2)
+      if (n_reg == 2 && reg == gpr)
 	{
 	  u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
 		     size_int (n_reg - 1));
@@ -9028,33 +9051,32 @@ rs6000_init_libfuncs (void)
   if (!TARGET_HARD_FLOAT)
     return;
 
-  if (DEFAULT_ABI != ABI_V4)
+  if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
+      && !TARGET_POWER2 && !TARGET_POWERPC)
     {
-      if (TARGET_XCOFF && ! TARGET_POWER2 && ! TARGET_POWERPC)
-	{
-	  /* AIX library routines for float->int conversion.  */
-	  set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
-	  set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
-	  set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
-	  set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
-	}
+      /* AIX library routines for float->int conversion.  */
+      set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
+      set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
+      set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
+      set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
+    }
 
+  if (!TARGET_IEEEQUAD)
       /* AIX/Darwin/64-bit Linux quad floating point routines.  */
-      if (!TARGET_XL_COMPAT)
-	{
-	  set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
-	  set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
-	  set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
-	  set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
-	}
-      else
-	{
-	  set_optab_libfunc (add_optab, TFmode, "_xlqadd");
-	  set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
-	  set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
-	  set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
-	}
-    }
+    if (!TARGET_XL_COMPAT)
+      {
+	set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
+	set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
+	set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
+	set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
+      }
+    else
+      {
+	set_optab_libfunc (add_optab, TFmode, "_xlqadd");
+	set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
+	set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
+	set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
+      }
   else
     {
       /* 32-bit SVR4 quad floating point routines.  */
@@ -11089,7 +11111,7 @@ rs6000_generate_compare (enum rtx_code c
 	 CLOBBERs to match cmptf_internal2 pattern.  */
       if (comp_mode == CCFPmode && TARGET_XL_COMPAT
 	  && GET_MODE (rs6000_compare_op0) == TFmode
-	  && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+	  && !TARGET_IEEEQUAD
 	  && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
 	emit_insn (gen_rtx_PARALLEL (VOIDmode,
 	  gen_rtvec (9,
@@ -18873,6 +18895,7 @@ rs6000_function_value (tree valtype, tre
 						   GP_ARG_RETURN + 3),
 				      GEN_INT (12))));
     }
+
   if ((INTEGRAL_TYPE_P (valtype)
        && TYPE_PRECISION (valtype) < BITS_PER_WORD)
       || POINTER_TYPE_P (valtype))
--- gcc/config/rs6000/linux64.h.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/linux64.h	2006-01-28 10:33:14.000000000 +0100
@@ -568,3 +568,5 @@ while (0)
    ppc64 glibc provides it at -0x7010(13).  */
 #define TARGET_THREAD_SSP_OFFSET	(TARGET_64BIT ? -0x7010 : -0x7008)
 #endif
+
+#define POWERPC_LINUX
--- gcc/config/rs6000/darwin-ldouble.c.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/darwin-ldouble.c	2006-01-28 10:33:14.000000000 +0100
@@ -48,7 +49,7 @@ Software Foundation, 51 Franklin Street,
 
    This code currently assumes big-endian.  */
 
-#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__) || defined (_AIX))
+#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__) || defined (__powerpc__) || defined (_AIX))
 
 #define fabs(x) __builtin_fabs(x)
 #define isless(x, y) __builtin_isless (x, y)
@@ -67,7 +68,8 @@ extern long double __gcc_qsub (double, d
 extern long double __gcc_qmul (double, double, double, double);
 extern long double __gcc_qdiv (double, double, double, double);
 
-#if defined __ELF__ && defined SHARED
+#if defined __ELF__ && defined SHARED \
+    && (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__))
 /* Provide definitions of the old symbol names to satisfy apps and
    shared libs built against an older libgcc.  To access the _xlq
    symbols an explicit version reference is needed, so these won't
--- gcc/config/rs6000/t-linux64.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/t-linux64	2006-01-28 10:33:14.000000000 +0100
@@ -4,9 +4,7 @@
 LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
 	$(srcdir)/config/rs6000/darwin-ldouble.c
 
-TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC -specs=bispecs
-
-SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-ppc64.ver
+TARGET_LIBGCC2_CFLAGS += -mno-minimal-toc
 
 MULTILIB_OPTIONS        = m64/m32 msoft-float
 MULTILIB_DIRNAMES       = 64 32 nof
@@ -32,13 +30,3 @@ fp-bit32.c: $(srcdir)/config/fp-bit.c
 	  echo '#define FLOAT'; \
 	  cat $(srcdir)/config/fp-bit.c; \
 	  echo '#endif' ) > fp-bit32.c
-
-# Hack to use -mlong-double-128 just for compiling 64 bit libgcc
-mklibgcc: bispecs
-
-bispecs: specs
-	if [ x`$(GCC_FOR_TARGET) -print-multi-os-directory` = x../lib ]; then \
-	  sed -e '/cc1_options/{ n; s/$$/ %{m64:-mlong-double-128}/; }' < specs > $@; \
-	else \
-	  sed -e '/cc1_options/{ n; s/$$/ %{!m32:-mlong-double-128}/; }' < specs > $@; \
-	fi
--- gcc/config/rs6000/rs6000.h.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/rs6000.h	2006-01-28 10:33:14.000000000 +0100
@@ -291,6 +292,7 @@ extern const char *rs6000_traceback_name
 /* These are separate from target_flags because we've run out of bits
    there.  */
 extern int rs6000_long_double_type_size;
+extern int rs6000_ieeequad;
 extern int rs6000_altivec_abi;
 extern int rs6000_spe_abi;
 extern int rs6000_float_gprs;
@@ -316,6 +318,7 @@ extern enum rs6000_nop_insertion rs6000_
 #endif
 
 #define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
+#define TARGET_IEEEQUAD rs6000_ieeequad
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
 
 #define TARGET_SPE_ABI 0
@@ -1214,8 +1217,8 @@ enum reg_class
 /* Return a class of registers that cannot change FROM mode to TO mode.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)			  \
-  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)		  \
-    && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8)		  \
+  (!TARGET_IEEEQUAD							  \
+   && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8		  \
    ? 0									  \
    : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)				  \
    ? reg_classes_intersect_p (FLOAT_REGS, CLASS)			  \
--- gcc/config/rs6000/t-ppccomm.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/t-ppccomm	2006-01-28 10:33:14.000000000 +0100
@@ -1,6 +1,6 @@
 # Common support for PowerPC ELF targets (both EABI and SVR4).
 
-LIB2FUNCS_EXTRA = tramp.S
+LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
 
 # This one can't end up in shared libgcc
 LIB2FUNCS_STATIC_EXTRA = eabi.S
@@ -11,6 +11,18 @@ eabi.S: $(srcdir)/config/rs6000/eabi.asm
 tramp.S: $(srcdir)/config/rs6000/tramp.asm
 	cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
 
+ifneq (,$findstring gnu,$(target))
+TARGET_LIBGCC2_CFLAGS += -specs=ldblspecs
+
+SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-ppc-glibc.ver
+
+# Hack to use -mlong-double-128 only when not compiling nof libgcc
+mklibgcc: ldblspecs
+
+ldblspecs: specs
+	sed -e '/cc1_options/{ n; s/$$/ %{!msoft-float:-mlong-double-128}/; }' < specs > $@
+endif
+
 # Switch synonyms
 MULTILIB_MATCHES_ENDIAN	= mlittle=mlittle-endian mbig=mbig-endian
 MULTILIB_MATCHES_SYSV	= mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi mcall-sysv=mcall-linux mcall-sysv=mcall-netbsd
--- gcc/config/rs6000/ppc64-fp.c.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/ppc64-fp.c	2006-01-28 10:33:14.000000000 +0100
@@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street,
 02110-1301, USA.  */
 
 #if defined(__powerpc64__)
+#define TMODES
 #include "config/fp-bit.h"
 
 extern DItype __fixtfdi (TFtype);
--- gcc/config/rs6000/rs6000.md.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/rs6000.md	2006-01-28 10:33:14.000000000 +0100
@@ -151,7 +152,7 @@
 ; Any hardware-supported floating-point mode
 (define_mode_macro FP [(SF "TARGET_HARD_FLOAT")
   (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
-  (TF "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  (TF "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")])
 
 ; Various instructions that come in SI and DI forms.
@@ -7785,7 +7786,7 @@
 (define_expand "movtf"
   [(set (match_operand:TF 0 "general_operand" "")
 	(match_operand:TF 1 "any_operand" ""))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
 
@@ -7795,7 +7796,7 @@
 (define_insn_and_split "*movtf_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r")
 	(match_operand:TF 1 "input_operand"         "f,o,f,YGHF,r,r"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
    && (gpc_reg_operand (operands[0], TFmode)
        || gpc_reg_operand (operands[1], TFmode))"
@@ -7809,7 +7810,7 @@
   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
 		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
 	      (use (match_dup 2))])]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
 {
   operands[2] = CONST0_RTX (DFmode);
@@ -7819,7 +7820,7 @@
   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
        (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
    (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
@@ -7837,7 +7838,7 @@
 (define_expand "extendsftf2"
   [(set (match_operand:TF 0 "nonimmediate_operand" "")
 	(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
 {
   rtx tmp = gen_reg_rtx (DFmode);
@@ -7849,14 +7850,14 @@
 (define_expand "trunctfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "")
 
 (define_insn_and_split "trunctfdf2_internal1"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
 	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT
+  "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "@
    #
@@ -7872,7 +7873,7 @@
 (define_insn "trunctfdf2_internal2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT
+  "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")])
@@ -7881,7 +7882,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
    (clobber (match_scratch:DF 2 "=f"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
@@ -7894,7 +7895,7 @@
 (define_expand "floatsitf2"
   [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
         (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
 {
   rtx tmp = gen_reg_rtx (DFmode);
@@ -7922,7 +7923,7 @@
 	      (clobber (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))])]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && (TARGET_POWER2 || TARGET_POWERPC)
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
 {
@@ -7939,7 +7940,7 @@
    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
    (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 5 "memory_operand" "=o"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
   "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[5]))"
@@ -7960,7 +7961,7 @@
 (define_insn "negtf2"
   [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
 	(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "*
 {
@@ -7975,7 +7976,7 @@
 (define_expand "abstf2"
   [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
 	(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "
 {
@@ -7995,7 +7996,7 @@
 			   (label_ref (match_operand 2 "" ""))
 			   (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "
 {
@@ -10934,7 +10935,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
 		      (match_operand:TF 2 "gpc_reg_operand" "f")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT
+  "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
@@ -10952,7 +10953,7 @@
     (clobber (match_scratch:DF 8 "=f"))
     (clobber (match_scratch:DF 9 "=f"))
     (clobber (match_scratch:DF 10 "=f"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT
+  "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
--- gcc/config/rs6000/aix.h.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/aix.h	2006-01-28 10:33:14.000000000 +0100
@@ -38,6 +38,8 @@
 #define TARGET_ALTIVEC 0
 #undef  TARGET_ALTIVEC_ABI
 #define TARGET_ALTIVEC_ABI 0
+#undef  TARGET_IEEEQUAD
+#define TARGET_IEEEQUAD 0
 
 /* The AIX linker will discard static constructors in object files before
    collect has a chance to see them, so scan the object files directly.  */
--- gcc/config/rs6000/linux.h.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/linux.h	2006-01-28 10:33:14.000000000 +0100
@@ -118,3 +118,5 @@
 /* ppc32 glibc provides __stack_chk_guard in -0x7008(2).  */
 #define TARGET_THREAD_SSP_OFFSET	-0x7008
 #endif
+
+#define POWERPC_LINUX
--- gcc/config/rs6000/sysv4.h.jj	2006-01-28 09:54:04.000000000 +0100
+++ gcc/config/rs6000/sysv4.h	2006-01-28 10:33:14.000000000 +0100
@@ -215,6 +215,13 @@ do {									\
       error ("-msecure-plt not supported by your assembler");		\
     }									\
 									\
+  if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128)			\
+    {									\
+      rs6000_long_double_type_size = 64;				\
+      if (rs6000_explicit_options.long_double)				\
+	warning (0, "soft-float and long-double-128 are incompatible");	\
+    }									\
+									\
   /* Treat -fPIC the same as -mrelocatable.  */				\
   if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX)				\
     target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \
--- gcc/config/fp-bit.h.jj	2006-01-28 09:54:06.000000000 +0100
+++ gcc/config/fp-bit.h	2006-01-28 10:33:14.000000000 +0100
@@ -87,7 +87,9 @@ Boston, MA 02110-1301, USA.  */
 #endif /* ! FINE_GRAINED_LIBRARIES */
 
 #if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106
-# define TMODES
+# if defined(TFLOAT) || defined(L_sf_to_tf) || defined(L_df_to_tf)
+#  define TMODES
+# endif
 #endif
 
 typedef float SFtype __attribute__ ((mode (SF)));
--- gcc/libgcc-std.ver.jj	2006-01-28 09:54:08.000000000 +0100
+++ gcc/libgcc-std.ver	2006-01-28 10:33:48.000000000 +0100
@@ -252,3 +252,7 @@ GCC_4.0.0 {
   __mulxc3
   __multc3
 }
+
+%inherit GCC_4.1.0 GCC_4.0.0
+GCC_4.1.0 {
+}
--- gcc/mklibgcc.in.jj	2006-01-28 09:54:07.000000000 +0100
+++ gcc/mklibgcc.in	2006-01-28 10:36:26.000000000 +0100
@@ -315,6 +316,7 @@ for ml in $MULTILIBS; do
 
   if [ "$FPBIT" ]; then
     for name in $FPBIT_FUNCS; do
+      [ "$name" = _sf_to_tf -a -z "$TPBIT" ] && continue
       if [ "$libgcc_s_so" ]; then
 	out="libgcc/${dir}/${name}${objext}"
 	outS="libgcc/${dir}/${name}_s${objext}"
@@ -345,6 +347,7 @@ for ml in $MULTILIBS; do
 
   if [ "$DPBIT" ]; then
     for name in $DPBIT_FUNCS; do
+      [ "$name" = _df_to_tf -a -z "$TPBIT" ] && continue
       if [ "$libgcc_s_so" ]; then
 	out="libgcc/${dir}/${name}${objext}"
 	outS="libgcc/${dir}/${name}_s${objext}"

gcc41-s390-ldbl.patch:
 2084.md          |   42 ++++-
 libgcc-glibc.ver |   33 +++
 s390.c           |   58 ++++++
 s390.h           |   46 ++++-
 s390.md          |  457 ++++++++++++++++++++++++++++++++++++++++---------------
 s390.opt         |    8 
 t-crtstuff       |    1 
 7 files changed, 506 insertions(+), 139 deletions(-)

--- NEW FILE gcc41-s390-ldbl.patch ---
2006-01-27  Andreas Krebbel  <krebbel1 at de.ibm.com>
            Ulrich Weigand  <uweigand at de.ibm.com>

	* config/s390/2084.md ("x_fsimptf", "x_fmultf", "x_fdivtf",
	"x_floadtf", "x_ftrunctf", "x_ftruncdf"): New insn reservations.
	* config/s390/s390.c (struct processor_costs): Add mxbr, sqxbr, dxbr 
	and dxr fields.
	(z900_cost, z990_cost, z9_109_cost): Values for the new fields added.
	(s390_rtx_costs): Use the new fields to calculate rtx costs.
	(s390_secondary_input_reload_class, s390_secondary_output_reload_class):
	Define secondary reloads for TFmode moves.
	(constant_modes): Add TFmode.
	(NR_C_MODES): Set to 8.
	* config/s390/s390.h (TARGET_CPU_CPP_BUILTINS): Add __LONG_DOUBLE_128__
	builtin define.
	(LONG_DOUBLE_TYPE_SIZE): Set to 128 or 64.
	(LIBGCC2_LONG_DOUBLE_TYPE_SIZE, WIDEST_HARDWARE_FP_SIZE): Define.
	(HARD_REGNO_NREGS, HARD_REGNO_MODE_OK, CLASS_MAX_NREGS, 
	CANNOT_CHANGE_MODE_CLASS): Consider TFmode.
	* config/s390/s390.md ("type" attribute): Add fsimptf, floadtf, fmultf, 
	fdivtf, fsqrttf, ftrunctf, ftruncdf as possible values.
	(FPR mode macro): Add TFmode.
	(DSF mode macro): New.
	(<de>, <dee> mode attributes): Removed.
	(<xde>, <xdee>, <RRe>, <RXe>, <Rf> mode attributes): New.
	("*cmp<mode>_ccs_0", "*cmp<mode>_ccs_0_ibm", "*cmp<mode>_ccs", 
	"*cmp<mode>_ccs_ibm", "fix_trunc<FPR:mode><GPR:mode>2_ieee", 
	"floatdi<mode>2", "floatsi<mode>2_ieee", "*add<mode>3", 
	"*add<mode>3_cc", "*add<mode>3_cconly", "*add<mode>3_ibm", 
	"*sub<mode>3", "*sub<mode>3_cc", "*sub<mode>3_cconly", 
	"*sub<mode>3_ibm", "*mul<mode>3_ibm", "*fmadd<mode>", "*fmsub<mode>",
	"*div<mode>3", "*div<mode>3_ibm", "*neg<mode>2_cc", 
	"*neg<mode>2_cconly", "*neg<mode>2", "*neg<mode>2_ibm", 
	"*abs<mode>2_cc", "*abs<mode>2_cconly", "*abs<mode>2",
	"*abs<mode>2_ibm", "*negabs<mode>2_cc", "*negabs<mode>2_cconly", 
	"*negabs<mode>2", "sqrt<mode>2"):
	Changed <de> to <xde>. R constraint replaced by <Rf>.
	("*mul<mode>3"): Changed <dee> to <xdee>. R constraint replaced by 
	<Rf>.
	("fix_trunc<FPR:mode>di2"): 'FPR:' removed.
        ("*fmadd<mode>", "*fmsub<mode>"): FPR mode replaced by DSF.
	("movtf"): New insn definition followed by 2 new splitters.
	("reload_outtf", "reload_intf", "trunctfdf2", "trunctfsf2", 
	"extenddftf2", "extendsftf2"): New expanders.
	("*trunctfdf2_ieee", "*trunctfdf2_ibm", "*trunctfsf2_ieee", 
	"*trunctfsf2_ibm", "*extenddftf2_ieee", "*extenddftf2_ibm",
	"*extendsftf2_ieee", "*extendsftf2_ibm"): New insn patterns.
	* config/s390/s390.opt (mlong-double-128, mlong-double-64):
	New options.
	* config/s390/t-crtstuff (TARGET_LIBGCC2_CFLAGS): Macro defined.
	* config/s390/libgcc-glibc.ver (__divtc3, __multc3, __powitf2, 
	__fixtfti, __fixunstfti, __floattitf, __fixtfdi, __fixunstfdi,
	__floatditf): Add a GCC_4.1.0 symbol version tag.

--- gcc/gcc/config/s390/2084.md.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/gcc/config/s390/2084.md	2006-01-28 10:39:11.000000000 +0100
@@ -161,6 +161,11 @@
 ;; Floating point insns
 ;;
 
+(define_insn_reservation "x_fsimptf" 7 
+  (and (eq_attr "cpu" "z990,z9_109")
+       (eq_attr "type" "fsimptf"))
+  "x_e1_t*2,x-wr-fp") 
+
 (define_insn_reservation "x_fsimpdf" 6 
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "fsimpdf,fmuldf"))
@@ -171,6 +176,18 @@
        (eq_attr "type" "fsimpsf,fmulsf"))
   "x_e1_t,x-wr-fp") 
 
+
+(define_insn_reservation "x_fmultf" 33
+  (and (eq_attr "cpu" "z990,z9_109")
+       (eq_attr "type" "fmultf"))
+  "x_e1_t*27,x-wr-fp") 
+
+
+(define_insn_reservation "x_fdivtf" 82
+  (and (eq_attr "cpu" "z990,z9_109")
+       (eq_attr "type" "fdivtf,fsqrttf"))
+  "x_e1_t*76,x-wr-fp") 
+
 (define_insn_reservation "x_fdivdf" 36
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "fdivdf,fsqrtdf"))
@@ -181,6 +198,12 @@
        (eq_attr "type" "fdivsf,fsqrtsf"))
   "x_e1_t*30,x-wr-fp") 
 
+
+(define_insn_reservation "x_floadtf" 6 
+  (and (eq_attr "cpu" "z990,z9_109")
+       (eq_attr "type" "floadtf"))
+  "x_e1_t,x-wr-fp") 
+
 (define_insn_reservation "x_floaddf" 6 
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "floaddf"))
@@ -191,6 +214,7 @@
        (eq_attr "type" "floadsf"))
   "x_e1_t,x-wr-fp") 
 
+
 (define_insn_reservation "x_fstoredf" 1 
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "fstoredf"))
@@ -201,6 +225,18 @@
        (eq_attr "type" "fstoresf"))
   "x_e1_t,x-wr-fp") 
 
+
+(define_insn_reservation "x_ftrunctf" 16
+  (and (eq_attr "cpu" "z990,z9_109")
+       (eq_attr "type" "ftrunctf"))
+  "x_e1_t*10,x-wr-fp") 
+
+(define_insn_reservation "x_ftruncdf" 11
+  (and (eq_attr "cpu" "z990,z9_109")
+       (eq_attr "type" "ftruncdf"))
+  "x_e1_t*5,x-wr-fp") 
+
+
 (define_insn_reservation "x_ftoi" 1 
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "ftoi"))
@@ -234,7 +270,7 @@
 	         "s390_agen_dep_p")
 
 (define_bypass 9 "x_int,x_agen,x_lr" 
-                 "x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
+                 "x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
 		  x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf"
 	         "s390_agen_dep_p")
 ;;
@@ -247,7 +283,7 @@
 	         "s390_agen_dep_p")
 
 (define_bypass 5 "x_load"
-                 "x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
+                 "x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
 		  x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf"
 	         "s390_agen_dep_p")
 
@@ -261,7 +297,7 @@
 	         "s390_agen_dep_p")
 
 (define_bypass 5 "x_larl, x_la"
-                 "x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
+                 "x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
 		  x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf"
 	         "s390_agen_dep_p")
 
--- gcc/gcc/config/s390/s390.c.jj	2006-01-28 10:29:03.000000000 +0100
+++ gcc/gcc/config/s390/s390.c	2006-01-28 10:39:11.000000000 +0100
@@ -71,13 +71,17 @@ struct processor_costs 
   const int msgr;     /* cost of an MSGR instruction.  */
   const int msr;      /* cost of an MSR instruction.  */
   const int mult_df;  /* cost of multiplication in DFmode.  */
+  const int mxbr;
   /* square root */
+  const int sqxbr;    /* cost of square root in TFmode.  */
   const int sqdbr;    /* cost of square root in DFmode.  */
   const int sqebr;    /* cost of square root in SFmode.  */
   /* multiply and add */
   const int madbr;    /* cost of multiply and add in DFmode.  */
   const int maebr;    /* cost of multiply and add in SFmode.  */
   /* division */
+  const int dxbr;
+  const int dxr;
   const int ddbr;
   const int ddr;
   const int debr;
@@ -107,10 +111,14 @@ struct processor_costs z900_cost = 
   COSTS_N_INSNS (10),    /* MSGR  */
   COSTS_N_INSNS (4),     /* MSR   */
   COSTS_N_INSNS (7),     /* multiplication in DFmode */
+  COSTS_N_INSNS (13),    /* MXBR */
+  COSTS_N_INSNS (136),   /* SQXBR */
   COSTS_N_INSNS (44),    /* SQDBR */
   COSTS_N_INSNS (35),    /* SQEBR */
   COSTS_N_INSNS (18),    /* MADBR */
   COSTS_N_INSNS (13),    /* MAEBR */
+  COSTS_N_INSNS (134),   /* DXBR */
+  COSTS_N_INSNS (135),   /* DXR */
   COSTS_N_INSNS (30),    /* DDBR */
   COSTS_N_INSNS (30),    /* DDR  */
   COSTS_N_INSNS (27),    /* DEBR */
@@ -138,10 +146,14 @@ struct processor_costs z990_cost = 
   COSTS_N_INSNS (4),     /* MSGR  */
   COSTS_N_INSNS (4),     /* MSR   */
   COSTS_N_INSNS (1),     /* multiplication in DFmode */
+  COSTS_N_INSNS (28),    /* MXBR */
+  COSTS_N_INSNS (130),   /* SQXBR */
   COSTS_N_INSNS (66),    /* SQDBR */
   COSTS_N_INSNS (38),    /* SQEBR */
   COSTS_N_INSNS (1),     /* MADBR */
   COSTS_N_INSNS (1),     /* MAEBR */
+  COSTS_N_INSNS (60),    /* DXBR */
+  COSTS_N_INSNS (72),    /* DXR */
   COSTS_N_INSNS (40),    /* DDBR */
   COSTS_N_INSNS (44),    /* DDR  */
   COSTS_N_INSNS (26),    /* DDBR */
@@ -169,10 +181,14 @@ struct processor_costs z9_109_cost = 
   COSTS_N_INSNS (4),     /* MSGR  */
   COSTS_N_INSNS (4),     /* MSR   */
   COSTS_N_INSNS (1),     /* multiplication in DFmode */
+  COSTS_N_INSNS (28),    /* MXBR */
+  COSTS_N_INSNS (130),   /* SQXBR */
   COSTS_N_INSNS (66),    /* SQDBR */
   COSTS_N_INSNS (38),    /* SQEBR */
   COSTS_N_INSNS (1),     /* MADBR */
   COSTS_N_INSNS (1),     /* MAEBR */
+  COSTS_N_INSNS (60),    /* DXBR */
+  COSTS_N_INSNS (72),    /* DXR */
   COSTS_N_INSNS (40),    /* DDBR */
   COSTS_N_INSNS (37),    /* DDR  */
   COSTS_N_INSNS (26),    /* DDBR */
@@ -2154,6 +2170,9 @@ s390_rtx_costs (rtx x, int code, int out
 	case DFmode:
 	  *total = s390_cost->mult_df;
 	  break;
+	case TFmode:
+	  *total = s390_cost->mxbr;
+	  break;
 	default:
 	  return false;
 	}
@@ -2204,13 +2223,22 @@ s390_rtx_costs (rtx x, int code, int out
 	  else /* TARGET_IBM_FLOAT */
 	    *total = s390_cost->ddr;
 	}
+      else if (GET_MODE (x) == TFmode)
+	{
+	  if (TARGET_IEEE_FLOAT)
+	    *total = s390_cost->dxbr;
+	  else /* TARGET_IBM_FLOAT */
+	    *total = s390_cost->dxr;
+	}
       return false;
 
     case SQRT:
       if (GET_MODE (x) == SFmode)
 	*total = s390_cost->sqebr;
-      else /* DFmode */
+      else if (GET_MODE (x) == DFmode)
 	*total = s390_cost->sqdbr;
+      else /* TFmode */
+	*total = s390_cost->sqxbr;
       return false;
 
     case SIGN_EXTEND:
@@ -2565,6 +2593,18 @@ s390_secondary_input_reload_class (enum 
   if (s390_plus_operand (in, mode))
     return ADDR_REGS;
 
+  if (reg_classes_intersect_p (FP_REGS, class)
+      && mode == TFmode
+      && GET_CODE (in) == MEM)
+    {
+      rtx disp = const0_rtx;
+
+      eliminate_constant_term (XEXP (in, 0), &disp);
+
+      if (!DISP_IN_RANGE (INTVAL (disp) + GET_MODE_SIZE (mode) - 1))
+	return ADDR_REGS;
+    }
+
   if (reg_classes_intersect_p (CC_REGS, class))
     return GENERAL_REGS;
 
@@ -2592,6 +2632,18 @@ s390_secondary_output_reload_class (enum
 			 + GET_MODE_SIZE (mode) - 1))
     return ADDR_REGS;
 
+  if (reg_classes_intersect_p (FP_REGS, class)
+      && mode == TFmode
+      && GET_CODE (out) == MEM)
+    {
+      rtx disp = const0_rtx;
+
+      eliminate_constant_term (XEXP (out, 0), &disp);
+
+      if (!DISP_IN_RANGE (INTVAL (disp) + GET_MODE_SIZE (mode) - 1))
+	return ADDR_REGS;
+    }
+
   if (reg_classes_intersect_p (CC_REGS, class))
     return GENERAL_REGS;
 
@@ -5164,10 +5216,10 @@ replace_ltrel_base (rtx *x)
 /* We keep a list of constants which we have to add to internal
    constant tables in the middle of large functions.  */
 
-#define NR_C_MODES 7
+#define NR_C_MODES 8
 enum machine_mode constant_modes[NR_C_MODES] =
 {
-  TImode,
+  TFmode, TImode,
   DFmode, DImode,
   SFmode, SImode,
   HImode,
--- gcc/gcc/config/s390/s390.h.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/gcc/config/s390/s390.h	2006-01-28 10:39:11.000000000 +0100
@@ -93,6 +93,8 @@ extern enum processor_flags s390_arch_fl
       builtin_define ("__s390__");			\
       if (TARGET_64BIT)					\
         builtin_define ("__s390x__");			\
+      if (TARGET_LONG_DOUBLE_128)			\
+        builtin_define ("__LONG_DOUBLE_128__");		\
     }							\
   while (0)
 
@@ -216,7 +218,18 @@ if (INTEGRAL_MODE_P (MODE) &&	        	 
 #define LONG_LONG_TYPE_SIZE 64
 #define FLOAT_TYPE_SIZE 32
 #define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64  /* ??? Should support extended format.  */
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+   not depend on target_flags.  */
+#ifdef __LONG_DOUBLE_128__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#endif
+
+/* Work around target_flags dependency in ada/targtyps.c.  */
+#define WIDEST_HARDWARE_FP_SIZE 64
 
 /* We use "unsigned char" as default.  */
 #define DEFAULT_SIGNED_CHAR 0
@@ -334,28 +347,34 @@ if (INTEGRAL_MODE_P (MODE) &&	        	 
    Floating point modes <= word size fit into any FPR or GPR.
    Floating point modes > word size (i.e. DFmode on 32-bit) fit
    into any FPR, or an even-odd GPR pair.
+   TFmode fits only into an even-odd FPR pair.
 
    Complex floating point modes fit either into two FPRs, or into
    successive GPRs (again starting with an even number).
+   TCmode fits only into two successive even-odd FPR pairs.
 
    Condition code modes fit only into the CC register.  */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)                           \
   (FP_REGNO_P(REGNO)?                                           \
-    (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) :      \
+   (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ?                \
+    2 * ((GET_MODE_SIZE(MODE) / 2 + 8 - 1) / 8) : 		\
+    ((GET_MODE_SIZE(MODE) + 8 - 1) / 8)) :			\
    GENERAL_REGNO_P(REGNO)?                                      \
     ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : \
    ACCESS_REGNO_P(REGNO)?					\
-    ((GET_MODE_SIZE(MODE)+4-1) / 4) : 				\
+    ((GET_MODE_SIZE(MODE) + 4 - 1) / 4) : 			\
    1)
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                             \
   (FP_REGNO_P(REGNO)?                                               \
-   ((MODE) == SImode || (MODE) == DImode ||                         \
-    GET_MODE_CLASS(MODE) == MODE_FLOAT ||                           \
-    GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT) :                   \
+   (((MODE) == SImode || (MODE) == DImode                           \
+     || GET_MODE_CLASS(MODE) == MODE_FLOAT                          \
+     || GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT)                 \
+    && (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) :    \
    GENERAL_REGNO_P(REGNO)?                                          \
-    (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) :        \
+   ((HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))	    \
+    && (MODE) != TFmode && (MODE) != TCmode) :			    \
    CC_REGNO_P(REGNO)?                                               \
      GET_MODE_CLASS (MODE) == MODE_CC :                             \
    FRAME_REGNO_P(REGNO)?                                            \
@@ -376,7 +395,9 @@ if (INTEGRAL_MODE_P (MODE) &&	        	 
    in a register of class CLASS.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)   					\
      ((CLASS) == FP_REGS ? 						\
-      (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) :  		\
+      (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ?                     \
+       2 * (GET_MODE_SIZE (MODE) / 2 + 8 - 1) / 8 :		        \
+       (GET_MODE_SIZE (MODE) + 8 - 1) / 8) :				\
       (CLASS) == ACCESS_REGS ?						\
       (GET_MODE_SIZE (MODE) + 4 - 1) / 4 :				\
       (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -386,10 +407,11 @@ if (INTEGRAL_MODE_P (MODE) &&	        	 
    cannot use SUBREGs to switch between modes in FP registers.
    Likewise for access registers, since they have only half the
    word size on 64-bit.  */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		\
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)			\
-   ? reg_classes_intersect_p (FP_REGS, CLASS)			\
-     || reg_classes_intersect_p (ACCESS_REGS, CLASS) : 0)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		        \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)			        \
+   ? ((reg_classes_intersect_p (FP_REGS, CLASS)				\
+       && (GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8))		\
+      || reg_classes_intersect_p (ACCESS_REGS, CLASS)) : 0)
 
 /* Register classes.  */
 
--- gcc/gcc/config/s390/s390.md.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/gcc/config/s390/s390.md	2006-01-28 10:39:11.000000000 +0100
@@ -199,11 +199,11 @@
 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
 	             cs,vs,store,sem,idiv,
                      imulhi,imulsi,imuldi,
-		     branch,jsr,fsimpdf,fsimpsf,
-		     floaddf,floadsf,fstoredf,fstoresf,
-		     fmuldf,fmulsf,fdivdf,fdivsf,
-		     ftoi,itof,fsqrtdf,fsqrtsf,
-                     other"
+		     branch,jsr,fsimptf,fsimpdf,fsimpsf,
+		     floadtf,floaddf,floadsf,fstoredf,fstoresf,
+		     fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
+		     ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf,
+                     ftrunctf,ftruncdf,other"
   (cond [(eq_attr "op_type" "NN")  (const_string "other")
          (eq_attr "op_type" "SS")  (const_string "cs")]
     (const_string "integer")))
@@ -278,9 +278,10 @@
 
 ;; Macros
 
-;; This mode macro allows DF and SF patterns to be generated from the
+;; This mode macro allows floating point patterns to be generated from the
 ;; same template.
-(define_mode_macro FPR     [DF SF])
+(define_mode_macro FPR [TF DF SF])
+(define_mode_macro DSF [DF SF])
 
 ;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
 ;; from the same template.
@@ -321,13 +322,22 @@
 			  (plus "add") (minus "sub") (mult "nand")])
 
 
-;; In FPR templates, a string like "lt<de>br" will expand to "ltdbr" in DFmode
-;; and "ltebr" in SFmode.
-(define_mode_attr de [(DF "d") (SF "e")])
-
-;; In FPR templates, a string like "m<dee>br" will expand to "mdbr" in DFmode
-;; and "meebr" in SFmode.  This is needed for the 'mul<mode>3' pattern. 
-(define_mode_attr dee [(DF "d") (SF "ee")])
+;; In FPR templates, a string like "lt<de>br" will expand to "ltxbr" in TFmode,
+;; "ltdbr" in DFmode, and "ltebr" in SFmode.
+(define_mode_attr xde [(TF "x") (DF "d") (SF "e")])
+
+;; In FPR templates, a string like "m<dee>br" will expand to "mxbr" in TFmode,
+;; "mdbr" in DFmode, and "meebr" in SFmode.
+(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")])
+
+;; In FPR templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
+;; Likewise for "<RXe>".
+(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
+(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
+
+;; In FPR templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
+;; This is used to disable the memory alternative in TFmode patterns.
+(define_mode_attr Rf [(TF "f") (DF "R") (SF "R")])
 
 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in 
 ;; 'ashift' and "srdl" in 'lshiftrt'.
@@ -816,7 +826,7 @@
         (compare (match_operand:FPR 0 "register_operand" "f")
                  (match_operand:FPR 1 "const0_operand" "")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lt<de>br\t%0,%0"
+  "lt<xde>br\t%0,%0"
    [(set_attr "op_type" "RRE")
     (set_attr "type"  "fsimp<mode>")])
 
@@ -825,30 +835,30 @@
         (compare (match_operand:FPR 0 "register_operand" "f")
                  (match_operand:FPR 1 "const0_operand" "")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
-  "lt<de>r\t%0,%0"
-   [(set_attr "op_type" "RR")
+  "lt<xde>r\t%0,%0"
+   [(set_attr "op_type" "<RRe>")
     (set_attr "type"  "fsimp<mode>")])
 
 (define_insn "*cmp<mode>_ccs"
   [(set (reg CC_REGNUM)
         (compare (match_operand:FPR 0 "register_operand" "f,f")
-                 (match_operand:FPR 1 "general_operand" "f,R")))]
+                 (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   c<de>br\t%0,%1
-   c<de>b\t%0,%1"
+   c<xde>br\t%0,%1
+   c<xde>b\t%0,%1"
    [(set_attr "op_type" "RRE,RXE")
     (set_attr "type"  "fsimp<mode>")])
 
 (define_insn "*cmp<mode>_ccs_ibm"
   [(set (reg CC_REGNUM)
         (compare (match_operand:FPR 0 "register_operand" "f,f")
-                 (match_operand:FPR 1 "general_operand" "f,R")))]
+                 (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   c<de>r\t%0,%1
-   c<de>\t%0,%1"
-   [(set_attr "op_type" "RR,RX")
+   c<xde>r\t%0,%1
+   c<xde>\t%0,%1"
+   [(set_attr "op_type" "<RRe>,<RXe>")
     (set_attr "type"  "fsimp<mode>")])
 
 
@@ -1483,6 +1493,79 @@
    (set_attr "type" "lr,load,load,*")])
 
 ;
+; movtf instruction pattern(s).
+;
+
+(define_insn "movtf"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
+        (match_operand:TF 1 "general_operand"       "G,f,o,f,Q"))]
+  ""
+  "@
+   lzxr\t%0
+   lxr\t%0,%1
+   #
+   #
+   #"
+  [(set_attr "op_type" "RRE,RRE,*,*,*")
+   (set_attr "type" "fsimptf,fsimptf,*,*,*")])
+
+(define_split
+  [(set (match_operand:TF 0 "register_operand" "")
+        (match_operand:TF 1 "memory_operand" ""))]
+  "reload_completed && offsettable_memref_p (operands[1])"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))]
+{
+  operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0);
+  operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8);
+  operands[4] = adjust_address_nv (operands[1], DFmode, 0);
+  operands[5] = adjust_address_nv (operands[1], DFmode, 8);
+})
+
+(define_split
+  [(set (match_operand:TF 0 "memory_operand" "")
+        (match_operand:TF 1 "register_operand" ""))]
+  "reload_completed && offsettable_memref_p (operands[0])"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))]
+{
+  operands[2] = adjust_address_nv (operands[0], DFmode, 0);
+  operands[3] = adjust_address_nv (operands[0], DFmode, 8);
+  operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0);
+  operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8);
+})
+
+(define_expand "reload_outtf"
+  [(parallel [(match_operand:TF 0 "" "")
+              (match_operand:TF 1 "register_operand" "f")
+              (match_operand:SI 2 "register_operand" "=&a")])]
+  ""
+{
+  rtx addr = gen_lowpart (Pmode, operands[2]);
+
+  gcc_assert (MEM_P (operands[0]));
+  s390_load_address (addr, find_replacement (&XEXP (operands[0], 0)));
+  operands[0] = replace_equiv_address (operands[0], addr);
+  emit_move_insn (operands[0], operands[1]);
+  DONE;
+})
+
+(define_expand "reload_intf"
+  [(parallel [(match_operand:TF 0 "register_operand" "=f")
+              (match_operand:TF 1 "" "")
+              (match_operand:SI 2 "register_operand" "=&a")])]
+  ""
+{
+  rtx addr = gen_lowpart (Pmode, operands[2]);
+ 
+  gcc_assert (MEM_P (operands[1]));
+  s390_load_address (addr, find_replacement (&XEXP (operands[1], 0)));
+  operands[1] = replace_equiv_address (operands[1], addr);
+  emit_move_insn (operands[0], operands[1]);
+  DONE;
+})
+
+;
 ; movdf instruction pattern(s).
 ;
 
@@ -3083,13 +3166,13 @@
   DONE;
 })
 
-(define_expand "fix_trunc<FPR:mode>di2"
+(define_expand "fix_trunc<mode>di2"
   [(set (match_operand:DI 0 "register_operand" "")
-        (fix:DI (match_operand:FPR 1 "nonimmediate_operand" "")))]
+        (fix:DI (match_operand:DSF 1 "nonimmediate_operand" "")))]
   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
 {
-  operands[1] = force_reg (<FPR:MODE>mode, operands[1]);
-  emit_insn (gen_fix_trunc<FPR:mode>di2_ieee (operands[0], operands[1],
+  operands[1] = force_reg (<MODE>mode, operands[1]);
+  emit_insn (gen_fix_trunc<mode>di2_ieee (operands[0], operands[1],
       GEN_INT(5)));
   DONE;
 })
@@ -3100,11 +3183,23 @@
    (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "c<GPR:gf><FPR:de>br\t%0,%h2,%1"
+  "c<GPR:gf><FPR:xde>br\t%0,%h2,%1"
   [(set_attr "op_type" "RRE")
    (set_attr "type"    "ftoi")])
 
 ;
+; fix_trunctf(si|di)2 instruction pattern(s).
+;
+
+(define_expand "fix_trunctf<mode>2"
+  [(parallel [(set (match_operand:GPR 0 "register_operand" "")
+		   (fix:GPR (match_operand:TF 1 "register_operand" "")))
+	      (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
+	      (clobber (reg:CC CC_REGNUM))])]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "")
+
+;
 ; fix_truncdfsi2 instruction pattern(s).
 ;
 
@@ -3177,21 +3272,36 @@
 })
 
 ;
-; floatdi(df|sf)2 instruction pattern(s).
+; float(si|di)(tf|df|sf)2 instruction pattern(s).
 ;
 
 (define_insn "floatdi<mode>2"
   [(set (match_operand:FPR 0 "register_operand" "=f")
         (float:FPR (match_operand:DI 1 "register_operand" "d")))]
   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "c<de>gbr\t%0,%1"
+  "c<xde>gbr\t%0,%1"
   [(set_attr "op_type" "RRE")
    (set_attr "type"    "itof" )])
 
+(define_insn "floatsi<mode>2_ieee"
+  [(set (match_operand:FPR 0 "register_operand" "=f")
+        (float:FPR (match_operand:SI 1 "register_operand" "d")))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "c<xde>fbr\t%0,%1"
+  [(set_attr "op_type" "RRE")
+   (set_attr "type"   "itof" )])
+
+
 ;
-; floatsidf2 instruction pattern(s).
+; floatsi(tf|df)2 instruction pattern(s).
 ;
 
+(define_expand "floatsitf2"
+  [(set (match_operand:TF 0 "register_operand" "")
+        (float:TF (match_operand:SI 1 "register_operand" "")))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "")
+
 (define_expand "floatsidf2"
   [(set (match_operand:DF 0 "register_operand" "")
         (float:DF (match_operand:SI 1 "register_operand" "")))]
@@ -3209,14 +3319,6 @@
     }
 })
 
-(define_insn "floatsidf2_ieee"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-        (float:DF (match_operand:SI 1 "register_operand" "d")))]
-  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "cdfbr\t%0,%1"
-  [(set_attr "op_type" "RRE")
-   (set_attr "type"   "itof" )])
-
 (define_insn "floatsidf2_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f")
         (float:DF (match_operand:SI 1 "register_operand" "d")))
@@ -3252,14 +3354,6 @@
     }
 })
 
-(define_insn "floatsisf2_ieee"
-  [(set (match_operand:SF 0 "register_operand" "=f")
-        (float:SF (match_operand:SI 1 "register_operand" "d")))]
-  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "cefbr\t%0,%1"
-  [(set_attr "op_type" "RRE")
-   (set_attr "type"    "itof" )])
-
 ;
 ; truncdfsf2 instruction pattern(s).
 ;
@@ -3275,7 +3369,8 @@
         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "ledbr\t%0,%1"
-  [(set_attr "op_type"  "RRE")])
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"   "ftruncdf")])
 
 (define_insn "truncdfsf2_ibm"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
@@ -3288,6 +3383,66 @@
    (set_attr "type"   "floadsf")])
 
 ;
+; trunctfdf2 instruction pattern(s).
+;
+
+(define_expand "trunctfdf2"
+  [(parallel 
+    [(set (match_operand:DF 0 "register_operand" "")
+	  (float_truncate:DF (match_operand:TF 1 "register_operand" "")))
+     (clobber (match_scratch:TF 2 "=f"))])]
+  "TARGET_HARD_FLOAT"
+  "")
+
+(define_insn "*trunctfdf2_ieee"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+        (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
+   (clobber (match_scratch:TF 2 "=f"))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "ldxbr\t%2,%1\;ldr\t%0,%2"
+  [(set_attr "length" "6")
+   (set_attr "type"   "ftrunctf")])   
+
+(define_insn "*trunctfdf2_ibm"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+        (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
+   (clobber (match_scratch:TF 2 "=f"))]
+  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+  "ldxr\t%2,%1\;ldr\t%0,%2"
+  [(set_attr "length"  "4")
+   (set_attr "type"   "ftrunctf")])
+
+;
+; trunctfsf2 instruction pattern(s).
+;
+
+(define_expand "trunctfsf2"
+  [(parallel 
+    [(set (match_operand:SF 0 "register_operand" "=f")
+	  (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
+     (clobber (match_scratch:TF 2 "=f"))])]
+  "TARGET_HARD_FLOAT"
+  "")
+
+(define_insn "*trunctfsf2_ieee"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
+   (clobber (match_scratch:TF 2 "=f"))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "lexbr\t%2,%1\;ler\t%0,%2"
+  [(set_attr "length"  "6")
+   (set_attr "type"   "ftrunctf")])
+
+(define_insn "*trunctfsf2_ibm"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
+   (clobber (match_scratch:TF 2 "=f"))]
+  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+  "lexr\t%2,%1\;ler\t%0,%2"
+  [(set_attr "length"  "6")
+   (set_attr "type"   "ftrunctf")])
+
+;
 ; extendsfdf2 instruction pattern(s).
 ;
 
@@ -3311,7 +3466,7 @@
    ldebr\t%0,%1
    ldeb\t%0,%1"
   [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "type"   "floadsf")])
+   (set_attr "type"   "fsimpsf, floadsf")])
 
 (define_insn "extendsfdf2_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
@@ -3324,6 +3479,66 @@
   [(set_attr "length"   "4,6")
    (set_attr "type"     "floadsf")])
 
+;
+; extenddftf2 instruction pattern(s).
+;
+
+(define_expand "extenddftf2"
+  [(set (match_operand:TF 0 "register_operand" "")
+        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
+  "TARGET_HARD_FLOAT"
+  "")
+
+(define_insn "*extenddftf2_ieee"
+  [(set (match_operand:TF 0 "register_operand" "=f,f")
+        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "@
+   lxdbr\t%0,%1
+   lxdb\t%0,%1"
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"   "fsimptf, floadtf")])
+
+(define_insn "*extenddftf2_ibm"
+  [(set (match_operand:TF 0 "register_operand" "=f,f")
+        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
+  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+  "@
+   lxdr\t%0,%1
+   lxd\t%0,%1"
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"   "fsimptf, floadtf")])
+
+;
+; extendsftf2 instruction pattern(s).
+;
+
+(define_expand "extendsftf2"
+  [(set (match_operand:TF 0 "register_operand" "")
+        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
+  "TARGET_HARD_FLOAT"
+  "")
+
+(define_insn "*extendsftf2_ieee"
+  [(set (match_operand:TF 0 "register_operand" "=f,f")
+        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "@
+   lxebr\t%0,%1
+   lxeb\t%0,%1"
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"   "fsimptf, floadtf")])
+
+(define_insn "*extendsftf2_ibm"
+  [(set (match_operand:TF 0 "register_operand" "=f,f")
+        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
+  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+  "@
+   lxer\t%0,%1
+   lxe\t%0,%1"
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"   "fsimptf, floadtf")])
+
 
 ;;
 ;; ARITHMETIC OPERATIONS
@@ -3751,7 +3966,7 @@
   [(parallel
     [(set (match_operand:FPR 0 "register_operand" "=f,f")
           (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-                    (match_operand:FPR 2 "general_operand" "f,R")))
+                    (match_operand:FPR 2 "general_operand" "f,<Rf>")))
      (clobber (reg:CC CC_REGNUM))])]
   "TARGET_HARD_FLOAT"
   "")
@@ -3759,52 +3974,52 @@
 (define_insn "*add<mode>3"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-                  (match_operand:FPR 2 "general_operand" "f,R")))
+                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   a<de>br\t%0,%2
-   a<de>b\t%0,%2"
+   a<xde>br\t%0,%2
+   a<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*add<mode>3_cc"
   [(set (reg CC_REGNUM)
 	(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-			   (match_operand:FPR 2 "general_operand" "f,R"))
+			   (match_operand:FPR 2 "general_operand" "f,<Rf>"))
 		 (match_operand:FPR 3 "const0_operand" "")))
    (set (match_operand:FPR 0 "register_operand" "=f,f")
 	(plus:FPR (match_dup 1) (match_dup 2)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   a<de>br\t%0,%2
-   a<de>b\t%0,%2"
+   a<xde>br\t%0,%2
+   a<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*add<mode>3_cconly"
   [(set (reg CC_REGNUM)
 	(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-			   (match_operand:FPR 2 "general_operand" "f,R"))
+			   (match_operand:FPR 2 "general_operand" "f,<Rf>"))
 		 (match_operand:FPR 3 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f,f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   a<de>br\t%0,%2
-   a<de>b\t%0,%2"
+   a<xde>br\t%0,%2
+   a<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*add<mode>3_ibm"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-                  (match_operand:FPR 2 "general_operand" "f,R")))
+                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   a<de>r\t%0,%2
-   a<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   a<xde>r\t%0,%2
+   a<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fsimp<mode>")])
 
 
@@ -4163,52 +4378,52 @@
 (define_insn "*sub<mode>3"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
-                   (match_operand:FPR 2 "general_operand" "f,R")))
+                   (match_operand:FPR 2 "general_operand" "f,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   s<de>br\t%0,%2
-   s<de>b\t%0,%2"
+   s<xde>br\t%0,%2
+   s<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*sub<mode>3_cc"
   [(set (reg CC_REGNUM)
 	(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
-			    (match_operand:FPR 2 "general_operand" "f,R"))
+			    (match_operand:FPR 2 "general_operand" "f,<Rf>"))
 		 (match_operand:FPR 3 "const0_operand" "")))
    (set (match_operand:FPR 0 "register_operand" "=f,f")
 	(minus:FPR (match_dup 1) (match_dup 2)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   s<de>br\t%0,%2
-   s<de>b\t%0,%2"
+   s<xde>br\t%0,%2
+   s<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*sub<mode>3_cconly"
   [(set (reg CC_REGNUM)
 	(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
-			    (match_operand:FPR 2 "general_operand" "f,R"))
+			    (match_operand:FPR 2 "general_operand" "f,<Rf>"))
 		 (match_operand:FPR 3 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f,f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   s<de>br\t%0,%2
-   s<de>b\t%0,%2"
+   s<xde>br\t%0,%2
+   s<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*sub<mode>3_ibm"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
-                   (match_operand:FPR 2 "general_operand" "f,R")))
+                   (match_operand:FPR 2 "general_operand" "f,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   s<de>r\t%0,%2
-   s<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   s<xde>r\t%0,%2
+   s<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fsimp<mode>")])
 
 
@@ -4456,53 +4671,53 @@
 (define_expand "mul<mode>3"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-                  (match_operand:FPR 2 "general_operand" "f,R")))]
+                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*mul<mode>3"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-                  (match_operand:FPR 2 "general_operand" "f,R")))]
+                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   m<dee>br\t%0,%2
-   m<dee>b\t%0,%2"
+   m<xdee>br\t%0,%2
+   m<xdee>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fmul<mode>")])
 
 (define_insn "*mul<mode>3_ibm"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
-                  (match_operand:FPR 2 "general_operand" "f,R")))]
+                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   m<de>r\t%0,%2
-   m<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   m<xde>r\t%0,%2
+   m<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fmul<mode>")])
 
 (define_insn "*fmadd<mode>"
-  [(set (match_operand:FPR 0 "register_operand" "=f,f")
-	(plus:FPR (mult:FPR (match_operand:FPR 1 "register_operand" "%f,f")
-			   (match_operand:FPR 2 "nonimmediate_operand"  "f,R"))
-		 (match_operand:FPR 3 "register_operand" "0,0")))]
+  [(set (match_operand:DSF 0 "register_operand" "=f,f")
+	(plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f")
+			    (match_operand:DSF 2 "nonimmediate_operand"  "f,R"))
+		 (match_operand:DSF 3 "register_operand" "0,0")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
   "@
-   ma<de>br\t%0,%1,%2
-   ma<de>b\t%0,%1,%2"
+   ma<xde>br\t%0,%1,%2
+   ma<xde>b\t%0,%1,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fmul<mode>")])
 
 (define_insn "*fmsub<mode>"
-  [(set (match_operand:FPR 0 "register_operand" "=f,f")
-	(minus:FPR (mult:FPR (match_operand:FPR 1 "register_operand" "f,f")
-			    (match_operand:FPR 2 "nonimmediate_operand"  "f,R"))
-		 (match_operand:FPR 3 "register_operand" "0,0")))]
+  [(set (match_operand:DSF 0 "register_operand" "=f,f")
+	(minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f")
+			     (match_operand:DSF 2 "nonimmediate_operand"  "f,R"))
+		 (match_operand:DSF 3 "register_operand" "0,0")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
   "@
-   ms<de>br\t%0,%1,%2
-   ms<de>b\t%0,%1,%2"
+   ms<xde>br\t%0,%1,%2
+   ms<xde>b\t%0,%1,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fmul<mode>")])
 
@@ -4949,30 +5164,30 @@
 (define_expand "div<mode>3"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
-                 (match_operand:FPR 2 "general_operand" "f,R")))]
+                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*div<mode>3"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
-                 (match_operand:FPR 2 "general_operand" "f,R")))]
+                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   d<de>br\t%0,%2
-   d<de>b\t%0,%2"
+   d<xde>br\t%0,%2
+   d<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fdiv<mode>")])
 
 (define_insn "*div<mode>3_ibm"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
         (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
-                 (match_operand:FPR 2 "general_operand" "f,R")))]
+                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   d<de>r\t%0,%2
-   d<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   d<xde>r\t%0,%2
+   d<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fdiv<mode>")])
 
 
@@ -5955,7 +6170,7 @@
    (set (match_operand:FPR 0 "register_operand" "=f")
         (neg:FPR (match_dup 1)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lc<de>br\t%0,%1"
+  "lc<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
@@ -5965,7 +6180,7 @@
                  (match_operand:FPR 2 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lc<de>br\t%0,%1"
+  "lc<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
@@ -5974,7 +6189,7 @@
         (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lc<de>br\t%0,%1"
+  "lc<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
@@ -5983,8 +6198,8 @@
         (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
-  "lc<de>r\t%0,%1"
-  [(set_attr "op_type"  "RR")
+  "lc<xde>r\t%0,%1"
+  [(set_attr "op_type"  "<RRe>")
    (set_attr "type"     "fsimp<mode>")])
 
 
@@ -6062,7 +6277,7 @@
    (set (match_operand:FPR 0 "register_operand" "=f")
         (abs:FPR (match_dup 1)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lp<de>br\t%0,%1"
+  "lp<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
@@ -6072,7 +6287,7 @@
                  (match_operand:FPR 2 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lp<de>br\t%0,%1"
+  "lp<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
@@ -6081,7 +6296,7 @@
         (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lp<de>br\t%0,%1"
+  "lp<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
@@ -6090,8 +6305,8 @@
         (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
-  "lp<de>r\t%0,%1"
-  [(set_attr "op_type"  "RR")
+  "lp<xde>r\t%0,%1"
+  [(set_attr "op_type"  "<RRe>")
    (set_attr "type"     "fsimp<mode>")])
 
 ;;
@@ -6161,7 +6376,7 @@
    (set (match_operand:FPR 0 "register_operand" "=f")
         (neg:FPR (abs:FPR (match_dup 1))))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "ln<de>br\t%0,%1"
+  "ln<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
@@ -6171,7 +6386,7 @@
                  (match_operand:FPR 2 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "ln<de>br\t%0,%1"
+  "ln<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
@@ -6180,7 +6395,7 @@
         (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "ln<de>br\t%0,%1"
+  "ln<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
@@ -6194,11 +6409,11 @@
 
 (define_insn "sqrt<mode>2"
   [(set (match_operand:FPR 0 "register_operand" "=f,f")
-	(sqrt:FPR (match_operand:FPR 1 "general_operand" "f,R")))]
+	(sqrt:FPR (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   sq<de>br\t%0,%1
-   sq<de>b\t%0,%1"
+   sq<xde>br\t%0,%1
+   sq<xde>b\t%0,%1"
   [(set_attr "op_type" "RRE,RXE")
    (set_attr "type" "fsqrt<mode>")])
 
--- gcc/gcc/config/s390/s390.opt.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/gcc/config/s390/s390.opt	2006-01-28 10:39:11.000000000 +0100
@@ -51,6 +51,14 @@ mhard-float
 Target Report RejectNegative Mask(HARD_FLOAT)
 Use hardware fp
 
+mlong-double-128
+Target Report RejectNegative Mask(LONG_DOUBLE_128)
+Use 128-bit long double
+
+mlong-double-64
+Target Report RejectNegative InverseMask(LONG_DOUBLE_128)
+Use 64-bit long double
+
 mpacked-stack
 Target Report Mask(PACKED_STACK)
 Use packed stack layout
--- gcc/gcc/config/s390/t-crtstuff.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/gcc/config/s390/t-crtstuff	2006-01-28 10:39:11.000000000 +0100
@@ -2,3 +2,4 @@
 # because then __FRAME_END__ might not be the last thing in .eh_frame
 # section.
 CRTSTUFF_T_CFLAGS = -fno-asynchronous-unwind-tables
+TARGET_LIBGCC2_CFLAGS += -mlong-double-128
--- gcc/gcc/config/s390/libgcc-glibc.ver.jj	2006-01-28 09:54:03.000000000 +0100
+++ gcc/gcc/config/s390/libgcc-glibc.ver	2006-01-28 10:39:11.000000000 +0100
@@ -39,3 +39,36 @@ GLIBC_2.2 {
 }
 %endif
 
+# With GCC 4.1.0 long double 128 bit support was introduced. The
+# following symbols coming from libgcc are enabled when -mlong-double-128
+# is specified. These lines make the symbols to get a @@GCC_4.1.0 attached.
+
+%exclude {
+  __divtc3
+  __multc3
+  __powitf2
+  __fixtfti
+  __fixunstfti
+  __floattitf
+
+  __fixtfdi
+  __fixunstfdi
+  __floatditf
+}
+
+GCC_4.1.0 {
+  __divtc3
+  __multc3
+  __powitf2
+
+%ifdef __s390x__
+  __fixtfti
+  __fixunstfti
+  __floattitf
+
+%else
+  __fixtfdi
+  __fixunstfdi
+  __floatditf
+%endif
+}


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/gcc/devel/.cvsignore,v
retrieving revision 1.127
retrieving revision 1.128
diff -u -r1.127 -r1.128
--- .cvsignore	21 Jan 2006 11:38:40 -0000	1.127
+++ .cvsignore	28 Jan 2006 10:00:01 -0000	1.128
@@ -1 +1 @@
-gcc-4.1.0-20060121.tar.bz2
+gcc-4.1.0-20060128.tar.bz2


Index: gcc41.spec
===================================================================
RCS file: /cvs/dist/rpms/gcc/devel/gcc41.spec,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- gcc41.spec	21 Jan 2006 11:38:40 -0000	1.18
+++ gcc41.spec	28 Jan 2006 10:00:01 -0000	1.19
@@ -1,6 +1,6 @@
-%define DATE 20060121
+%define DATE 20060128
 %define gcc_version 4.1.0
-%define gcc_release 0.16
+%define gcc_release 0.17
 %define _unpackaged_files_terminate_build 0
 %define multilib_64_archs sparc64 ppc64 s390x x86_64
 %ifarch %{ix86} x86_64 ia64
@@ -92,11 +92,10 @@
 Patch11: gcc41-java-slow_pthread_self.patch
 Patch12: gcc41-libjava-libltdl.patch
 Patch13: gcc41-fortran-finclude.patch
-Patch14: gcc41-ppc64-sync.patch
+Patch14: gcc41-atomic-builtins.patch
 Patch15: gcc41-ppc32-retaddr.patch
-Patch16: gcc41-s390-atomic1.patch
-Patch17: gcc41-pr25717.patch
-Patch18: gcc41-pr25324.patch
+Patch16: gcc41-ppc32-ldbl.patch
+Patch17: gcc41-s390-ldbl.patch
 
 %define _gnu %{nil}
 %ifarch sparc
@@ -440,11 +439,10 @@
 %patch11 -p0 -b .java-slow_pthread_self~
 %patch12 -p0 -b .libjava-libltdl~
 %patch13 -p0 -b .fortran-finclude~
-%patch14 -p0 -b .ppc64-sync~
+%patch14 -p0 -b .atomic-builtins~
 %patch15 -p0 -b .ppc32-retaddr~
-%patch16 -p0 -b .s390-atomic1~
-%patch17 -p0 -b .pr25717~
-%patch18 -p0 -b .pr25324~
+%patch16 -p0 -b .ppc32-ldbl~
+%patch17 -p0 -b .s390-ldbl~
 
 sed -i -e 's/4\.1\.0/4.1.0/' gcc/BASE-VER gcc/version.c
 sed -i -e 's/" (Red Hat[^)]*)"/" (Red Hat %{version}-%{gcc_release})"/' gcc/version.c
@@ -1530,6 +1528,21 @@
 %endif
 
 %changelog
+* Sat Jan 28 2006 Jakub Jelinek <jakub at redhat.com> 4.1.0-0.17
+- update from gcc-4_1-branch (-r110062:110317)
+  - PRs ada/20548, ada/21317, bootstrap/25859, c++/25552, c++/25856,
+	c++/25858, c++/25895, c/25892, fortran/18540, fortran/20852,
+	fortran/20881, fortran/23308, fortran/24276, fortran/25084,
+	fortran/25085, fortran/25086, fortran/25124, fortran/25416,
+	fortran/25538, fortran/25625, fortran/25710, fortran/25716,
+	fortran/25901, fortran/25964, java/25816, other/24829,
+	rtl-optimization/24626, rtl-optimization/25654, target/24831,
+	testsuite/24962, testsuite/25590
+- atomic builtin fixes (Richard Henderson)
+- -mlong-double-128 support on ppc32 (David Edelsohn, Alan Modra)
+- -mlong-double-128 support on s390 and s390x (Andreas Krebbel,
+  Ulrich Weigand)
+
 * Sat Jan 21 2006 Jakub Jelinek <jakub at redhat.com> 4.1.0-0.16
 - update from gcc-4_1-branch (-r109815:110062)
   - PRs ada/24533, c++/16829, c++/22136, c++/25836, c++/25854, c/25805,


Index: sources
===================================================================
RCS file: /cvs/dist/rpms/gcc/devel/sources,v
retrieving revision 1.129
retrieving revision 1.130
diff -u -r1.129 -r1.130
--- sources	21 Jan 2006 11:38:40 -0000	1.129
+++ sources	28 Jan 2006 10:00:01 -0000	1.130
@@ -1 +1 @@
-429a46ed48d114066429682803e970aa  gcc-4.1.0-20060121.tar.bz2
+dc997a74f17dccebeb7145a1849573b4  gcc-4.1.0-20060128.tar.bz2


--- gcc41-ppc64-sync.patch DELETED ---


--- gcc41-pr25324.patch DELETED ---


--- gcc41-pr25717.patch DELETED ---


--- gcc41-s390-atomic1.patch DELETED ---




More information about the fedora-cvs-commits mailing list