[PATCH, RFC] Enable IBM long double for PPC32 Linux

David Edelsohn dje@watson.ibm.com
Mon Jan 23 17:51:00 GMT 2006


	PPC64 Linux specifies long double as the IBM extended precision
format and SVR4 PowerPC specifies the IEEE extended precision format.
Support for IBM extended precision will be included in the next Glibc
release.  128-bit long double has not been enabled by default for PowerPC
Linux, so members of the PowerPC Linux development community would like to
take this opportunity to make the IBM extended precision format the
default.  This provides a consistent long double format across PowerPC
Linux and utilizes a format that is much more effecient on PowerPC.

	The proposal changes 32-bit PowerPC Linux to use the IBM extended
precision format, but does not change SVR4 PowerPC / eABI.  New -mabi
options would be available to select the opposite long double ABI manually
for compatibility.

	The proposed ABI for IBM long double in PowerPC Linux attempts to
remain consistent with the rest of the ABI, only changing long double
itself.  In the SVR4 PowerPC ABI, float and double are passed and returned
in FPRs; IBM long double is treated similarly, unlike IEEE long double
passed and returned by reference.  In the SVR4 ABI, complex is passed and
returned by reference and will remain the same.  In the SVR4 ABI,
multi-register arguments are not split between the parameter registers and
the stack; IBM long double will be consistent.

	The appended patch implements this proposal and we would like to
include it in mainline and GCC 4.1.

David

	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.
	* doc/invoke.texi (-mabi): Collect options together.  Add
	ibmlongdouble and ieeelongdouble.

Index: config/rs6000/linux.h
===================================================================
*** config/rs6000/linux.h	(revision 109981)
--- config/rs6000/linux.h	(working copy)
***************
*** 118,120 ****
--- 118,123 ----
  /* ppc32 glibc provides __stack_chk_guard in -0x7008(2).  */
  #define TARGET_THREAD_SSP_OFFSET	-0x7008
  #endif
+ 
+ #define POWERPC_LINUX
+ 
Index: config/rs6000/darwin-ldouble.c
===================================================================
*** config/rs6000/darwin-ldouble.c	(revision 109981)
--- config/rs6000/darwin-ldouble.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 48,54 ****
  
     This code currently assumes big-endian.  */
  
! #if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__) || defined (_AIX))
  
  #define fabs(x) __builtin_fabs(x)
  #define isless(x, y) __builtin_isless (x, y)
--- 48,54 ----
  
     This code currently assumes big-endian.  */
  
! #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)
Index: config/rs6000/linux64.h
===================================================================
*** config/rs6000/linux64.h	(revision 109981)
--- config/rs6000/linux64.h	(working copy)
*************** while (0)
*** 567,569 ****
--- 567,572 ----
     ppc64 glibc provides it at -0x7010(13).  */
  #define TARGET_THREAD_SSP_OFFSET	(TARGET_64BIT ? -0x7010 : -0x7008)
  #endif
+ 
+ #define POWERPC_LINUX
+ 
Index: config/rs6000/darwin.h
===================================================================
*** config/rs6000/darwin.h	(revision 109981)
--- config/rs6000/darwin.h	(working copy)
*************** do {									\
*** 311,316 ****
--- 311,318 ----
  /* 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.  */
  
Index: config/rs6000/rs6000.c
===================================================================
*** config/rs6000/rs6000.c	(revision 109981)
--- config/rs6000/rs6000.c	(working copy)
*************** enum rs6000_nop_insertion rs6000_sched_i
*** 155,164 ****
  /* Support targetm.vectorize.builtin_mask_for_load.  */
  static GTY(()) tree altivec_builtin_mask_for_load;
  
! /* Size of long double */
  int rs6000_long_double_type_size;
  
! /* Whether -mabi=altivec has appeared */
  int rs6000_altivec_abi;
  
  /* Nonzero if we want SPE ABI extensions.  */
--- 155,167 ----
  /* Support targetm.vectorize.builtin_mask_for_load.  */
  static GTY(()) tree altivec_builtin_mask_for_load;
  
! /* Size of long double.  */
  int rs6000_long_double_type_size;
  
! /* 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.  */
*************** rs6000_override_options (const char *def
*** 1297,1302 ****
--- 1300,1312 ----
    if (!rs6000_explicit_options.long_double)
      rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
  
+   if (!rs6000_explicit_options.abi)
+ #ifdef POWERPC_LINUX
+   rs6000_ieeequad = 0;
+ #else
+   rs6000_ieeequad = 1;
+ #endif
+ 
    /* Set Altivec ABI as default for powerpc64 linux.  */
    if (TARGET_ELF && TARGET_64BIT)
      {
*************** rs6000_override_options (const char *def
*** 1410,1417 ****
    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))
      REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
  
    if (TARGET_TOC)
--- 1420,1426 ----
    if (!rs6000_explicit_options.aix_struct_ret)
      aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
  
!   if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
      REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
  
    if (TARGET_TOC)
*************** rs6000_handle_option (size_t code, const
*** 1780,1785 ****
--- 1789,1805 ----
  	  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);
*************** rs6000_emit_move (rtx dest, rtx source, 
*** 3902,3908 ****
  
    /* 128-bit constant floating-point values on Darwin should really be
       loaded as two parts.  */
!   if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
        && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
        && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
      {
--- 3922,3928 ----
  
    /* 128-bit constant floating-point values on Darwin should really be
       loaded as two parts.  */
!   if (!TARGET_IEEEQUAD
        && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
        && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
      {
*************** rs6000_return_in_memory (tree type, tree
*** 4227,4233 ****
        return true;
      }
  
!   if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
      return true;
  
    return false;
--- 4247,4253 ----
        return true;
      }
  
!   if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
      return true;
  
    return false;
*************** function_arg_advance (CUMULATIVE_ARGS *c
*** 4614,4626 ****
    else if (DEFAULT_ABI == ABI_V4)
      {
        if (TARGET_HARD_FLOAT && TARGET_FPRS
! 	  && (mode == SFmode || mode == DFmode))
  	{
! 	  if (cum->fregno <= FP_ARG_V4_MAX_REG)
! 	    cum->fregno++;
  	  else
  	    {
! 	      if (mode == DFmode)
  		cum->words += cum->words & 1;
  	      cum->words += rs6000_arg_size (mode, type);
  	    }
--- 4634,4648 ----
    else if (DEFAULT_ABI == ABI_V4)
      {
        if (TARGET_HARD_FLOAT && TARGET_FPRS
! 	  && (mode == SFmode || mode == DFmode
! 	      || (mode == TFmode && !TARGET_IEEEQUAD)))
  	{
! 	  if (cum->fregno <= FP_ARG_V4_MAX_REG
! 			     + (mode == TFmode ? 1 : 0))
! 	    cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
  	  else
  	    {
! 	      if (mode == DFmode || mode == TFmode)
  		cum->words += cum->words & 1;
  	      cum->words += rs6000_arg_size (mode, type);
  	    }
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 5146,5154 ****
    else if (abi == ABI_V4)
      {
        if (TARGET_HARD_FLOAT && TARGET_FPRS
! 	  && (mode == SFmode || mode == DFmode))
  	{
! 	  if (cum->fregno <= FP_ARG_V4_MAX_REG)
  	    return gen_rtx_REG (mode, cum->fregno);
  	  else
  	    return NULL_RTX;
--- 5168,5177 ----
    else if (abi == ABI_V4)
      {
        if (TARGET_HARD_FLOAT && TARGET_FPRS
! 	  && (mode == SFmode || mode == DFmode
! 	      || (mode == TFmode && !TARGET_IEEEQUAD)))
  	{
! 	  if (cum->fregno <= FP_ARG_V4_MAX_REG + (mode == TFmode ? 1 : 0))
  	    return gen_rtx_REG (mode, cum->fregno);
  	  else
  	    return NULL_RTX;
*************** rs6000_pass_by_reference (CUMULATIVE_ARG
*** 5351,5357 ****
  			  enum machine_mode mode, tree type,
  			  bool named ATTRIBUTE_UNUSED)
  {
!   if (DEFAULT_ABI == ABI_V4 && mode == TFmode)
      {
        if (TARGET_DEBUG_ARG)
  	fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
--- 5374,5380 ----
  			  enum machine_mode mode, tree type,
  			  bool named ATTRIBUTE_UNUSED)
  {
!   if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
      {
        if (TARGET_DEBUG_ARG)
  	fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
*************** rs6000_gimplify_va_arg (tree valist, tre
*** 5802,5815 ****
    align = 1;
  
    if (TARGET_HARD_FLOAT && TARGET_FPRS
!       && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
      {
        /* FP args go in FP registers, if present.  */
        reg = fpr;
!       n_reg = 1;
        sav_ofs = 8*4;
        sav_scale = 8;
!       if (TYPE_MODE (type) == DFmode)
  	align = 8;
      }
    else
--- 5825,5840 ----
    align = 1;
  
    if (TARGET_HARD_FLOAT && TARGET_FPRS
!       && (TYPE_MODE (type) == SFmode
! 	  || TYPE_MODE (type) == DFmode
! 	  || TYPE_MODE (type) == TFmode))
      {
        /* FP args go in FP registers, if present.  */
        reg = fpr;
!       n_reg = (size + 7) / 8;
        sav_ofs = 8*4;
        sav_scale = 8;
!       if (TYPE_MODE (type) != SFmode)
  	align = 8;
      }
    else
*************** rs6000_gimplify_va_arg (tree valist, tre
*** 5841,5847 ****
  	 As are any other 2 gpr item such as complex int due to a
  	 historical mistake.  */
        u = reg;
!       if (n_reg == 2)
  	{
  	  u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
  		     size_int (n_reg - 1));
--- 5866,5872 ----
  	 As are any other 2 gpr item such as complex int due to a
  	 historical mistake.  */
        u = reg;
!       if (n_reg == 2 && reg == gpr)
  	{
  	  u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
  		     size_int (n_reg - 1));
*************** rs6000_init_libfuncs (void)
*** 9047,9079 ****
    if (!TARGET_HARD_FLOAT)
      return;
  
!   if (DEFAULT_ABI != ABI_V4)
      {
!       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/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");
! 	}
!     }
    else
      {
        /* 32-bit SVR4 quad floating point routines.  */
--- 9072,9103 ----
    if (!TARGET_HARD_FLOAT)
      return;
  
!   if (DEFAULT_ABI != ABI_V4 && 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");
!     }
  
+   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");
!       }
    else
      {
        /* 32-bit SVR4 quad floating point routines.  */
*************** rs6000_generate_compare (enum rtx_code c
*** 11108,11114 ****
  	 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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
  	emit_insn (gen_rtx_PARALLEL (VOIDmode,
  	  gen_rtvec (9,
--- 11132,11138 ----
  	 CLOBBERs to match cmptf_internal2 pattern.  */
        if (comp_mode == CCFPmode && TARGET_XL_COMPAT
  	  && GET_MODE (rs6000_compare_op0) == TFmode
! 	  && !TARGET_IEEEQUAD
  	  && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
  	emit_insn (gen_rtx_PARALLEL (VOIDmode,
  	  gen_rtvec (9,
*************** rs6000_function_value (tree valtype, tre
*** 19027,19032 ****
--- 19051,19057 ----
  						   GP_ARG_RETURN + 3),
  				      GEN_INT (12))));
      }
+ 
    if ((INTEGRAL_TYPE_P (valtype)
         && TYPE_PRECISION (valtype) < BITS_PER_WORD)
        || POINTER_TYPE_P (valtype))
Index: config/rs6000/rs6000.h
===================================================================
*** config/rs6000/rs6000.h	(revision 109981)
--- config/rs6000/rs6000.h	(working copy)
*************** extern const char *rs6000_traceback_name
*** 291,296 ****
--- 291,297 ----
  /* 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;
*************** extern enum rs6000_nop_insertion rs6000_
*** 316,321 ****
--- 317,323 ----
  #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
*************** enum reg_class
*** 1214,1221 ****
  /* 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)		  \
     ? 0									  \
     : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)				  \
     ? reg_classes_intersect_p (FLOAT_REGS, CLASS)			  \
--- 1216,1223 ----
  /* Return a class of registers that cannot change FROM mode to TO mode.  */
  
  #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)			  \
!   (!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)			  \
Index: config/rs6000/rs6000.md
===================================================================
*** config/rs6000/rs6000.md	(revision 109981)
--- config/rs6000/rs6000.md	(working copy)
***************
*** 151,157 ****
  ; 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)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")])
  
  ; Various instructions that come in SI and DI forms.
--- 151,157 ----
  ; Any hardware-supported floating-point mode
  (define_mode_macro FP [(SF "TARGET_HARD_FLOAT")
    (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
!   (TF "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")])
  
  ; Various instructions that come in SI and DI forms.
***************
*** 8249,8255 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
  
--- 8249,8255 ----
  (define_expand "movtf"
    [(set (match_operand:TF 0 "general_operand" "")
  	(match_operand:TF 1 "any_operand" ""))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
  
***************
*** 8259,8265 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
     && (gpc_reg_operand (operands[0], TFmode)
         || gpc_reg_operand (operands[1], TFmode))"
--- 8259,8265 ----
  (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"))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
     && (gpc_reg_operand (operands[0], TFmode)
         || gpc_reg_operand (operands[1], TFmode))"
***************
*** 8273,8279 ****
    [(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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
    operands[2] = CONST0_RTX (DFmode);
--- 8273,8279 ----
    [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
  		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
  	      (use (match_dup 2))])]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
    operands[2] = CONST0_RTX (DFmode);
***************
*** 8283,8289 ****
    [(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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& reload_completed"
--- 8283,8289 ----
    [(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"))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& reload_completed"
***************
*** 8301,8307 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
    rtx tmp = gen_reg_rtx (DFmode);
--- 8301,8307 ----
  (define_expand "extendsftf2"
    [(set (match_operand:TF 0 "nonimmediate_operand" "")
  	(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
    rtx tmp = gen_reg_rtx (DFmode);
***************
*** 8313,8326 ****
  (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_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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "@
     #
--- 8313,8326 ----
  (define_expand "trunctfdf2"
    [(set (match_operand:DF 0 "gpc_reg_operand" "")
  	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
!   "!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")))]
!   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "@
     #
***************
*** 8336,8342 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "fadd %0,%1,%L1"
    [(set_attr "type" "fp")])
--- 8336,8342 ----
  (define_insn "trunctfdf2_internal2"
    [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
  	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
!   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "fadd %0,%1,%L1"
    [(set_attr "type" "fp")])
***************
*** 8345,8351 ****
    [(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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& reload_completed"
--- 8345,8351 ----
    [(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"))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& reload_completed"
***************
*** 8358,8364 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
    rtx tmp = gen_reg_rtx (DFmode);
--- 8358,8364 ----
  (define_expand "floatsitf2"
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
          (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
    rtx tmp = gen_reg_rtx (DFmode);
***************
*** 8386,8392 ****
  	      (clobber (match_dup 3))
  	      (clobber (match_dup 4))
  	      (clobber (match_dup 5))])]
!   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
     && (TARGET_POWER2 || TARGET_POWERPC)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
--- 8386,8392 ----
  	      (clobber (match_dup 3))
  	      (clobber (match_dup 4))
  	      (clobber (match_dup 5))])]
!   "!TARGET_IEEEQUAD
     && (TARGET_POWER2 || TARGET_POWERPC)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
  {
***************
*** 8403,8409 ****
     (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[5]))"
--- 8403,8409 ----
     (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"))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[5]))"
***************
*** 8424,8430 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "*
  {
--- 8424,8430 ----
  (define_insn "negtf2"
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
  	(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "*
  {
***************
*** 8439,8445 ****
  (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "
  {
--- 8439,8445 ----
  (define_expand "abstf2"
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
  	(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "
  {
***************
*** 8459,8465 ****
  			   (label_ref (match_operand 2 "" ""))
  			   (pc)))
     (set (match_dup 6) (neg:DF (match_dup 6)))]
!   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "
  {
--- 8459,8465 ----
  			   (label_ref (match_operand 2 "" ""))
  			   (pc)))
     (set (match_dup 6) (neg:DF (match_dup 6)))]
!   "!TARGET_IEEEQUAD
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "
  {
***************
*** 11398,11404 ****
    [(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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
    [(set_attr "type" "fpcompare")
--- 11398,11404 ----
    [(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")))]
!   "!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")
***************
*** 11416,11422 ****
      (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_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& reload_completed"
--- 11416,11422 ----
      (clobber (match_scratch:DF 8 "=f"))
      (clobber (match_scratch:DF 9 "=f"))
      (clobber (match_scratch:DF 10 "=f"))]
!   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
    "#"
    "&& reload_completed"
Index: config/rs6000/t-ppccomm
===================================================================
*** config/rs6000/t-ppccomm	(revision 109981)
--- config/rs6000/t-ppccomm	(working copy)
***************
*** 1,6 ****
  # Common support for PowerPC ELF targets (both EABI and SVR4).
  
! LIB2FUNCS_EXTRA = tramp.S
  
  # This one can't end up in shared libgcc
  LIB2FUNCS_STATIC_EXTRA = eabi.S
--- 1,6 ----
  # Common support for PowerPC ELF targets (both EABI and SVR4).
  
! LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
  
  # This one can't end up in shared libgcc
  LIB2FUNCS_STATIC_EXTRA = eabi.S
Index: config/rs6000/aix.h
===================================================================
*** config/rs6000/aix.h	(revision 109981)
--- config/rs6000/aix.h	(working copy)
***************
*** 38,43 ****
--- 38,45 ----
  #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.  */
Index: doc/invoke.texi
===================================================================
*** doc/invoke.texi	(revision 109981)
--- doc/invoke.texi	(working copy)
*************** enhancements.
*** 11111,11126 ****
  @opindex mno-vrsave
  Generate VRSAVE instructions when generating AltiVec code.
  
- @item -mabi=spe
- @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@.
- 
- @item -mabi=no-spe
- @opindex mabi=no-spe
- Disable Booke SPE ABI extensions for the current ABI@.
- 
  @item -msecure-plt
  @opindex msecure-plt
  Generate code that allows ld and ld.so to build executables and shared
--- 11111,11116 ----
*************** SVR4 ABI)@.
*** 11483,11489 ****
  @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}@.
  
  @item -mprototype
  @itemx -mno-prototype
--- 11473,11499 ----
  @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}@.
! 
! @item -mabi=spe
! @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@.
! 
! @item -mabi=no-spe
! @opindex mabi=no-spe
! Disable Booke SPE ABI extensions for the current ABI@.
! 
! @item -mabi=ibmlongdouble
! @opindex mabi=ibmlongdouble
! Change the current ABI to use IBM extended precision long double.
! This is a PowerPC 32-bit SYSV ABI option.
! 
! @item -mabi=ieeelongdouble
! @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



More information about the Gcc-patches mailing list