public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: PowerPC -- support single-precision FPU
@ 2008-09-21 21:18 David Edelsohn
  2008-09-21 21:20 ` Michael Eager
  2008-09-23 17:14 ` Michael Eager
  0 siblings, 2 replies; 26+ messages in thread
From: David Edelsohn @ 2008-09-21 21:18 UTC (permalink / raw)
  To: Michael Eager; +Cc: GCC Patches, Andrew Pinski

>>>>> Michael Eager writes:

>> Should floatsisf2_internal have the same constraints as floatdidf2?
>
> Yes.
>
> The condition for floatsisf2_internal should also be changed to
> "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT"
> so that it is only matched for -fsingle-float and not for -fdouble-float
> or classic PowerPC FPU.

The floatsisf2_internal pattern also needs TARGET_POWERPC64 condition.
 fcfid only is present
on processors that implement PowerPC64.

Is the floatsisf2_internal pattern even necessary?  Is that RTL and
instruction ever generated
for the Xilinx configuration?

The floatsisf2 define_expand pattern has final condition !TARGET_FPRS,
which was intended
for SPE and is false for the Xilinx processor.

Thanks, David

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

* Re: PowerPC -- support single-precision FPU
  2008-09-21 21:18 PowerPC -- support single-precision FPU David Edelsohn
@ 2008-09-21 21:20 ` Michael Eager
  2008-09-23 17:14 ` Michael Eager
  1 sibling, 0 replies; 26+ messages in thread
From: Michael Eager @ 2008-09-21 21:20 UTC (permalink / raw)
  To: David Edelsohn; +Cc: GCC Patches, Andrew Pinski

David Edelsohn wrote:
>>>>>> Michael Eager writes:
> 
>>> Should floatsisf2_internal have the same constraints as floatdidf2?
>> Yes.
>>
>> The condition for floatsisf2_internal should also be changed to
>> "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT"
>> so that it is only matched for -fsingle-float and not for -fdouble-float
>> or classic PowerPC FPU.
> 
> The floatsisf2_internal pattern also needs TARGET_POWERPC64 condition.
>  fcfid only is present
> on processors that implement PowerPC64.
> 
> Is the floatsisf2_internal pattern even necessary?  Is that RTL and
> instruction ever generated
> for the Xilinx configuration?

I'll move this into the Xilinx FPU-specific patch, conditioned with
the flag for that FPU.  Xilinx reused the opcode for their SI->SF
conversion instruction.

> The floatsisf2 define_expand pattern has final condition !TARGET_FPRS,
> which was intended
> for SPE and is false for the Xilinx processor.

Yep.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: PowerPC -- support single-precision FPU
  2008-09-21 21:18 PowerPC -- support single-precision FPU David Edelsohn
  2008-09-21 21:20 ` Michael Eager
@ 2008-09-23 17:14 ` Michael Eager
  2008-09-26 16:10   ` RESUBMIT: " Michael Eager
  1 sibling, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-09-23 17:14 UTC (permalink / raw)
  To: David Edelsohn; +Cc: GCC Patches, Andrew Pinski

[-- Attachment #1: Type: text/plain, Size: 1017 bytes --]

David Edelsohn wrote:
>>>>>> Michael Eager writes:
> 
>>> Should floatsisf2_internal have the same constraints as floatdidf2?
>> Yes.
>>
>> The condition for floatsisf2_internal should also be changed to
>> "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT"
>> so that it is only matched for -fsingle-float and not for -fdouble-float
>> or classic PowerPC FPU.
> 
> The floatsisf2_internal pattern also needs TARGET_POWERPC64 condition.
>  fcfid only is present
> on processors that implement PowerPC64.
> 
> Is the floatsisf2_internal pattern even necessary?  Is that RTL and
> instruction ever generated
> for the Xilinx configuration?
> 
> The floatsisf2 define_expand pattern has final condition !TARGET_FPRS,
> which was intended
> for SPE and is false for the Xilinx processor.

Updated patch attached.

Added TARGET_SINGLE_FPU condition to floatsisf2 and eliminated
floatsisf2_internal.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: changelog --]
[-- Type: text/plain, Size: 3414 bytes --]

2008-09-18  Michael J. Eager  <eager@eagercon.com>

	* config/rs6000/predicates.md (easy_fp_constant): single FP consts are easy
	* config/rs6000/rs6000.c (rs6000_override_options): move 
	rs6000_init_hard_regno_mode_ok after all options changed.
	Set rs6000_single_float, rs6000_double_float if TARGET_HARD_FLOAT.
	(rs6000_handle_option): Process -msingle-float (rs6000_single_float), 
	-mdouble-float (rs6000_double_float), -msimple-fpu flags (rs6000_simple_fpu)
	Add warning messages if single FP not configured.
	(rs6000_file_start): Output gnu_attribute for single-float
	(legitimate_lo_sum_address_p): condition on TARGET_DOUBLE_FLOAT
	(rs6000_legitimize_address): likewise
	(rs6000_legitimize_reload_address): likewise
	(rs6000_emit_move): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(function_arg_advance): likewise
	(function_arg): likewise
	(setup_incoming_varargs): condition on TARGET_DOUBLE_FLOAT
	(rs6000_gimplify_va_arg): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_split_multireg_move): condition on TARGET_DOUBLE_FLOAT
	(rs6000_emit_prologue): likewise
	(rs6000_function_value): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_libcall_value): likewise
	* config/rs6000/rs6000.h (TARGET_SINGLE_FLOAT): New default to 1
	(TARGET_DOUBLE_FLOAT): New default to 1
	(TARGET_SIMPLE_FPU): New default to 0
	(TARGET_SINGLE_FPU): New default to 0
	(TARGET_SINGLE_FLOAT_MODE): New.
	(TARGET_DOUBLE_FLOAT_MODE): New.
	* config/rs6000/singlefp.h: New; redefine TARGET_SINGLE_FLOAT,
	TARGET_DOUBLE_FLOAT, TARGET_SIMPLE_FPU, TARGET_SINGLE_FPU,
	UNITS_PER_FP_WORD
	* config/rs6000/rs6000.md (define_mode_iterator): condition on TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT
	(extendsfdf2,extendsfdf2_fpr,truncdfsf2,truncdfsf2_fpr, copysigndf3,fseldfsf4,
	negdf2, negdf2_fpr, absdf2, absdf2_fpr, nabsdf2_fpr, adddf3, adddf3_fpr, subdf3,
	subdf3_fpr, muldf3, muldf3_fpr, divdf3, divdf3_fpr, sqrtdf2, smaxdf3, smindf3,
	movdfcc, *fseldfdf4, floatsidf2, *floatsidf2_internal, floatunssidf2, 
	*floatunssidf2_internal, fix_truncdfsi2, *fix_truncdfsi2_internal, 
	fix_truncdfsi2_internal_gfxopt, fix_truncdfsi2_mfpgpr, fctiwz, btruncdf2,
	ceildf2, floordf2, rounddf2, floatdidf2, floatsidf_ppc64_mfpgpr, floatsidf_ppc64,
	floatunssidf_ppc64, fix_truncdfdi2, movdf_hardfloat32, movdf_hardfloat64_mfpgpr,
	movdf_hardfloat64, extenddftf2_fprs, extenddftf2_internal, trunctfdf2_internal2,
	fix_trunc_helper, abstf2_internal, movdf_update1, movdf_update2, cmpdf_internal1,
	cmptf_internal1, *cmptf_internal2): condition on TARGET_DOUBLE_FLOAT
	(aux_truncdfsf2, negsf2, *negsf2, abssf2, *abssf2, addsf3, subsf3, mulsf3,
	divsf3, sqrtsf2, copysignsf3, smaxsf3, sminsf3, movsfcc, *fselsfsf4, 
	fixuns_truncsfsi2, fix_truncsfsi2, floatunssisf2, btruncsf2, ceilsf2, 
	floorsf2, roundsf2, floatdisf2_internal1, floatdisf2_internal2,
	*movsf_hardfloat, trunctfsf2_fprs, *movsf_update1, *movsf_update2, 
	*cmpsf_internal1): Condition on TARGET_SINGLE_FLOAT.
	(divsf3, sqrtsf2, divdf3, divdf3_fpr): Condition on TARGET_SIMPLE_FPU.
	* config/rs6000/rs6000.opt (-msingle-floati): New
	(-mdouble-float): New
	(-msimple-fpu): New
	* gcc/doc/invoke.texi (RS/6000 and PowerPC Options): Add 
	-msingle-float, -mdouble-float, -msimple-fpu options
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): set _SOFT_DOUBLE 
	for -msingle-float
	* config.gcc: New config for target=powerpc-xilinx-eabi
	


[-- Attachment #3: gcc.patch --]
[-- Type: text/x-patch, Size: 64225 bytes --]

diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/predicates.md gcc/gcc/config/rs6000/predicates.md
--- gcc-orig/gcc/config/rs6000/predicates.md	2008-09-23 09:07:56.000000000 -0700
+++ gcc/gcc/config/rs6000/predicates.md	2008-09-23 09:09:33.000000000 -0700
@@ -192,7 +192,8 @@
     return 0;
 
   /* Consider all constants with -msoft-float to be easy.  */
-  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE 
+      || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT)))
       && mode != DImode)
     return 1;
 
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
--- gcc-orig/gcc/config/rs6000/rs6000.c	2008-09-23 09:07:57.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.c	2008-09-23 09:09:33.000000000 -0700
@@ -1556,8 +1556,6 @@ rs6000_override_options (const char *def
 		     | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
   };
 
-  rs6000_init_hard_regno_mode_ok ();
-
   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
 #ifdef OS_MISSING_POWERPC64
   if (OS_MISSING_POWERPC64)
@@ -1968,6 +1966,25 @@ rs6000_override_options (const char *def
      can be optimized to ap = __builtin_next_arg (0).  */
   if (DEFAULT_ABI != ABI_V4)
     targetm.expand_builtin_va_start = NULL;
+
+  /* Set up single/double float flags.  
+     If TARGET_HARD_FLOAT is set, but neither single or double is set, 
+     then set both flags. */
+  if (TARGET_HARD_FLOAT && TARGET_FPRS 
+      && rs6000_single_float == 0 && rs6000_double_float == 0)
+    rs6000_single_float = rs6000_double_float = 1;
+
+  /* Reset single and double FP flags if target is E500. */
+  if (TARGET_E500) 
+  {
+    rs6000_single_float = rs6000_double_float = 0;
+    if (TARGET_E500_SINGLE)
+      rs6000_single_float = 1; 
+    if (TARGET_E500_DOUBLE)
+      rs6000_single_float = rs6000_double_float = 1;
+  }
+
+  rs6000_init_hard_regno_mode_ok ();
 }
 
 /* Implement targetm.vectorize.builtin_mask_for_load.  */
@@ -2477,6 +2494,37 @@ rs6000_handle_option (size_t code, const
 	  return false;
 	}
       break;
+
+    case OPT_msingle_float:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msingle-float option equivalent to -mhard-float");
+      /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
+      rs6000_double_float = 0;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_mdouble_float:
+      /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
+      rs6000_single_float = 1;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_msimple_fpu:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msimple-fpu option ignored");
+      break;
+
+    case OPT_mhard_float:
+      /* -mhard_float implies -msingle-float and -mdouble-float. */
+      rs6000_single_float = rs6000_double_float = 1;
+      break;
+
+    case OPT_msoft_float:
+      /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
+      rs6000_single_float = rs6000_double_float = 0;
+      break;
     }
   return true;
 }
@@ -2546,7 +2594,9 @@ rs6000_file_start (void)
   if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
     {
       fprintf (file, "\t.gnu_attribute 4, %d\n",
-	       (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+	       ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 
+	        : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 
+	        : 2));
       fprintf (file, "\t.gnu_attribute 8, %d\n",
 	       (TARGET_ALTIVEC_ABI ? 2
 		: TARGET_SPE_ABI ? 3
@@ -3691,7 +3741,7 @@ legitimate_lo_sum_address_p (enum machin
 	return false;
       if (GET_MODE_BITSIZE (mode) > 64
 	  || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
-	      && !(TARGET_HARD_FLOAT && TARGET_FPRS
+	      && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
 		   && (mode == DFmode || mode == DDmode))))
 	return false;
 
@@ -3758,7 +3808,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (XEXP (x, 0)) == REG
 	   && GET_CODE (XEXP (x, 1)) != CONST_INT
 	   && GET_MODE_NUNITS (mode) == 1
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || TARGET_POWERPC64
 	       || ((mode != DImode && mode != DFmode && mode != DDmode)
 		   || (TARGET_E500_DOUBLE && mode != DDmode)))
@@ -3827,7 +3877,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && CONSTANT_P (x)
 	   && GET_MODE_NUNITS (mode) == 1
 	   && (GET_MODE_BITSIZE (mode) <= 32
-	       || ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	       || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 		   && (mode == DFmode || mode == DDmode))))
     {
       rtx reg = gen_reg_rtx (Pmode);
@@ -3842,7 +3892,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (x) != CONST_INT
 	   && GET_CODE (x) != CONST_DOUBLE
 	   && CONSTANT_P (x)
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || (mode != DFmode && mode != DDmode))
 	   && mode != DImode
 	   && mode != TImode)
@@ -4259,7 +4309,7 @@ rs6000_legitimize_reload_address (rtx x,
       && mode != TDmode
       && (mode != DImode || TARGET_POWERPC64)
       && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
-	  || (TARGET_FPRS && TARGET_HARD_FLOAT)))
+	  || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
     {
 #if TARGET_MACHO
       if (flag_pic)
@@ -4384,7 +4434,7 @@ rs6000_legitimate_address (enum machine_
       && mode != TImode
       && mode != TFmode
       && mode != TDmode
-      && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+      && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	  || TARGET_POWERPC64
 	  || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
       && (TARGET_POWERPC64 || mode != DImode)
@@ -4839,7 +4889,7 @@ rs6000_emit_move (rtx dest, rtx source, 
     operands[1] = force_reg (mode, operands[1]);
 
   if (mode == SFmode && ! TARGET_POWERPC
-      && TARGET_HARD_FLOAT && TARGET_FPRS
+      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
       && GET_CODE (operands[0]) == MEM)
     {
       int regnum;
@@ -5200,7 +5250,9 @@ rs6000_emit_move (rtx dest, rtx source, 
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)		\
   (SCALAR_FLOAT_MODE_P (MODE)			\
    && (CUM)->fregno <= FP_ARG_MAX_REG		\
-   && TARGET_HARD_FLOAT && TARGET_FPRS)
+   && TARGET_HARD_FLOAT && TARGET_FPRS 		\
+   && (TARGET_DOUBLE_FLOAT_MODE (MODE)		\
+       || TARGET_SINGLE_FLOAT_MODE (MODE)))
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)	\
@@ -5677,9 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || mode == SDmode || mode == DDmode || mode == TDmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)))
+          && (TARGET_SINGLE_FLOAT_MODE (mode)
+              || (TARGET_DOUBLE_FLOAT 
+                  && (mode == DFmode || mode == DDmode || mode == TDmode))
+              || (mode == TFmode && !TARGET_IEEEQUAD)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -5745,7 +5798,8 @@ function_arg_advance (CUMULATIVE_ARGS *c
       cum->words = align_words + n_words;
 
       if (SCALAR_FLOAT_MODE_P (mode)
-	  && TARGET_HARD_FLOAT && TARGET_FPRS)
+	  && TARGET_HARD_FLOAT && TARGET_FPRS
+ 	  && (TARGET_DOUBLE_FLOAT_MODE (mode) || TARGET_SINGLE_FLOAT_MODE (mode)))
 	{
 	  /* _Decimal128 must be passed in an even/odd float register pair.
 	     This assumes that the register number is odd when fregno is
@@ -6239,9 +6293,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)
-	      || mode == SDmode || mode == DDmode || mode == TDmode))
+	  && (TARGET_SINGLE_FLOAT_MODE(mode)
+	       || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode))
+	  && ((mode == TFmode && !TARGET_IEEEQUAD)
+	     || mode == SDmode || mode == DDmode || mode == TDmode)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -6701,11 +6756,17 @@ setup_incoming_varargs (CUMULATIVE_ARGS 
 	   fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
 	   fregno++, off += UNITS_PER_FP_WORD, nregs++)
 	{
-	  mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
-	  MEM_NOTRAP_P (mem) = 1;
-	  set_mem_alias_set (mem, set);
-	  set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
-	  emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
+	  mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			      ? DFmode : SFmode, 
+                             plus_constant (save_area, off));
+  	  MEM_NOTRAP_P (mem) = 1;
+  	  set_mem_alias_set (mem, set);
+	  set_mem_align (mem, GET_MODE_ALIGNMENT (
+			 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			  ? DFmode : SFmode));
+	  emit_move_insn (mem, gen_rtx_REG (
+                          (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			   ? DFmode : SFmode, fregno));
 	}
 
       emit_label (lab);
@@ -6920,18 +6981,19 @@ 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) == TFmode
-	  || TYPE_MODE (type) == SDmode
-	  || TYPE_MODE (type) == DDmode
-	  || TYPE_MODE (type) == TDmode))
+      && (TARGET_SINGLE_FLOAT_MODE (TYPE_MODE (type))
+          || (TARGET_DOUBLE_FLOAT 
+              && (TYPE_MODE (type) == DFmode 
+ 	          || TYPE_MODE (type) == TFmode
+	          || TYPE_MODE (type) == SDmode
+	          || TYPE_MODE (type) == DDmode
+	          || TYPE_MODE (type) == TDmode))))
     {
       /* FP args go in FP registers, if present.  */
       reg = fpr;
       n_reg = (size + 7) / 8;
-      sav_ofs = 8*4;
-      sav_scale = 8;
+      sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
+      sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
       if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
 	align = 8;
     }
@@ -14127,7 +14189,8 @@ rs6000_split_multireg_move (rtx dst, rtx
   mode = GET_MODE (dst);
   nregs = hard_regno_nregs[reg][mode];
   if (FP_REGNO_P (reg))
-    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 
+	((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
   else if (ALTIVEC_REGNO_P (reg))
     reg_mode = V16QImode;
   else if (TARGET_E500_DOUBLE && mode == TFmode)
@@ -16079,11 +16142,14 @@ rs6000_emit_prologue (void)
 	 properly.  */
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + sp_offset + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
 	}
@@ -16190,7 +16256,9 @@ rs6000_emit_prologue (void)
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
 	     && ! call_used_regs[info->first_fp_reg_save+i]))
-	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
+	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, 
+			   (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			    ? DFmode : SFmode,
 			   info->first_fp_reg_save + i,
 			   info->fp_save_offset + sp_offset + 8 * i,
 			   info->total_size);
@@ -16835,11 +16903,14 @@ rs6000_emit_epilogue (int sibcall)
 	}
       for (i = 0; info->first_fp_reg_save + i <= 63; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+ 			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
 	}
@@ -17244,9 +17315,12 @@ rs6000_emit_epilogue (int sibcall)
 			       GEN_INT (info->fp_save_offset
 					+ sp_offset
 					+ 8 * i));
-	  mem = gen_frame_mem (DFmode, addr);
+	  mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				 ? DFmode : SFmode), addr);
 
-	  emit_move_insn (gen_rtx_REG (DFmode,
+ 	  emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT 
+					 && TARGET_DOUBLE_FLOAT)
+				        ? DFmode : SFmode),
 				       info->first_fp_reg_save + i),
 			  mem);
 	}
@@ -22386,7 +22460,10 @@ rs6000_function_value (const_tree valtyp
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
-  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_FPRS 
+           && (TARGET_HARD_FLOAT 
+	       && (TARGET_SINGLE_FLOAT_MODE (mode) 
+	            || TARGET_DOUBLE_FLOAT)))
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
 	   && targetm.calls.split_complex_arg)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000-c.c gcc/gcc/config/rs6000/rs6000-c.c
--- gcc-orig/gcc/config/rs6000/rs6000-c.c	2008-09-23 09:07:56.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000-c.c	2008-09-23 09:09:33.000000000 -0700
@@ -297,7 +297,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     builtin_define ("__PAIRED__");
   if (TARGET_SOFT_FLOAT)
     builtin_define ("_SOFT_FLOAT");
-  if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+  if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+      ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT))
     builtin_define ("_SOFT_DOUBLE");
   /* Used by lwarx/stwcx. errata work-around.  */
   if (rs6000_cpu == PROCESSOR_PPC405)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.h gcc/gcc/config/rs6000/rs6000.h
--- gcc-orig/gcc/config/rs6000/rs6000.h	2008-09-23 09:07:56.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.h	2008-09-23 09:09:33.000000000 -0700
@@ -298,6 +298,17 @@ enum processor_type
    PROCESSOR_CELL
 };
 
+/* FPU operations supported. 
+   Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must 
+   also test TARGET_HARD_FLOAT.  */
+#define TARGET_SINGLE_FLOAT 1
+#define TARGET_DOUBLE_FLOAT 1
+#define TARGET_SINGLE_FPU   0
+#define TARGET_SIMPLE_FPU   0
+
+#define TARGET_SINGLE_FLOAT_MODE(MODE) (TARGET_SINGLE_FLOAT && (MODE) == SFmode)
+#define TARGET_DOUBLE_FLOAT_MODE(MODE) (TARGET_DOUBLE_FLOAT && (MODE) == DFmode)
+
 extern enum processor_type rs6000_cpu;
 
 /* Recast the processor type to the cpu attribute.  */
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.md gcc/gcc/config/rs6000/rs6000.md
--- gcc-orig/gcc/config/rs6000/rs6000.md	2008-09-23 09:07:57.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.md	2008-09-23 09:11:56.000000000 -0700
@@ -202,8 +202,11 @@
 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
 
 ; Any hardware-supported floating-point mode
-(define_mode_iterator FP [(SF "TARGET_HARD_FLOAT")
-  (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
+(define_mode_iterator FP [
+  (SF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
+  (DF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
   (TF "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
@@ -5059,13 +5062,13 @@
 (define_expand "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn_and_split "*extendsfdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "@
    #
    fmr %0,%1
@@ -5081,53 +5084,53 @@
 (define_expand "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*truncdfsf2_fpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "aux_truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5135,14 +5138,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fadds %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5150,7 +5153,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5158,14 +5161,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		  (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsubs %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5173,7 +5176,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5181,14 +5184,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fmuls %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5196,7 +5199,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5204,14 +5207,15 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		(match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fdivs %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
@@ -5219,7 +5223,8 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5247,7 +5252,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5256,7 +5262,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5265,7 +5272,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5274,7 +5282,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5284,7 +5293,7 @@
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5293,7 +5302,7 @@
 	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
    && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
@@ -5303,7 +5312,8 @@
 	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5313,7 +5323,7 @@
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5323,7 +5333,7 @@
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5333,7 +5343,7 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5342,7 +5352,8 @@
 	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5352,27 +5363,31 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
 (define_expand "sqrtsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) 
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT 
+   && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrts %0,%1"
   [(set_attr "type" "ssqrt")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5405,7 +5420,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
    && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
   {
      operands[3] = gen_reg_rtx (SFmode);
@@ -5423,7 +5438,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
    && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
   {
      operands[3] = gen_reg_rtx (DFmode);
@@ -5441,7 +5456,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "sminsf3"
@@ -5450,7 +5466,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5458,7 +5475,8 @@
 	(match_operator:SF 3 "min_max_operator"
 	 [(match_operand:SF 1 "gpc_reg_operand" "")
 	  (match_operand:SF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5519,7 +5537,7 @@
 	 (if_then_else:SF (match_operand 1 "comparison_operator" "")
 			  (match_operand:SF 2 "gpc_reg_operand" "")
 			  (match_operand:SF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5534,7 +5552,7 @@
 			     (match_operand:SF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5544,40 +5562,40 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
 (define_expand "negdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*negdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "absdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*absdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "*nabsdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5585,14 +5603,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*adddf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5600,14 +5618,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		  (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*subdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		  (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5615,14 +5633,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*muldf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5630,14 +5648,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		(match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn "*divdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		(match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5665,7 +5683,7 @@
 	(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			  (match_operand:DF 2 "gpc_reg_operand" "f"))
 		 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5674,7 +5692,7 @@
 	(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5683,7 +5701,7 @@
 	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				  (match_operand:DF 2 "gpc_reg_operand" "f"))
 			 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5693,7 +5711,7 @@
 	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5703,7 +5721,7 @@
 	(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				   (match_operand:DF 2 "gpc_reg_operand" "f"))
 			  (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5713,7 +5731,7 @@
 	(minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
 	          (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5721,7 +5739,8 @@
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5734,7 +5753,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "smindf3"
@@ -5743,7 +5763,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5751,7 +5772,8 @@
 	(match_operator:DF 3 "min_max_operator"
 	 [(match_operand:DF 1 "gpc_reg_operand" "")
 	  (match_operand:DF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5764,7 +5786,7 @@
 	 (if_then_else:DF (match_operand 1 "comparison_operator" "")
 			  (match_operand:DF 2 "gpc_reg_operand" "")
 			  (match_operand:DF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5779,7 +5801,7 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:DF 2 "gpc_reg_operand" "f")
 			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5798,13 +5820,13 @@
 (define_expand "fixuns_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "fix_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 ; For each of these conversions, there is a define_expand, a define_insn
@@ -5820,7 +5842,8 @@
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))
 	      (clobber (match_dup 6))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5850,7 +5873,7 @@
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5879,7 +5902,7 @@
 (define_expand "floatunssisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "floatunssidf2"
@@ -5889,7 +5912,7 @@
 	      (use (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5917,7 +5940,7 @@
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5947,7 +5970,7 @@
 	      (clobber (match_dup 2))
 	      (clobber (match_dup 3))])]
   "(TARGET_POWER2 || TARGET_POWERPC)
-   && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+   && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5983,7 +6006,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
   [(pc)]
@@ -6004,7 +6028,8 @@
   [(set (match_operand:SI 0 "memory_operand" "=Z")
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && TARGET_PPC_GFXOPT"
   "#"
   "&& 1"
@@ -6022,7 +6047,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& 1"
   [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ))
@@ -6039,63 +6065,64 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
 	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
 		   UNSPEC_FCTIWZ))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceildf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceilsf2"
  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floordf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floorsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "rounddf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "roundsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
@@ -6111,27 +6138,27 @@
 (define_expand "floatsisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && (!TARGET_FPRS || TARGET_SINGLE_FPU)"
   "")
 
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncdfdi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r")
 	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "floatdisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "
 {
   rtx val = operands[1];
@@ -6153,7 +6180,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))
    (clobber (match_scratch:DF 2 "=f"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -6187,7 +6214,7 @@
 			   (label_ref (match_operand:DI 2 "" ""))
 			   (pc)))
    (set (match_dup 0) (match_dup 1))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   operands[3] = gen_reg_rtx (DImode);
@@ -8219,7 +8246,7 @@
 	(match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))]
   "(gpc_reg_operand (operands[0], SFmode)
    || gpc_reg_operand (operands[1], SFmode))
-   && (TARGET_HARD_FLOAT && TARGET_FPRS)"
+   && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
   "@
    mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
@@ -8357,7 +8384,7 @@
 (define_insn "*movdf_hardfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8452,7 +8479,9 @@
 (define_insn "*movdf_softfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
 	(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
-  "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  "! TARGET_POWERPC64 
+   && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) 
+       || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8495,7 +8524,8 @@
 (define_insn "*movdf_hardfloat64_mfpgpr"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8521,7 +8551,8 @@
 (define_insn "*movdf_hardfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
-  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8614,7 +8645,8 @@
 		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
 	      (use (match_dup 2))])]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
 {
   operands[2] = CONST0_RTX (DFmode);
   /* Generate GOT reference early for SVR4 PIC.  */
@@ -8627,7 +8659,8 @@
        (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(pc)]
@@ -8684,7 +8717,8 @@
   [(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")])
 
@@ -8708,7 +8742,8 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -8738,7 +8773,7 @@
 	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
 		   UNSPEC_FIX_TRUNC_TF))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
   [(set_attr "type" "fp")
    (set_attr "length" "20")])
@@ -8859,7 +8894,8 @@
 			   (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "
 {
   const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
@@ -10010,7 +10046,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    lfsux %3,%0,%2
    lfsu %3,%2(%0)"
@@ -10022,7 +10058,7 @@
 	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    stfsux %3,%0,%2
    stfsu %3,%2(%0)"
@@ -10058,7 +10094,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    lfdux %3,%0,%2
    lfdu %3,%2(%0)"
@@ -10070,7 +10106,7 @@
 	(match_operand:DF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    stfdux %3,%0,%2
    stfdu %3,%2(%0)"
@@ -10091,7 +10127,7 @@
    (set (match_operand:DF 2 "gpc_reg_operand" "")
 	(match_operand:DF 3 "memory_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[0], operands[2])
    && mems_ok_for_quad_peep (operands[1], operands[3])"
   [(set (match_dup 0)
@@ -10113,7 +10149,7 @@
    (set (match_operand:DF 2 "memory_operand" "")
 	(match_operand:DF 3 "gpc_reg_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[1], operands[3])
    && mems_ok_for_quad_peep (operands[0], operands[2])"
   [(set (match_dup 0)
@@ -11899,7 +11935,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
 		      (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11907,7 +11943,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
 		      (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11917,7 +11953,7 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
    (set_attr "length" "12")])
@@ -11935,7 +11971,7 @@
     (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 13))
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.opt gcc/gcc/config/rs6000/rs6000.opt
--- gcc-orig/gcc/config/rs6000/rs6000.opt	2008-09-23 09:07:56.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.opt	2008-09-23 09:09:33.000000000 -0700
@@ -260,3 +260,15 @@ Specify alignment of structure fields de
 mprioritize-restricted-insns=
 Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority)
 Specify scheduling priority for dispatch slot restricted insns
+
+msingle-float
+Target RejectNegative Var(rs6000_single_float)
+Single-precision floating point unit
+
+mdouble-float
+Target RejectNegative Var(rs6000_double_float)
+Double-precision floating point unit
+
+msimple-fpu
+Target RejectNegative Var(rs6000_simple_fpu)
+Floating point unit does not support divide & sqrt
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/singlefp.h gcc/gcc/config/rs6000/singlefp.h
--- gcc-orig/gcc/config/rs6000/singlefp.h	1969-12-31 16:00:00.000000000 -0800
+++ gcc/gcc/config/rs6000/singlefp.h	2008-09-23 09:09:33.000000000 -0700
@@ -0,0 +1,40 @@
+/* Definitions for PowerPC single-precision floating point unit
+   such as Xilinx PowerPC 405/440 APU.
+
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Michael Eager (eager@eagercon.com)
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Undefine definitions from rs6000.h. */
+#undef TARGET_SINGLE_FLOAT
+#undef TARGET_DOUBLE_FLOAT
+#undef TARGET_SINGLE_FPU
+#undef TARGET_SIMPLE_FPU
+#undef UNITS_PER_FP_WORD
+
+/* FPU operations supported. 
+   If TARGET_SINGLE_FPU set, processor supports single fp options. */
+#define TARGET_SINGLE_FLOAT (rs6000_single_float)
+#define TARGET_DOUBLE_FLOAT (rs6000_double_float)
+#define TARGET_SINGLE_FPU   1
+#define TARGET_SIMPLE_FPU   (rs6000_simple_fpu)
+
+/* FP word width depends on single/double fp support. */
+#define UNITS_PER_FP_WORD ((TARGET_SOFT_FLOAT || TARGET_DOUBLE_FLOAT) ? 8 : 4)
+
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config.gcc gcc/gcc/config.gcc
--- gcc-orig/gcc/config.gcc	2008-09-23 09:07:58.000000000 -0700
+++ gcc/gcc/config.gcc	2008-09-23 09:09:33.000000000 -0700
@@ -1791,6 +1791,11 @@ powerpc-*-eabialtivec*)
 	extra_options="${extra_options} rs6000/sysv4.opt"
 	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
 	;;
+powerpc-xilinx-eabi*)
+	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/singlefp.h"
+	extra_options="${extra_options} rs6000/sysv4.opt"
+	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+	;;
 powerpc-*-eabi*)
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
 	extra_options="${extra_options} rs6000/sysv4.opt"
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/doc/invoke.texi gcc/gcc/doc/invoke.texi
--- gcc-orig/gcc/doc/invoke.texi	2008-09-23 09:07:55.000000000 -0700
+++ gcc/gcc/doc/invoke.texi	2008-09-23 09:09:33.000000000 -0700
@@ -715,6 +715,7 @@ See RS/6000 and PowerPC Options.
 -m64  -m32  -mxl-compat  -mno-xl-compat  -mpe @gol
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
+-msingle-float -mdouble-float -msimple-fpu @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
 -mfused-madd  -mno-fused-madd  -mbit-align  -mno-bit-align @gol
 -mstrict-align  -mno-strict-align  -mrelocatable @gol
@@ -13419,7 +13420,8 @@ following options:
 
 @gccoptlist{-maltivec  -mfprnd  -mhard-float  -mmfcrf  -mmultiple @gol
 -mnew-mnemonics  -mpopcntb  -mpower  -mpower2  -mpowerpc64 @gol
--mpowerpc-gpopt  -mpowerpc-gfxopt  -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
+-mpowerpc-gpopt  -mpowerpc-gfxopt  -msingle-float -mdouble-float @gol
+-msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
 
 The particular options set for any particular CPU will vary between
 compiler versions, depending on what setting seems to produce optimal
@@ -13636,6 +13638,17 @@ Generate code that does not use (uses) t
 Software floating point emulation is provided if you use the
 @option{-msoft-float} option, and pass the option to GCC when linking.
 
+@item -msingle-float
+@itemx -mdouble-float
+@opindex msingle-float
+@opindex mdouble-float
+Generate code for single or double-precision floating point operations. 
+@option{-mdouble-float} implies @option{-msingle-float}. 
+
+@item -msimple-fpu
+@opindex msimple-fpu
+Do not generate sqrt and div instructions for hardware floating point unit.
+
 @item -mmultiple
 @itemx -mno-multiple
 @opindex mmultiple

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

* RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-23 17:14 ` Michael Eager
@ 2008-09-26 16:10   ` Michael Eager
  2008-09-26 17:45     ` Janis Johnson
  0 siblings, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-09-26 16:10 UTC (permalink / raw)
  To: GCC Patches; +Cc: David Edelsohn, Andrew Pinski

[-- Attachment #1: Type: text/plain, Size: 1291 bytes --]

Michael Eager wrote:
> David Edelsohn wrote:
>>>>>>> Michael Eager writes:
>>
>>>> Should floatsisf2_internal have the same constraints as floatdidf2?
>>> Yes.
>>>
>>> The condition for floatsisf2_internal should also be changed to
>>> "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && ! 
>>> TARGET_DOUBLE_FLOAT"
>>> so that it is only matched for -fsingle-float and not for -fdouble-float
>>> or classic PowerPC FPU.
>>
>> The floatsisf2_internal pattern also needs TARGET_POWERPC64 condition.
>>  fcfid only is present
>> on processors that implement PowerPC64.
>>
>> Is the floatsisf2_internal pattern even necessary?  Is that RTL and
>> instruction ever generated
>> for the Xilinx configuration?
>>
>> The floatsisf2 define_expand pattern has final condition !TARGET_FPRS,
>> which was intended
>> for SPE and is false for the Xilinx processor.
> 
> Updated patch attached.
> 
> Added TARGET_SINGLE_FPU condition to floatsisf2 and eliminated
> floatsisf2_internal.

There were problems with the TARGET_SINGLE_FLOAT_MODE and
TARGET_DOUBLE_FLOAT_MODE macros in the previous patch, and it
turns out that they really didn't make much difference.

They have been removed from this patch.



-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: changelog --]
[-- Type: text/plain, Size: 3346 bytes --]

2008-09-26  Michael J. Eager  <eager@eagercon.com>

	* config/rs6000/predicates.md (easy_fp_constant): single FP consts are easy
	* config/rs6000/rs6000.c (rs6000_override_options): move 
	rs6000_init_hard_regno_mode_ok after all options changed.
	Set rs6000_single_float, rs6000_double_float if TARGET_HARD_FLOAT.
	(rs6000_handle_option): Process -msingle-float (rs6000_single_float), 
	-mdouble-float (rs6000_double_float), -msimple-fpu flags (rs6000_simple_fpu)
	Add warning messages if single FP not configured.
	(rs6000_file_start): Output gnu_attribute for single-float
	(legitimate_lo_sum_address_p): condition on TARGET_DOUBLE_FLOAT
	(rs6000_legitimize_address): likewise
	(rs6000_legitimize_reload_address): likewise
	(rs6000_emit_move): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(function_arg_advance): likewise
	(function_arg): likewise
	(setup_incoming_varargs): condition on TARGET_DOUBLE_FLOAT
	(rs6000_gimplify_va_arg): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_split_multireg_move): condition on TARGET_DOUBLE_FLOAT
	(rs6000_emit_prologue): likewise
	(rs6000_function_value): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_libcall_value): likewise
	* config/rs6000/rs6000.h (TARGET_SINGLE_FLOAT): New default to 1
	(TARGET_DOUBLE_FLOAT): New default to 1
	(TARGET_SIMPLE_FPU): New default to 0
	(TARGET_SINGLE_FPU): New default to 0
	* config/rs6000/singlefp.h: New; redefine TARGET_SINGLE_FLOAT,
	TARGET_DOUBLE_FLOAT, TARGET_SIMPLE_FPU, TARGET_SINGLE_FPU,
	UNITS_PER_FP_WORD
	* config/rs6000/rs6000.md (define_mode_iterator): condition on TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT
	(extendsfdf2,extendsfdf2_fpr,truncdfsf2,truncdfsf2_fpr, copysigndf3,fseldfsf4,
	negdf2, negdf2_fpr, absdf2, absdf2_fpr, nabsdf2_fpr, adddf3, adddf3_fpr, subdf3,
	subdf3_fpr, muldf3, muldf3_fpr, divdf3, divdf3_fpr, sqrtdf2, smaxdf3, smindf3,
	movdfcc, *fseldfdf4, floatsidf2, *floatsidf2_internal, floatunssidf2, 
	*floatunssidf2_internal, fix_truncdfsi2, *fix_truncdfsi2_internal, 
	fix_truncdfsi2_internal_gfxopt, fix_truncdfsi2_mfpgpr, fctiwz, btruncdf2,
	ceildf2, floordf2, rounddf2, floatdidf2, floatsidf_ppc64_mfpgpr, floatsidf_ppc64,
	floatunssidf_ppc64, fix_truncdfdi2, movdf_hardfloat32, movdf_hardfloat64_mfpgpr,
	movdf_hardfloat64, extenddftf2_fprs, extenddftf2_internal, trunctfdf2_internal2,
	fix_trunc_helper, abstf2_internal, movdf_update1, movdf_update2, cmpdf_internal1,
	cmptf_internal1, *cmptf_internal2): condition on TARGET_DOUBLE_FLOAT
	(aux_truncdfsf2, negsf2, *negsf2, abssf2, *abssf2, addsf3, subsf3, mulsf3,
	divsf3, sqrtsf2, copysignsf3, smaxsf3, sminsf3, movsfcc, *fselsfsf4, 
	fixuns_truncsfsi2, fix_truncsfsi2, floatunssisf2, btruncsf2, ceilsf2, 
	floorsf2, roundsf2, floatdisf2_internal1, floatdisf2_internal2,
	*movsf_hardfloat, trunctfsf2_fprs, *movsf_update1, *movsf_update2, 
	*cmpsf_internal1): Condition on TARGET_SINGLE_FLOAT.
	(divsf3, sqrtsf2, divdf3, divdf3_fpr): Condition on TARGET_SIMPLE_FPU.
	* config/rs6000/rs6000.opt (-msingle-floati): New
	(-mdouble-float): New
	(-msimple-fpu): New
	* gcc/doc/invoke.texi (RS/6000 and PowerPC Options): Add 
	-msingle-float, -mdouble-float, -msimple-fpu options
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): set _SOFT_DOUBLE 
	for -msingle-float
	* config.gcc: New config for target=powerpc-xilinx-eabi
	


[-- Attachment #3: gcc.patch --]
[-- Type: text/x-patch, Size: 64136 bytes --]

diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/predicates.md gcc/gcc/config/rs6000/predicates.md
--- gcc-orig/gcc/config/rs6000/predicates.md	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/config/rs6000/predicates.md	2008-09-25 17:08:02.000000000 -0700
@@ -192,7 +192,8 @@
     return 0;
 
   /* Consider all constants with -msoft-float to be easy.  */
-  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE 
+      || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT)))
       && mode != DImode)
     return 1;
 
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
--- gcc-orig/gcc/config/rs6000/rs6000.c	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.c	2008-09-26 08:14:33.000000000 -0700
@@ -1556,8 +1556,6 @@ rs6000_override_options (const char *def
 		     | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
   };
 
-  rs6000_init_hard_regno_mode_ok ();
-
   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
 #ifdef OS_MISSING_POWERPC64
   if (OS_MISSING_POWERPC64)
@@ -1968,6 +1966,25 @@ rs6000_override_options (const char *def
      can be optimized to ap = __builtin_next_arg (0).  */
   if (DEFAULT_ABI != ABI_V4)
     targetm.expand_builtin_va_start = NULL;
+
+  /* Set up single/double float flags.  
+     If TARGET_HARD_FLOAT is set, but neither single or double is set, 
+     then set both flags. */
+  if (TARGET_HARD_FLOAT && TARGET_FPRS 
+      && rs6000_single_float == 0 && rs6000_double_float == 0)
+    rs6000_single_float = rs6000_double_float = 1;
+
+  /* Reset single and double FP flags if target is E500. */
+  if (TARGET_E500) 
+  {
+    rs6000_single_float = rs6000_double_float = 0;
+    if (TARGET_E500_SINGLE)
+      rs6000_single_float = 1; 
+    if (TARGET_E500_DOUBLE)
+      rs6000_single_float = rs6000_double_float = 1;
+  }
+
+  rs6000_init_hard_regno_mode_ok ();
 }
 
 /* Implement targetm.vectorize.builtin_mask_for_load.  */
@@ -2477,6 +2494,37 @@ rs6000_handle_option (size_t code, const
 	  return false;
 	}
       break;
+
+    case OPT_msingle_float:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msingle-float option equivalent to -mhard-float");
+      /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
+      rs6000_double_float = 0;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_mdouble_float:
+      /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
+      rs6000_single_float = 1;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_msimple_fpu:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msimple-fpu option ignored");
+      break;
+
+    case OPT_mhard_float:
+      /* -mhard_float implies -msingle-float and -mdouble-float. */
+      rs6000_single_float = rs6000_double_float = 1;
+      break;
+
+    case OPT_msoft_float:
+      /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
+      rs6000_single_float = rs6000_double_float = 0;
+      break;
     }
   return true;
 }
@@ -2546,7 +2594,9 @@ rs6000_file_start (void)
   if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
     {
       fprintf (file, "\t.gnu_attribute 4, %d\n",
-	       (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+	       ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 
+	        : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 
+	        : 2));
       fprintf (file, "\t.gnu_attribute 8, %d\n",
 	       (TARGET_ALTIVEC_ABI ? 2
 		: TARGET_SPE_ABI ? 3
@@ -3691,7 +3741,7 @@ legitimate_lo_sum_address_p (enum machin
 	return false;
       if (GET_MODE_BITSIZE (mode) > 64
 	  || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
-	      && !(TARGET_HARD_FLOAT && TARGET_FPRS
+	      && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
 		   && (mode == DFmode || mode == DDmode))))
 	return false;
 
@@ -3758,7 +3808,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (XEXP (x, 0)) == REG
 	   && GET_CODE (XEXP (x, 1)) != CONST_INT
 	   && GET_MODE_NUNITS (mode) == 1
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || TARGET_POWERPC64
 	       || ((mode != DImode && mode != DFmode && mode != DDmode)
 		   || (TARGET_E500_DOUBLE && mode != DDmode)))
@@ -3827,7 +3877,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && CONSTANT_P (x)
 	   && GET_MODE_NUNITS (mode) == 1
 	   && (GET_MODE_BITSIZE (mode) <= 32
-	       || ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	       || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 		   && (mode == DFmode || mode == DDmode))))
     {
       rtx reg = gen_reg_rtx (Pmode);
@@ -3842,7 +3892,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (x) != CONST_INT
 	   && GET_CODE (x) != CONST_DOUBLE
 	   && CONSTANT_P (x)
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || (mode != DFmode && mode != DDmode))
 	   && mode != DImode
 	   && mode != TImode)
@@ -4259,7 +4309,7 @@ rs6000_legitimize_reload_address (rtx x,
       && mode != TDmode
       && (mode != DImode || TARGET_POWERPC64)
       && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
-	  || (TARGET_FPRS && TARGET_HARD_FLOAT)))
+	  || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
     {
 #if TARGET_MACHO
       if (flag_pic)
@@ -4384,7 +4434,7 @@ rs6000_legitimate_address (enum machine_
       && mode != TImode
       && mode != TFmode
       && mode != TDmode
-      && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+      && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	  || TARGET_POWERPC64
 	  || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
       && (TARGET_POWERPC64 || mode != DImode)
@@ -4839,7 +4889,7 @@ rs6000_emit_move (rtx dest, rtx source, 
     operands[1] = force_reg (mode, operands[1]);
 
   if (mode == SFmode && ! TARGET_POWERPC
-      && TARGET_HARD_FLOAT && TARGET_FPRS
+      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
       && GET_CODE (operands[0]) == MEM)
     {
       int regnum;
@@ -5200,7 +5250,9 @@ rs6000_emit_move (rtx dest, rtx source, 
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)		\
   (SCALAR_FLOAT_MODE_P (MODE)			\
    && (CUM)->fregno <= FP_ARG_MAX_REG		\
-   && TARGET_HARD_FLOAT && TARGET_FPRS)
+   && TARGET_HARD_FLOAT && TARGET_FPRS 		\
+   && ((TARGET_DOUBLE_FLOAT && (MODE) == DFmode)\
+       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)	\
@@ -5677,9 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || mode == SDmode || mode == DDmode || mode == TDmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)))
+          && ((TARGET_SINGLE_FLOAT && mode == SFmode)
+              || (TARGET_DOUBLE_FLOAT 
+                  && (mode == DFmode || mode == DDmode || mode == TDmode))
+              || (mode == TFmode && !TARGET_IEEEQUAD)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -5745,7 +5798,9 @@ function_arg_advance (CUMULATIVE_ARGS *c
       cum->words = align_words + n_words;
 
       if (SCALAR_FLOAT_MODE_P (mode)
-	  && TARGET_HARD_FLOAT && TARGET_FPRS)
+	  && TARGET_HARD_FLOAT && TARGET_FPRS
+ 	  && ((TARGET_DOUBLE_FLOAT && mode == DFmode)
+ 	      || (TARGET_SINGLE_FLOAT && mode == SFmode)))
 	{
 	  /* _Decimal128 must be passed in an even/odd float register pair.
 	     This assumes that the register number is odd when fregno is
@@ -6239,9 +6294,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)
-	      || mode == SDmode || mode == DDmode || mode == TDmode))
+	  && (((TARGET_SINGLE_FLOAT && mode == SFmode)
+	       || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode)))
+	  && ((mode == TFmode && !TARGET_IEEEQUAD)
+	     || mode == SDmode || mode == DDmode || mode == TDmode)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -6701,11 +6757,17 @@ setup_incoming_varargs (CUMULATIVE_ARGS 
 	   fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
 	   fregno++, off += UNITS_PER_FP_WORD, nregs++)
 	{
-	  mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
-	  MEM_NOTRAP_P (mem) = 1;
-	  set_mem_alias_set (mem, set);
-	  set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
-	  emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
+	  mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			      ? DFmode : SFmode, 
+                             plus_constant (save_area, off));
+  	  MEM_NOTRAP_P (mem) = 1;
+  	  set_mem_alias_set (mem, set);
+	  set_mem_align (mem, GET_MODE_ALIGNMENT (
+			 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			  ? DFmode : SFmode));
+	  emit_move_insn (mem, gen_rtx_REG (
+                          (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			   ? DFmode : SFmode, fregno));
 	}
 
       emit_label (lab);
@@ -6920,18 +6982,19 @@ 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) == TFmode
-	  || TYPE_MODE (type) == SDmode
-	  || TYPE_MODE (type) == DDmode
-	  || TYPE_MODE (type) == TDmode))
+      && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
+          || (TARGET_DOUBLE_FLOAT 
+              && (TYPE_MODE (type) == DFmode 
+ 	          || TYPE_MODE (type) == TFmode
+	          || TYPE_MODE (type) == SDmode
+	          || TYPE_MODE (type) == DDmode
+	          || TYPE_MODE (type) == TDmode))))
     {
       /* FP args go in FP registers, if present.  */
       reg = fpr;
       n_reg = (size + 7) / 8;
-      sav_ofs = 8*4;
-      sav_scale = 8;
+      sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
+      sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
       if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
 	align = 8;
     }
@@ -14127,7 +14190,8 @@ rs6000_split_multireg_move (rtx dst, rtx
   mode = GET_MODE (dst);
   nregs = hard_regno_nregs[reg][mode];
   if (FP_REGNO_P (reg))
-    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 
+	((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
   else if (ALTIVEC_REGNO_P (reg))
     reg_mode = V16QImode;
   else if (TARGET_E500_DOUBLE && mode == TFmode)
@@ -16079,11 +16143,14 @@ rs6000_emit_prologue (void)
 	 properly.  */
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + sp_offset + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
 	}
@@ -16190,7 +16257,9 @@ rs6000_emit_prologue (void)
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
 	     && ! call_used_regs[info->first_fp_reg_save+i]))
-	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
+	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, 
+			   (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			    ? DFmode : SFmode,
 			   info->first_fp_reg_save + i,
 			   info->fp_save_offset + sp_offset + 8 * i,
 			   info->total_size);
@@ -16835,11 +16904,14 @@ rs6000_emit_epilogue (int sibcall)
 	}
       for (i = 0; info->first_fp_reg_save + i <= 63; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+ 			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
 	}
@@ -17244,9 +17316,12 @@ rs6000_emit_epilogue (int sibcall)
 			       GEN_INT (info->fp_save_offset
 					+ sp_offset
 					+ 8 * i));
-	  mem = gen_frame_mem (DFmode, addr);
+	  mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				 ? DFmode : SFmode), addr);
 
-	  emit_move_insn (gen_rtx_REG (DFmode,
+ 	  emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT 
+					 && TARGET_DOUBLE_FLOAT)
+				        ? DFmode : SFmode),
 				       info->first_fp_reg_save + i),
 			  mem);
 	}
@@ -22386,7 +22461,10 @@ rs6000_function_value (const_tree valtyp
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
-  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_FPRS 
+           && (TARGET_HARD_FLOAT 
+	       && ((TARGET_SINGLE_FLOAT && mode == SFmode) 
+	           || TARGET_DOUBLE_FLOAT)))
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
 	   && targetm.calls.split_complex_arg)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000-c.c gcc/gcc/config/rs6000/rs6000-c.c
--- gcc-orig/gcc/config/rs6000/rs6000-c.c	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000-c.c	2008-09-25 17:08:02.000000000 -0700
@@ -297,7 +297,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     builtin_define ("__PAIRED__");
   if (TARGET_SOFT_FLOAT)
     builtin_define ("_SOFT_FLOAT");
-  if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+  if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+      ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT))
     builtin_define ("_SOFT_DOUBLE");
   /* Used by lwarx/stwcx. errata work-around.  */
   if (rs6000_cpu == PROCESSOR_PPC405)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.h gcc/gcc/config/rs6000/rs6000.h
--- gcc-orig/gcc/config/rs6000/rs6000.h	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.h	2008-09-25 17:08:02.000000000 -0700
@@ -298,6 +298,14 @@ enum processor_type
    PROCESSOR_CELL
 };
 
+/* FPU operations supported. 
+   Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must 
+   also test TARGET_HARD_FLOAT.  */
+#define TARGET_SINGLE_FLOAT 1
+#define TARGET_DOUBLE_FLOAT 1
+#define TARGET_SINGLE_FPU   0
+#define TARGET_SIMPLE_FPU   0
+
 extern enum processor_type rs6000_cpu;
 
 /* Recast the processor type to the cpu attribute.  */
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.md gcc/gcc/config/rs6000/rs6000.md
--- gcc-orig/gcc/config/rs6000/rs6000.md	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.md	2008-09-25 17:08:02.000000000 -0700
@@ -202,8 +202,11 @@
 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
 
 ; Any hardware-supported floating-point mode
-(define_mode_iterator FP [(SF "TARGET_HARD_FLOAT")
-  (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
+(define_mode_iterator FP [
+  (SF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
+  (DF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
   (TF "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
@@ -5059,13 +5062,13 @@
 (define_expand "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn_and_split "*extendsfdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "@
    #
    fmr %0,%1
@@ -5081,53 +5084,53 @@
 (define_expand "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*truncdfsf2_fpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "aux_truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5135,14 +5138,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fadds %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5150,7 +5153,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5158,14 +5161,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		  (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsubs %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5173,7 +5176,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5181,14 +5184,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fmuls %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5196,7 +5199,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5204,14 +5207,15 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		(match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fdivs %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
@@ -5219,7 +5223,8 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5247,7 +5252,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5256,7 +5262,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5265,7 +5272,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5274,7 +5282,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5284,7 +5293,7 @@
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5293,7 +5302,7 @@
 	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
    && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
@@ -5303,7 +5312,8 @@
 	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5313,7 +5323,7 @@
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5323,7 +5333,7 @@
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5333,7 +5343,7 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5342,7 +5352,8 @@
 	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5352,27 +5363,31 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
 (define_expand "sqrtsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) 
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT 
+   && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrts %0,%1"
   [(set_attr "type" "ssqrt")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5405,7 +5420,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
    && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
   {
      operands[3] = gen_reg_rtx (SFmode);
@@ -5423,7 +5438,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
    && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
   {
      operands[3] = gen_reg_rtx (DFmode);
@@ -5441,7 +5456,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "sminsf3"
@@ -5450,7 +5466,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5458,7 +5475,8 @@
 	(match_operator:SF 3 "min_max_operator"
 	 [(match_operand:SF 1 "gpc_reg_operand" "")
 	  (match_operand:SF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5519,7 +5537,7 @@
 	 (if_then_else:SF (match_operand 1 "comparison_operator" "")
 			  (match_operand:SF 2 "gpc_reg_operand" "")
 			  (match_operand:SF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5534,7 +5552,7 @@
 			     (match_operand:SF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5544,40 +5562,40 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
 (define_expand "negdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*negdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "absdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*absdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "*nabsdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5585,14 +5603,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*adddf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5600,14 +5618,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		  (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*subdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		  (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5615,14 +5633,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*muldf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5630,14 +5648,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		(match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn "*divdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		(match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5665,7 +5683,7 @@
 	(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			  (match_operand:DF 2 "gpc_reg_operand" "f"))
 		 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5674,7 +5692,7 @@
 	(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5683,7 +5701,7 @@
 	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				  (match_operand:DF 2 "gpc_reg_operand" "f"))
 			 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5693,7 +5711,7 @@
 	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5703,7 +5721,7 @@
 	(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				   (match_operand:DF 2 "gpc_reg_operand" "f"))
 			  (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5713,7 +5731,7 @@
 	(minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
 	          (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5721,7 +5739,8 @@
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5734,7 +5753,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "smindf3"
@@ -5743,7 +5763,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5751,7 +5772,8 @@
 	(match_operator:DF 3 "min_max_operator"
 	 [(match_operand:DF 1 "gpc_reg_operand" "")
 	  (match_operand:DF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5764,7 +5786,7 @@
 	 (if_then_else:DF (match_operand 1 "comparison_operator" "")
 			  (match_operand:DF 2 "gpc_reg_operand" "")
 			  (match_operand:DF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5779,7 +5801,7 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:DF 2 "gpc_reg_operand" "f")
 			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5798,13 +5820,13 @@
 (define_expand "fixuns_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "fix_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 ; For each of these conversions, there is a define_expand, a define_insn
@@ -5820,7 +5842,8 @@
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))
 	      (clobber (match_dup 6))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5850,7 +5873,7 @@
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5879,7 +5902,7 @@
 (define_expand "floatunssisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "floatunssidf2"
@@ -5889,7 +5912,7 @@
 	      (use (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5917,7 +5940,7 @@
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5947,7 +5970,7 @@
 	      (clobber (match_dup 2))
 	      (clobber (match_dup 3))])]
   "(TARGET_POWER2 || TARGET_POWERPC)
-   && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+   && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5983,7 +6006,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
   [(pc)]
@@ -6004,7 +6028,8 @@
   [(set (match_operand:SI 0 "memory_operand" "=Z")
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && TARGET_PPC_GFXOPT"
   "#"
   "&& 1"
@@ -6022,7 +6047,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& 1"
   [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ))
@@ -6039,63 +6065,64 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
 	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
 		   UNSPEC_FCTIWZ))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceildf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceilsf2"
  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floordf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floorsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "rounddf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "roundsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
@@ -6111,27 +6138,27 @@
 (define_expand "floatsisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && (!TARGET_FPRS || TARGET_SINGLE_FPU)"
   "")
 
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncdfdi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r")
 	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "floatdisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "
 {
   rtx val = operands[1];
@@ -6153,7 +6180,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))
    (clobber (match_scratch:DF 2 "=f"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -6187,7 +6214,7 @@
 			   (label_ref (match_operand:DI 2 "" ""))
 			   (pc)))
    (set (match_dup 0) (match_dup 1))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   operands[3] = gen_reg_rtx (DImode);
@@ -8219,7 +8246,7 @@
 	(match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))]
   "(gpc_reg_operand (operands[0], SFmode)
    || gpc_reg_operand (operands[1], SFmode))
-   && (TARGET_HARD_FLOAT && TARGET_FPRS)"
+   && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
   "@
    mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
@@ -8357,7 +8384,7 @@
 (define_insn "*movdf_hardfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8452,7 +8479,9 @@
 (define_insn "*movdf_softfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
 	(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
-  "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  "! TARGET_POWERPC64 
+   && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) 
+       || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8495,7 +8524,8 @@
 (define_insn "*movdf_hardfloat64_mfpgpr"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8521,7 +8551,8 @@
 (define_insn "*movdf_hardfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
-  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8614,7 +8645,8 @@
 		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
 	      (use (match_dup 2))])]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
 {
   operands[2] = CONST0_RTX (DFmode);
   /* Generate GOT reference early for SVR4 PIC.  */
@@ -8627,7 +8659,8 @@
        (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(pc)]
@@ -8684,7 +8717,8 @@
   [(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")])
 
@@ -8708,7 +8742,8 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -8738,7 +8773,7 @@
 	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
 		   UNSPEC_FIX_TRUNC_TF))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
   [(set_attr "type" "fp")
    (set_attr "length" "20")])
@@ -8859,7 +8894,8 @@
 			   (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "
 {
   const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
@@ -10010,7 +10046,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    lfsux %3,%0,%2
    lfsu %3,%2(%0)"
@@ -10022,7 +10058,7 @@
 	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    stfsux %3,%0,%2
    stfsu %3,%2(%0)"
@@ -10058,7 +10094,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    lfdux %3,%0,%2
    lfdu %3,%2(%0)"
@@ -10070,7 +10106,7 @@
 	(match_operand:DF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    stfdux %3,%0,%2
    stfdu %3,%2(%0)"
@@ -10091,7 +10127,7 @@
    (set (match_operand:DF 2 "gpc_reg_operand" "")
 	(match_operand:DF 3 "memory_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[0], operands[2])
    && mems_ok_for_quad_peep (operands[1], operands[3])"
   [(set (match_dup 0)
@@ -10113,7 +10149,7 @@
    (set (match_operand:DF 2 "memory_operand" "")
 	(match_operand:DF 3 "gpc_reg_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[1], operands[3])
    && mems_ok_for_quad_peep (operands[0], operands[2])"
   [(set (match_dup 0)
@@ -11899,7 +11935,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
 		      (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11907,7 +11943,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
 		      (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11917,7 +11953,7 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
    (set_attr "length" "12")])
@@ -11935,7 +11971,7 @@
     (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 13))
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.opt gcc/gcc/config/rs6000/rs6000.opt
--- gcc-orig/gcc/config/rs6000/rs6000.opt	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.opt	2008-09-25 17:08:02.000000000 -0700
@@ -260,3 +260,15 @@ Specify alignment of structure fields de
 mprioritize-restricted-insns=
 Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority)
 Specify scheduling priority for dispatch slot restricted insns
+
+msingle-float
+Target RejectNegative Var(rs6000_single_float)
+Single-precision floating point unit
+
+mdouble-float
+Target RejectNegative Var(rs6000_double_float)
+Double-precision floating point unit
+
+msimple-fpu
+Target RejectNegative Var(rs6000_simple_fpu)
+Floating point unit does not support divide & sqrt
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/singlefp.h gcc/gcc/config/rs6000/singlefp.h
--- gcc-orig/gcc/config/rs6000/singlefp.h	1969-12-31 16:00:00.000000000 -0800
+++ gcc/gcc/config/rs6000/singlefp.h	2008-09-25 17:07:38.000000000 -0700
@@ -0,0 +1,40 @@
+/* Definitions for PowerPC single-precision floating point unit
+   such as Xilinx PowerPC 405/440 APU.
+
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Michael Eager (eager@eagercon.com)
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Undefine definitions from rs6000.h. */
+#undef TARGET_SINGLE_FLOAT
+#undef TARGET_DOUBLE_FLOAT
+#undef TARGET_SINGLE_FPU
+#undef TARGET_SIMPLE_FPU
+#undef UNITS_PER_FP_WORD
+
+/* FPU operations supported. 
+   If TARGET_SINGLE_FPU set, processor supports single fp options. */
+#define TARGET_SINGLE_FLOAT (rs6000_single_float)
+#define TARGET_DOUBLE_FLOAT (rs6000_double_float)
+#define TARGET_SINGLE_FPU   1
+#define TARGET_SIMPLE_FPU   (rs6000_simple_fpu)
+
+/* FP word width depends on single/double fp support. */
+#define UNITS_PER_FP_WORD ((TARGET_SOFT_FLOAT || TARGET_DOUBLE_FLOAT) ? 8 : 4)
+
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config.gcc gcc/gcc/config.gcc
--- gcc-orig/gcc/config.gcc	2008-09-25 17:05:36.000000000 -0700
+++ gcc/gcc/config.gcc	2008-09-25 17:08:02.000000000 -0700
@@ -1791,6 +1791,11 @@ powerpc-*-eabialtivec*)
 	extra_options="${extra_options} rs6000/sysv4.opt"
 	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
 	;;
+powerpc-xilinx-eabi*)
+	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/singlefp.h"
+	extra_options="${extra_options} rs6000/sysv4.opt"
+	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+	;;
 powerpc-*-eabi*)
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
 	extra_options="${extra_options} rs6000/sysv4.opt"
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/doc/invoke.texi gcc/gcc/doc/invoke.texi
--- gcc-orig/gcc/doc/invoke.texi	2008-09-25 17:05:40.000000000 -0700
+++ gcc/gcc/doc/invoke.texi	2008-09-25 17:08:03.000000000 -0700
@@ -715,6 +715,7 @@ See RS/6000 and PowerPC Options.
 -m64  -m32  -mxl-compat  -mno-xl-compat  -mpe @gol
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
+-msingle-float -mdouble-float -msimple-fpu @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
 -mfused-madd  -mno-fused-madd  -mbit-align  -mno-bit-align @gol
 -mstrict-align  -mno-strict-align  -mrelocatable @gol
@@ -13419,7 +13420,8 @@ following options:
 
 @gccoptlist{-maltivec  -mfprnd  -mhard-float  -mmfcrf  -mmultiple @gol
 -mnew-mnemonics  -mpopcntb  -mpower  -mpower2  -mpowerpc64 @gol
--mpowerpc-gpopt  -mpowerpc-gfxopt  -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
+-mpowerpc-gpopt  -mpowerpc-gfxopt  -msingle-float -mdouble-float @gol
+-msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
 
 The particular options set for any particular CPU will vary between
 compiler versions, depending on what setting seems to produce optimal
@@ -13636,6 +13638,17 @@ Generate code that does not use (uses) t
 Software floating point emulation is provided if you use the
 @option{-msoft-float} option, and pass the option to GCC when linking.
 
+@item -msingle-float
+@itemx -mdouble-float
+@opindex msingle-float
+@opindex mdouble-float
+Generate code for single or double-precision floating point operations. 
+@option{-mdouble-float} implies @option{-msingle-float}. 
+
+@item -msimple-fpu
+@opindex msimple-fpu
+Do not generate sqrt and div instructions for hardware floating point unit.
+
 @item -mmultiple
 @itemx -mno-multiple
 @opindex mmultiple

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-26 16:10   ` RESUBMIT: " Michael Eager
@ 2008-09-26 17:45     ` Janis Johnson
  2008-09-26 20:13       ` Michael Eager
  0 siblings, 1 reply; 26+ messages in thread
From: Janis Johnson @ 2008-09-26 17:45 UTC (permalink / raw)
  To: Michael Eager; +Cc: GCC Patches, David Edelsohn, Andrew Pinski

Michael Eager wrote:
> There were problems with the TARGET_SINGLE_FLOAT_MODE and
> TARGET_DOUBLE_FLOAT_MODE macros in the previous patch, and it
> turns out that they really didn't make much difference.
>
> They have been removed from this patch.

Please take a closer look at this hunk.  The earlier version of
the patch caused a warning, and in this one the indentation still
doesn't match the nesting.  I think the last '&&' should be '||',
it doesn't make much sense.

@@ -6239,9 +6294,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-         && (mode == SFmode || mode == DFmode
-             || (mode == TFmode && !TARGET_IEEEQUAD)
-             || mode == SDmode || mode == DDmode || mode == TDmode))
+         && (((TARGET_SINGLE_FLOAT && mode == SFmode)
+              || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode ==  DFmode)))
+         && ((mode == TFmode && !TARGET_IEEEQUAD)
+            || mode == SDmode || mode == DDmode || mode == TDmode)))
        {
          /* _Decimal128 must use an even/odd register pair.  This assumes
             that the register number is odd when fregno is odd.  */

Did you mean to change processing for modes TF, SD, DD, TD?  If not,
is this what you want?  (It also changes back the ordering of the
last two lines.)

  if (TARGET_HARD_FLOAT && TARGET_FPRS
      && (((TARGET_SINGLE_FLOAT && mode == SFmode)
           || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode)))
          || (mode == TFmode && !TARGET_IEEEQUAD)
          || mode == SDmode || mode == DDmode || mode == TDmode))

Janis

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-26 17:45     ` Janis Johnson
@ 2008-09-26 20:13       ` Michael Eager
  2008-09-29 17:42         ` Michael Eager
  0 siblings, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-09-26 20:13 UTC (permalink / raw)
  To: janis187; +Cc: GCC Patches, David Edelsohn, Andrew Pinski

Janis Johnson wrote:
> Michael Eager wrote:
>> There were problems with the TARGET_SINGLE_FLOAT_MODE and
>> TARGET_DOUBLE_FLOAT_MODE macros in the previous patch, and it
>> turns out that they really didn't make much difference.
>>
>> They have been removed from this patch.
> 
> Please take a closer look at this hunk.  The earlier version of
> the patch caused a warning, and in this one the indentation still
> doesn't match the nesting.  I think the last '&&' should be '||',
> it doesn't make much sense.
> 
> @@ -6239,9 +6294,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
>    else if (abi == ABI_V4)
>      {
>        if (TARGET_HARD_FLOAT && TARGET_FPRS
> -         && (mode == SFmode || mode == DFmode
> -             || (mode == TFmode && !TARGET_IEEEQUAD)
> -             || mode == SDmode || mode == DDmode || mode == TDmode))
> +         && (((TARGET_SINGLE_FLOAT && mode == SFmode)
> +              || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode ==  DFmode)))
> +         && ((mode == TFmode && !TARGET_IEEEQUAD)
> +            || mode == SDmode || mode == DDmode || mode == TDmode)))
>         {
>           /* _Decimal128 must use an even/odd register pair.  This assumes
>              that the register number is odd when fregno is odd.  */
> 
> Did you mean to change processing for modes TF, SD, DD, TD?  If not,
> is this what you want?  (It also changes back the ordering of the
> last two lines.)
> 
>   if (TARGET_HARD_FLOAT && TARGET_FPRS
>       && (((TARGET_SINGLE_FLOAT && mode == SFmode)
>            || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode)))
>           || (mode == TFmode && !TARGET_IEEEQUAD)
>           || mode == SDmode || mode == DDmode || mode == TDmode))

Yes, you are right.

The block is executed if HARD_FLOAT && FPRS with decimal float,
TF if not IEEE, or if the appropriate FP mode is supported.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-26 20:13       ` Michael Eager
@ 2008-09-29 17:42         ` Michael Eager
  2008-09-30 10:46           ` Andrew Pinski
  2008-09-30 14:12           ` David Edelsohn
  0 siblings, 2 replies; 26+ messages in thread
From: Michael Eager @ 2008-09-29 17:42 UTC (permalink / raw)
  To: janis187; +Cc: GCC Patches, David Edelsohn, Andrew Pinski

[-- Attachment #1: Type: text/plain, Size: 2116 bytes --]

Michael Eager wrote:
> Janis Johnson wrote:
>> Michael Eager wrote:
>>> There were problems with the TARGET_SINGLE_FLOAT_MODE and
>>> TARGET_DOUBLE_FLOAT_MODE macros in the previous patch, and it
>>> turns out that they really didn't make much difference.
>>>
>>> They have been removed from this patch.
>>
>> Please take a closer look at this hunk.  The earlier version of
>> the patch caused a warning, and in this one the indentation still
>> doesn't match the nesting.  I think the last '&&' should be '||',
>> it doesn't make much sense.
>>
>> @@ -6239,9 +6294,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
>>    else if (abi == ABI_V4)
>>      {
>>        if (TARGET_HARD_FLOAT && TARGET_FPRS
>> -         && (mode == SFmode || mode == DFmode
>> -             || (mode == TFmode && !TARGET_IEEEQUAD)
>> -             || mode == SDmode || mode == DDmode || mode == TDmode))
>> +         && (((TARGET_SINGLE_FLOAT && mode == SFmode)
>> +              || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode ==  
>> DFmode)))
>> +         && ((mode == TFmode && !TARGET_IEEEQUAD)
>> +            || mode == SDmode || mode == DDmode || mode == TDmode)))
>>         {
>>           /* _Decimal128 must use an even/odd register pair.  This 
>> assumes
>>              that the register number is odd when fregno is odd.  */
>>
>> Did you mean to change processing for modes TF, SD, DD, TD?  If not,
>> is this what you want?  (It also changes back the ordering of the
>> last two lines.)
>>
>>   if (TARGET_HARD_FLOAT && TARGET_FPRS
>>       && (((TARGET_SINGLE_FLOAT && mode == SFmode)
>>            || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == 
>> DFmode)))
>>           || (mode == TFmode && !TARGET_IEEEQUAD)
>>           || mode == SDmode || mode == DDmode || mode == TDmode))
> 
> Yes, you are right.
> 
> The block is executed if HARD_FLOAT && FPRS with decimal float,
> TF if not IEEE, or if the appropriate FP mode is supported.

Attached patch fixes this and another similar problem handling
decimal float mode.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: gcc.patch --]
[-- Type: text/x-patch, Size: 1757 bytes --]

diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
--- gcc-orig/gcc/config/rs6000/rs6000.c	2008-09-29 08:18:27.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.c	2008-09-29 08:32:55.000000000 -0700
@@ -5729,10 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-          && ((TARGET_SINGLE_FLOAT && mode == SFmode)
-              || (TARGET_DOUBLE_FLOAT 
-                  && (mode == DFmode || mode == DDmode || mode == TDmode))
-              || (mode == TFmode && !TARGET_IEEEQUAD)))
+          && ((TARGET_SINGLE_FLOAT && mode == SFmode) 
+               || (TARGET_DOUBLE_FLOAT && mode == DFmode))
+	      || mode == SDmode || mode == DDmode || mode == TDmode
+              || (mode == TFmode && !TARGET_IEEEQUAD))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -6294,10 +6294,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (((TARGET_SINGLE_FLOAT && mode == SFmode)
-	       || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode)))
-	  && ((mode == TFmode && !TARGET_IEEEQUAD)
-	     || mode == SDmode || mode == DDmode || mode == TDmode)))
+	  && ((TARGET_SINGLE_FLOAT && mode == SFmode) 
+               || (TARGET_DOUBLE_FLOAT && mode == DFmode))
+	      || mode == SDmode || mode == DDmode || mode == TDmode
+	      || (mode == TFmode && !TARGET_IEEEQUAD))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-29 17:42         ` Michael Eager
@ 2008-09-30 10:46           ` Andrew Pinski
  2008-09-30 13:53             ` David Edelsohn
  2008-09-30 14:12           ` David Edelsohn
  1 sibling, 1 reply; 26+ messages in thread
From: Andrew Pinski @ 2008-09-30 10:46 UTC (permalink / raw)
  To: Michael Eager; +Cc: janis187, GCC Patches, David Edelsohn

On Mon, Sep 29, 2008 at 10:05 AM, Michael Eager <eager@eagercon.com> wrote:
> Attached patch fixes this and another similar problem handling
> decimal float mode.

Looks like there was a small mistake in the patch

   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"

This is for the first fnmadds pattern.  You changed it from accepting
it with honoring signed zero to rejecting it unless not honoring
signed zeros.
This was caught by the gcc.target/powerpc/ppc-fmadd-2.c testcase.

Thanks,
Andrew Pinski

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-30 10:46           ` Andrew Pinski
@ 2008-09-30 13:53             ` David Edelsohn
  0 siblings, 0 replies; 26+ messages in thread
From: David Edelsohn @ 2008-09-30 13:53 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Michael Eager, janis187, GCC Patches

On Mon, Sep 29, 2008 at 10:05 PM, Andrew Pinski <pinskia@gmail.com> wrote:

> Looks like there was a small mistake in the patch
>
>   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
> -   && HONOR_SIGNED_ZEROS (SFmode)"
> +   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
>
> This is for the first fnmadds pattern.  You changed it from accepting
> it with honoring signed zero to rejecting it unless not honoring
> signed zeros.

I applied this patch.

Thanks, David

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-29 17:42         ` Michael Eager
  2008-09-30 10:46           ` Andrew Pinski
@ 2008-09-30 14:12           ` David Edelsohn
  2008-10-02 18:22             ` Andreas Tobler
  1 sibling, 1 reply; 26+ messages in thread
From: David Edelsohn @ 2008-09-30 14:12 UTC (permalink / raw)
  To: Michael Eager; +Cc: janis187, GCC Patches, Andrew Pinski

On Mon, Sep 29, 2008 at 1:05 PM, Michael Eager <eager@eagercon.com> wrote:


>> The block is executed if HARD_FLOAT && FPRS with decimal float,
>> TF if not IEEE, or if the appropriate FP mode is supported.
>
> Attached patch fixes this and another similar problem handling
> decimal float mode.

I do not think the revised patch is correct.  It still applies
incorrect grouping.

mode == SFmode -> (TARGET_SINGLE_FLOAT && mode == SFmode)
mode == DFmode -> (TARGET_DOUBLE_FLOAT && mode == DFmode)

Your patch applies too many parentheses and groups the later modes
with the outer conditional.  I believe the correct patch is:

Index: rs6000.c
===================================================================
--- rs6000.c    (revision 140777)
+++ rs6000.c    (working copy)
@@ -5729,9 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-          && (mode == SFmode || mode == DFmode
-             || mode == SDmode || mode == DDmode || mode == TDmode
-              || (mode == TFmode && !TARGET_IEEEQUAD)))
+         && ((TARGET_SINGLE_FLOAT && mode == SFmode)
+             || (TARGET_DOUBLE_FLOAT && mode == DFmode)
+              || (mode == TFmode && !TARGET_IEEEQUAD)
+             || mode == SDmode || mode == DDmode || mode == TDmode))
        {
          /* _Decimal128 must use an even/odd register pair.  This assumes
             that the register number is odd when fregno is odd.  */
@@ -6293,7 +6294,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-         && (mode == SFmode || mode == DFmode
+         && ((TARGET_SINGLE_FLOAT && mode == SFmode)
+             || (TARGET_DOUBLE_FLOAT && mode == DFmode)
              || (mode == TFmode && !TARGET_IEEEQUAD)
              || mode == SDmode || mode == DDmode || mode == TDmode))
        {

with a slight change in order to make the patterns symmetrical.

David

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-09-30 14:12           ` David Edelsohn
@ 2008-10-02 18:22             ` Andreas Tobler
  2008-10-02 19:00               ` David Edelsohn
  2008-10-02 19:24               ` Michael Eager
  0 siblings, 2 replies; 26+ messages in thread
From: Andreas Tobler @ 2008-10-02 18:22 UTC (permalink / raw)
  To: David Edelsohn, Michael Eager; +Cc: janis187, GCC Patches, Andrew Pinski

Hi,

I see some broken long double issues on ppc-darwin

these two hunks look to me not ok.

Both in rs6000.c (copied from cvs commit)

@@ -5200,7 +5250,9 @@
  #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)		\
    (SCALAR_FLOAT_MODE_P (MODE)			\
     && (CUM)->fregno <= FP_ARG_MAX_REG		\
-   && TARGET_HARD_FLOAT && TARGET_FPRS)
+   && TARGET_HARD_FLOAT && TARGET_FPRS 		\
+   && ((TARGET_DOUBLE_FLOAT && (MODE) == DFmode)\
+       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))


@@ -5745,7 +5797,9 @@
        cum->words = align_words + n_words;

        if (SCALAR_FLOAT_MODE_P (mode)
-	  && TARGET_HARD_FLOAT && TARGET_FPRS)
+	  && TARGET_HARD_FLOAT && TARGET_FPRS
+ 	  && ((TARGET_DOUBLE_FLOAT && mode == DFmode)
+ 	      || (TARGET_SINGLE_FLOAT && mode == SFmode)))


Reverting the locical comparison to

if (SCALAR_FLOAT_MODE_P (mode)
	  && TARGET_HARD_FLOAT && TARGET_FPRS)

Makes my libffi longdouble tests working again.

So, the question is why do you need a (TARGET_DOUBLE_FLOAT && mode == 
DFmode) instead of only TARGET_DOUBLE_FLOAT?

This restriction to DFmode blocks TFmode processing in the following lines.

Any ideas?

Thanks,
Andreas

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 18:22             ` Andreas Tobler
@ 2008-10-02 19:00               ` David Edelsohn
  2008-10-02 19:29                 ` Michael Eager
  2008-10-02 19:24               ` Michael Eager
  1 sibling, 1 reply; 26+ messages in thread
From: David Edelsohn @ 2008-10-02 19:00 UTC (permalink / raw)
  To: Andreas Tobler, Michael Eager; +Cc: janis187, GCC Patches, Andrew Pinski

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]

I committed the attached patch to fixes the problems discovered so far.

This patch adds the TARGET_SINGLE_FLOAT and TARGET_DOUBLE_FLOAT
conditionals in function_arg and function_arg_advance with the correct grouping.

It also reverts the conditionals that added tests for mode where there was
none before, breaking support for other FP modes.

        * config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Revert
        TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT.
        (function_arg_advance): Condition on TARGET_DOUBLE_FLOAT,
        TARGET_SINGLE_FLOAT.
        Revert SCALAR_FLOAT_MODE_P condition.
        (function_arg): Condition on TARGET_DOUBLE_FLOAT,
        TARGET_SINGLE_FLOAT.
        (rs6000_function_value): Revert TARGET_DOUBLE_FLOAT,
        TARGET_SINGLE_FLOAT.

David

[-- Attachment #2: xilinx-diff --]
[-- Type: application/octet-stream, Size: 3187 bytes --]

	* config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Revert
	TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT.
	(function_arg_advance): Condition on TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT.
	Revert SCALAR_FLOAT_MODE_P condition.
	(function_arg): Condition on TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT.
	(rs6000_function_value): Revert TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT.

Index: rs6000.c
===================================================================
--- rs6000.c	(revision 140836)
+++ rs6000.c	(working copy)
@@ -5249,9 +5249,7 @@ rs6000_emit_move (rtx dest, rtx source, 
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)		\
   (SCALAR_FLOAT_MODE_P (MODE)			\
    && (CUM)->fregno <= FP_ARG_MAX_REG		\
-   && TARGET_HARD_FLOAT && TARGET_FPRS 		\
-   && ((TARGET_DOUBLE_FLOAT && (MODE) == DFmode)\
-       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
+   && TARGET_HARD_FLOAT && TARGET_FPRS)
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)	\
@@ -5728,9 +5726,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-          && (mode == SFmode || mode == DFmode
-	      || mode == SDmode || mode == DDmode || mode == TDmode
-              || (mode == TFmode && !TARGET_IEEEQUAD)))
+	  && ((TARGET_SINGLE_FLOAT && mode == SFmode)
+	      || (TARGET_DOUBLE_FLOAT && mode == DFmode)
+	      || (mode == TFmode && !TARGET_IEEEQUAD)
+	      || mode == SDmode || mode == DDmode || mode == TDmode))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -5796,9 +5795,7 @@ function_arg_advance (CUMULATIVE_ARGS *c
       cum->words = align_words + n_words;
 
       if (SCALAR_FLOAT_MODE_P (mode)
-	  && TARGET_HARD_FLOAT && TARGET_FPRS
- 	  && ((TARGET_DOUBLE_FLOAT && mode == DFmode)
- 	      || (TARGET_SINGLE_FLOAT && mode == SFmode)))
+	  && TARGET_HARD_FLOAT && TARGET_FPRS)
 	{
 	  /* _Decimal128 must be passed in an even/odd float register pair.
 	     This assumes that the register number is odd when fregno is
@@ -6292,7 +6289,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
+	  && ((TARGET_SINGLE_FLOAT && mode == SFmode)
+	      || (TARGET_DOUBLE_FLOAT && mode == DFmode)
 	      || (mode == TFmode && !TARGET_IEEEQUAD)
 	      || mode == SDmode || mode == DDmode || mode == TDmode))
 	{
@@ -22522,10 +22520,7 @@ rs6000_function_value (const_tree valtyp
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
-  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_FPRS 
-           && (TARGET_HARD_FLOAT 
-	       && ((TARGET_SINGLE_FLOAT && mode == SFmode) 
-	           || TARGET_DOUBLE_FLOAT)))
+  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
 	   && targetm.calls.split_complex_arg)

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 18:22             ` Andreas Tobler
  2008-10-02 19:00               ` David Edelsohn
@ 2008-10-02 19:24               ` Michael Eager
  2008-10-02 19:55                 ` Andreas Tobler
  2008-10-02 20:29                 ` Janis Johnson
  1 sibling, 2 replies; 26+ messages in thread
From: Michael Eager @ 2008-10-02 19:24 UTC (permalink / raw)
  To: Andreas Tobler; +Cc: David Edelsohn, janis187, GCC Patches, Andrew Pinski

Andreas Tobler wrote:
> Hi,
> 
> I see some broken long double issues on ppc-darwin
> 
> these two hunks look to me not ok.
> 
> Both in rs6000.c (copied from cvs commit)
> 
> @@ -5200,7 +5250,9 @@
>  #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)        \
>    (SCALAR_FLOAT_MODE_P (MODE)            \
>     && (CUM)->fregno <= FP_ARG_MAX_REG        \
> -   && TARGET_HARD_FLOAT && TARGET_FPRS)
> +   && TARGET_HARD_FLOAT && TARGET_FPRS         \
> +   && ((TARGET_DOUBLE_FLOAT && (MODE) == DFmode)\
> +       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
> 
> 
> @@ -5745,7 +5797,9 @@
>        cum->words = align_words + n_words;
> 
>        if (SCALAR_FLOAT_MODE_P (mode)
> -      && TARGET_HARD_FLOAT && TARGET_FPRS)
> +      && TARGET_HARD_FLOAT && TARGET_FPRS
> +       && ((TARGET_DOUBLE_FLOAT && mode == DFmode)
> +           || (TARGET_SINGLE_FLOAT && mode == SFmode)))
> 
> 
> Reverting the locical comparison to
> 
> if (SCALAR_FLOAT_MODE_P (mode)
>       && TARGET_HARD_FLOAT && TARGET_FPRS)
> 
> Makes my libffi longdouble tests working again.
> 
> So, the question is why do you need a (TARGET_DOUBLE_FLOAT && mode == 
> DFmode) instead of only TARGET_DOUBLE_FLOAT?
> 
> This restriction to DFmode blocks TFmode processing in the following lines.
> 
> Any ideas?

Just having TARGET_DOUBLE_FLOAT, instead of (TARGET_DOUBLE_FLOAT &&
mode == DFmode) should be the same as previous behavior.

Other tests have explicit checks for TFmode, which are missing.
This would probably be better:


@@ -5200,7 +5250,9 @@
#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)        \
    (SCALAR_FLOAT_MODE_P (MODE)            \
     && (CUM)->fregno <= FP_ARG_MAX_REG        \
-   && TARGET_HARD_FLOAT && TARGET_FPRS)
+   && TARGET_HARD_FLOAT && TARGET_FPRS         \
+   && ((TARGET_DOUBLE_FLOAT && ((MODE) == DFmode || (MODE) == (TFmode))\
+       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))


@@ -5745,7 +5797,9 @@
        cum->words = align_words + n_words;

        if (SCALAR_FLOAT_MODE_P (mode)
-      && TARGET_HARD_FLOAT && TARGET_FPRS)
+      && TARGET_HARD_FLOAT && TARGET_FPRS
+       && ((TARGET_DOUBLE_FLOAT && (mode == DFmode || mode == TFmode))
+           || (TARGET_SINGLE_FLOAT && mode == SFmode)))




-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 19:00               ` David Edelsohn
@ 2008-10-02 19:29                 ` Michael Eager
  2008-10-02 19:49                   ` David Edelsohn
  0 siblings, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-10-02 19:29 UTC (permalink / raw)
  To: David Edelsohn; +Cc: Andreas Tobler, janis187, GCC Patches, Andrew Pinski

David Edelsohn wrote:
> I committed the attached patch to fixes the problems discovered so far.
> 
> This patch adds the TARGET_SINGLE_FLOAT and TARGET_DOUBLE_FLOAT
> conditionals in function_arg and function_arg_advance with the correct grouping.
> 
> It also reverts the conditionals that added tests for mode where there was
> none before, breaking support for other FP modes.
> 
>         * config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Revert
>         TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT.
>         (function_arg_advance): Condition on TARGET_DOUBLE_FLOAT,
>         TARGET_SINGLE_FLOAT.
>         Revert SCALAR_FLOAT_MODE_P condition.
>         (function_arg): Condition on TARGET_DOUBLE_FLOAT,
>         TARGET_SINGLE_FLOAT.
>         (rs6000_function_value): Revert TARGET_DOUBLE_FLOAT,
>         TARGET_SINGLE_FLOAT.

I'm not sure that removing the test for TARGET_SINGLE_FLOAT
in USE_FP_FOR_ARG_P is correct.  On a target with a single-precision
FPU, only SFmode values can be passed in FP regs.  This change says
that DFmode values are can be passed in FP regs, even if
TARGET_DOUBLE_FLOAT is false.

Removing the test in rs6000_function_value() means that
FP_ARG_RETURN will be used to return all FP values.   That's
not correct on a single-precision FPU for DFmode values.

I'll admit to being confused about TFmode.  This seems to
sneak in with DFmode.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 19:29                 ` Michael Eager
@ 2008-10-02 19:49                   ` David Edelsohn
  0 siblings, 0 replies; 26+ messages in thread
From: David Edelsohn @ 2008-10-02 19:49 UTC (permalink / raw)
  To: Michael Eager; +Cc: Andreas Tobler, janis187, GCC Patches, Andrew Pinski

On Thu, Oct 2, 2008 at 3:23 PM, Michael Eager <eager@eagercon.com> wrote:

> I'm not sure that removing the test for TARGET_SINGLE_FLOAT
> in USE_FP_FOR_ARG_P is correct.  On a target with a single-precision
> FPU, only SFmode values can be passed in FP regs.  This change says
> that DFmode values are can be passed in FP regs, even if
> TARGET_DOUBLE_FLOAT is false.
>
> Removing the test in rs6000_function_value() means that
> FP_ARG_RETURN will be used to return all FP values.   That's
> not correct on a single-precision FPU for DFmode values.
>
> I'll admit to being confused about TFmode.  This seems to
> sneak in with DFmode.

I did not mean to imply that my patch was the final, correct implementation
for the Xilinx functionality.  I meant this returns GCC to correct behavior
for existing architectures and ABIs.

David

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 19:24               ` Michael Eager
@ 2008-10-02 19:55                 ` Andreas Tobler
  2008-10-02 20:00                   ` Michael Eager
  2008-10-04 20:41                   ` Andreas Tobler
  2008-10-02 20:29                 ` Janis Johnson
  1 sibling, 2 replies; 26+ messages in thread
From: Andreas Tobler @ 2008-10-02 19:55 UTC (permalink / raw)
  To: Michael Eager; +Cc: David Edelsohn, janis187, GCC Patches, Andrew Pinski

Hi Michael,

Michael Eager wrote:

> Just having TARGET_DOUBLE_FLOAT, instead of (TARGET_DOUBLE_FLOAT &&
> mode == DFmode) should be the same as previous behavior.
> 
> Other tests have explicit checks for TFmode, which are missing.
> This would probably be better:
> 
> 
> @@ -5200,7 +5250,9 @@
> #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)        \
>    (SCALAR_FLOAT_MODE_P (MODE)            \
>     && (CUM)->fregno <= FP_ARG_MAX_REG        \
> -   && TARGET_HARD_FLOAT && TARGET_FPRS)
> +   && TARGET_HARD_FLOAT && TARGET_FPRS         \
> +   && ((TARGET_DOUBLE_FLOAT && ((MODE) == DFmode || (MODE) == (TFmode))\
> +       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
> 
> 
> @@ -5745,7 +5797,9 @@
>        cum->words = align_words + n_words;
> 
>        if (SCALAR_FLOAT_MODE_P (mode)
> -      && TARGET_HARD_FLOAT && TARGET_FPRS)
> +      && TARGET_HARD_FLOAT && TARGET_FPRS
> +       && ((TARGET_DOUBLE_FLOAT && (mode == DFmode || mode == TFmode))
> +           || (TARGET_SINGLE_FLOAT && mode == SFmode)))


Let me complete a build with current svn, including tests. After that 
I'll apply the two hunks above and rerun. I'll do this on ppc-darwin 
32-bit. We then get an idea if it breaks here or not.

After that, we can see what is needed to get TARGET_SINGLE_FLOAT to work 
correctly w/o breaking existing ABI's and FP rules, ok?

Regards,
Andreas

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 19:55                 ` Andreas Tobler
@ 2008-10-02 20:00                   ` Michael Eager
  2008-10-02 20:14                     ` Andreas Tobler
  2008-10-04 20:41                   ` Andreas Tobler
  1 sibling, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-10-02 20:00 UTC (permalink / raw)
  To: Andreas Tobler; +Cc: David Edelsohn, janis187, GCC Patches, Andrew Pinski

Andreas Tobler wrote:
> Hi Michael,
> 
> Michael Eager wrote:
> 
>> Just having TARGET_DOUBLE_FLOAT, instead of (TARGET_DOUBLE_FLOAT &&
>> mode == DFmode) should be the same as previous behavior.
>>
>> Other tests have explicit checks for TFmode, which are missing.
>> This would probably be better:
>>
>>
>> @@ -5200,7 +5250,9 @@
>> #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)        \
>>    (SCALAR_FLOAT_MODE_P (MODE)            \
>>     && (CUM)->fregno <= FP_ARG_MAX_REG        \
>> -   && TARGET_HARD_FLOAT && TARGET_FPRS)
>> +   && TARGET_HARD_FLOAT && TARGET_FPRS         \
>> +   && ((TARGET_DOUBLE_FLOAT && ((MODE) == DFmode || (MODE) == (TFmode))\
>> +       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
>>
>>
>> @@ -5745,7 +5797,9 @@
>>        cum->words = align_words + n_words;
>>
>>        if (SCALAR_FLOAT_MODE_P (mode)
>> -      && TARGET_HARD_FLOAT && TARGET_FPRS)
>> +      && TARGET_HARD_FLOAT && TARGET_FPRS
>> +       && ((TARGET_DOUBLE_FLOAT && (mode == DFmode || mode == TFmode))
>> +           || (TARGET_SINGLE_FLOAT && mode == SFmode)))
> 
> 
> Let me complete a build with current svn, including tests. After that 
> I'll apply the two hunks above and rerun. I'll do this on ppc-darwin 
> 32-bit. We then get an idea if it breaks here or not.
> 
> After that, we can see what is needed to get TARGET_SINGLE_FLOAT to work 
> correctly w/o breaking existing ABI's and FP rules, ok?

Sounds good.  Unfortunately, I don't have a PPC w/ standard FPU as
a test system, so I can't run regression tests.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 20:00                   ` Michael Eager
@ 2008-10-02 20:14                     ` Andreas Tobler
  0 siblings, 0 replies; 26+ messages in thread
From: Andreas Tobler @ 2008-10-02 20:14 UTC (permalink / raw)
  To: Michael Eager; +Cc: David Edelsohn, janis187, GCC Patches, Andrew Pinski

Michael Eager wrote:

> Sounds good.  Unfortunately, I don't have a PPC w/ standard FPU as
> a test system, so I can't run regression tests.

But I/we have, on the other side we do not have what you have ;)

So we have to work together.

Your intent is to have your system running and working correctly and our 
intent is to not break current behavior.

I think we will meet in the middle :)

Andreas


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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 19:24               ` Michael Eager
  2008-10-02 19:55                 ` Andreas Tobler
@ 2008-10-02 20:29                 ` Janis Johnson
  2008-10-02 21:25                   ` Michael Eager
  1 sibling, 1 reply; 26+ messages in thread
From: Janis Johnson @ 2008-10-02 20:29 UTC (permalink / raw)
  To: Michael Eager; +Cc: Andreas Tobler, David Edelsohn, GCC Patches, Andrew Pinski

On Thu, 2008-10-02 at 11:59 -0700, Michael Eager wrote:

> Other tests have explicit checks for TFmode, which are missing.
> This would probably be better:

Decimal float modes SDmode, DDmode, and TDmode also use
floating point registers.

Janis

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 20:29                 ` Janis Johnson
@ 2008-10-02 21:25                   ` Michael Eager
  2008-10-02 21:47                     ` Joseph S. Myers
  0 siblings, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-10-02 21:25 UTC (permalink / raw)
  To: janis187; +Cc: Andreas Tobler, David Edelsohn, GCC Patches, Andrew Pinski

Janis Johnson wrote:
> On Thu, 2008-10-02 at 11:59 -0700, Michael Eager wrote:
> 
>> Other tests have explicit checks for TFmode, which are missing.
>> This would probably be better:
> 
> Decimal float modes SDmode, DDmode, and TDmode also use
> floating point registers.

Perhaps we need a macro which tests for 32-bit modes (SFmode
and SDmode), 64-bit modes (DFmode and DDmode), and a third
for 128-bit modes (TFmode and TDmode).

Support for decimal float with a single-precision FPU
also needs some modification so that it's always handled
as SOFT_FLOAT.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 21:25                   ` Michael Eager
@ 2008-10-02 21:47                     ` Joseph S. Myers
  0 siblings, 0 replies; 26+ messages in thread
From: Joseph S. Myers @ 2008-10-02 21:47 UTC (permalink / raw)
  To: Michael Eager
  Cc: janis187, Andreas Tobler, David Edelsohn, GCC Patches, Andrew Pinski

On Thu, 2 Oct 2008, Michael Eager wrote:

> Janis Johnson wrote:
> > On Thu, 2008-10-02 at 11:59 -0700, Michael Eager wrote:
> > 
> > > Other tests have explicit checks for TFmode, which are missing.
> > > This would probably be better:
> > 
> > Decimal float modes SDmode, DDmode, and TDmode also use
> > floating point registers.
> 
> Perhaps we need a macro which tests for 32-bit modes (SFmode
> and SDmode), 64-bit modes (DFmode and DDmode), and a third
> for 128-bit modes (TFmode and TDmode).

Then you have TFmode in the TARGET_IEEEQUAD case, passed by reference - 
but I believe that case is long bit-rotten, with lots of TFmode references 
that don't try to check for TARGET_IEEEQUAD, and could safely be removed.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-02 19:55                 ` Andreas Tobler
  2008-10-02 20:00                   ` Michael Eager
@ 2008-10-04 20:41                   ` Andreas Tobler
  2008-10-06 22:57                     ` David Edelsohn
  1 sibling, 1 reply; 26+ messages in thread
From: Andreas Tobler @ 2008-10-04 20:41 UTC (permalink / raw)
  To: Michael Eager; +Cc: David Edelsohn, janis187, GCC Patches, Andrew Pinski

Andreas Tobler wrote:
> Hi Michael,
> 
> Michael Eager wrote:
> 
>> Just having TARGET_DOUBLE_FLOAT, instead of (TARGET_DOUBLE_FLOAT &&
>> mode == DFmode) should be the same as previous behavior.
>>
>> Other tests have explicit checks for TFmode, which are missing.
>> This would probably be better:
>>
>>
>> @@ -5200,7 +5250,9 @@
>> #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)        \
>>    (SCALAR_FLOAT_MODE_P (MODE)            \
>>     && (CUM)->fregno <= FP_ARG_MAX_REG        \
>> -   && TARGET_HARD_FLOAT && TARGET_FPRS)
>> +   && TARGET_HARD_FLOAT && TARGET_FPRS         \
>> +   && ((TARGET_DOUBLE_FLOAT && ((MODE) == DFmode || (MODE) == (TFmode))\
>> +       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
>>
>>
>> @@ -5745,7 +5797,9 @@
>>        cum->words = align_words + n_words;
>>
>>        if (SCALAR_FLOAT_MODE_P (mode)
>> -      && TARGET_HARD_FLOAT && TARGET_FPRS)
>> +      && TARGET_HARD_FLOAT && TARGET_FPRS
>> +       && ((TARGET_DOUBLE_FLOAT && (mode == DFmode || mode == TFmode))
>> +           || (TARGET_SINGLE_FLOAT && mode == SFmode)))
> 
> 
> Let me complete a build with current svn, including tests. After that 
> I'll apply the two hunks above and rerun. I'll do this on ppc-darwin 
> 32-bit. We then get an idea if it breaks here or not.

I completed the test run and there were no differences between the two 
versions; current svn vs. current svn plus the two hunks above.

Now we need to introduce the additions from Janis: SDmode, DDmode, 
TDmode. I suppose on my side there are not many issues....


Andreas

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

* Re: RESUBMIT: PowerPC -- support single-precision FPU
  2008-10-04 20:41                   ` Andreas Tobler
@ 2008-10-06 22:57                     ` David Edelsohn
  0 siblings, 0 replies; 26+ messages in thread
From: David Edelsohn @ 2008-10-06 22:57 UTC (permalink / raw)
  To: Andreas Tobler, Michael Eager; +Cc: janis187, GCC Patches, Andrew Pinski

On Sat, Oct 4, 2008 at 4:11 PM, Andreas Tobler <andreast-list@fgznet.ch> wrote:

> I completed the test run and there were no differences between the two
> versions; current svn vs. current svn plus the two hunks above.
>
> Now we need to introduce the additions from Janis: SDmode, DDmode, TDmode. I
> suppose on my side there are not many issues....

What is the next step for the series of patches?

David

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

* Re: PowerPC -- support single-precision FPU
  2008-09-20  6:21 ` Andrew Pinski
@ 2008-09-21 19:21   ` Michael Eager
  0 siblings, 0 replies; 26+ messages in thread
From: Michael Eager @ 2008-09-21 19:21 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1231 bytes --]

Andrew Pinski wrote:
> On Fri, Sep 19, 2008 at 10:42 AM, Michael Eager <eager@eagercon.com> wrote:
>> The attached patch adds generic support for single-precision
>> FPU on PowerPC.  A follow-on patch will use this patch to add
>> support for the single-precision FPU on the Xilinx PPC 405/440.
> 
> I noticed that "TARGET_SINGLE_FLOAT && (MODE) == SFmode" and
> "TARGET_DOUBLE_FLOAT && (MODE) == DFmode" are used in more than once
> place, could there be a macro that is defined to those?
> Likewise for "((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode)"

Can do.

Added TARGET_SINGLE_FLOAT_MODE and TARGET_DOUBLE_FLOAT_MODE.

> Should floatsisf2_internal have the same constraints as floatdidf2?

Yes.

The condition for floatsisf2_internal should also be changed to
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT"
so that it is only matched for -fsingle-float and not for -fdouble-float
or classic PowerPC FPU.

> 
> These three small issues are only the issues I have with the patch.
> Everything else looks good (though I cannot approve it).

Thanks.

Updated patch/changelog attached.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: changelog --]
[-- Type: text/plain, Size: 3465 bytes --]

2008-09-18  Michael J. Eager  <eager@eagercon.com>

	* config/rs6000/predicates.md (easy_fp_constant): single FP consts are easy
	* config/rs6000/rs6000.c (rs6000_override_options): move 
	rs6000_init_hard_regno_mode_ok after all options changed.
	Set rs6000_single_float, rs6000_double_float if TARGET_HARD_FLOAT.
	(rs6000_handle_option): Process -msingle-float (rs6000_single_float), 
	-mdouble-float (rs6000_double_float), -msimple-fpu flags (rs6000_simple_fpu)
	Add warning messages if single FP not configured.
	(rs6000_file_start): Output gnu_attribute for single-float
	(legitimate_lo_sum_address_p): condition on TARGET_DOUBLE_FLOAT
	(rs6000_legitimize_address): likewise
	(rs6000_legitimize_reload_address): likewise
	(rs6000_emit_move): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(function_arg_advance): likewise
	(function_arg): likewise
	(setup_incoming_varargs): condition on TARGET_DOUBLE_FLOAT
	(rs6000_gimplify_va_arg): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_split_multireg_move): condition on TARGET_DOUBLE_FLOAT
	(rs6000_emit_prologue): likewise
	(rs6000_function_value): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_libcall_value): likewise
	* config/rs6000/rs6000.h (TARGET_SINGLE_FLOAT): New default to 1
	(TARGET_DOUBLE_FLOAT): New default to 1
	(TARGET_SIMPLE_FPU): New default to 0
	(TARGET_SINGLE_FPU): New default to 0
	(TARGET_SINGLE_FLOAT_MODE): New.
	(TARGET_DOUBLE_FLOAT_MODE): New.
	* config/rs6000/singlefp.h: New; redefine TARGET_SINGLE_FLOAT,
	TARGET_DOUBLE_FLOAT, TARGET_SIMPLE_FPU, TARGET_SINGLE_FPU,
	UNITS_PER_FP_WORD
	* config/rs6000/rs6000.md (define_mode_iterator): condition on TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT
	(extendsfdf2,extendsfdf2_fpr,truncdfsf2,truncdfsf2_fpr, copysigndf3,fseldfsf4,
	negdf2, negdf2_fpr, absdf2, absdf2_fpr, nabsdf2_fpr, adddf3, adddf3_fpr, subdf3,
	subdf3_fpr, muldf3, muldf3_fpr, divdf3, divdf3_fpr, sqrtdf2, smaxdf3, smindf3,
	movdfcc, *fseldfdf4, floatsidf2, *floatsidf2_internal, floatunssidf2, 
	*floatunssidf2_internal, fix_truncdfsi2, *fix_truncdfsi2_internal, 
	fix_truncdfsi2_internal_gfxopt, fix_truncdfsi2_mfpgpr, fctiwz, btruncdf2,
	ceildf2, floordf2, rounddf2, floatdidf2, floatsidf_ppc64_mfpgpr, floatsidf_ppc64,
	floatunssidf_ppc64, fix_truncdfdi2, movdf_hardfloat32, movdf_hardfloat64_mfpgpr,
	movdf_hardfloat64, extenddftf2_fprs, extenddftf2_internal, trunctfdf2_internal2,
	fix_trunc_helper, abstf2_internal, movdf_update1, movdf_update2, cmpdf_internal1,
	cmptf_internal1, *cmptf_internal2): condition on TARGET_DOUBLE_FLOAT
	(aux_truncdfsf2, negsf2, *negsf2, abssf2, *abssf2, addsf3, subsf3, mulsf3,
	divsf3, sqrtsf2, copysignsf3, smaxsf3, sminsf3, movsfcc, *fselsfsf4, 
	fixuns_truncsfsi2, fix_truncsfsi2, floatunssisf2, btruncsf2, ceilsf2, 
	floorsf2, roundsf2, floatsisf2_internal, floatdisf2_internal1, floatdisf2_internal2,
	*movsf_hardfloat, trunctfsf2_fprs, *movsf_update1, *movsf_update2, 
	*cmpsf_internal1): Condition on TARGET_SINGLE_FLOAT.
	(divsf3, sqrtsf2, divdf3, divdf3_fpr): Condition on TARGET_SIMPLE_FPU.
	(floatsisf2_internal): New. 
	* config/rs6000/rs6000.opt (-msingle-floati): New
	(-mdouble-float): New
	(-msimple-fpu): New
	* gcc/doc/invoke.texi (RS/6000 and PowerPC Options): Add 
	-msingle-float, -mdouble-float, -msimple-fpu options
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): set _SOFT_DOUBLE 
	for -msingle-float
	* config.gcc: New config for target=powerpc-xilinx-eabi
	


[-- Attachment #3: gcc.patch --]
[-- Type: text/x-patch, Size: 64310 bytes --]

diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/predicates.md gcc/gcc/config/rs6000/predicates.md
--- gcc-orig/gcc/config/rs6000/predicates.md	2008-09-19 19:01:44.000000000 -0700
+++ gcc/gcc/config/rs6000/predicates.md	2008-09-19 19:04:22.000000000 -0700
@@ -192,7 +192,8 @@
     return 0;
 
   /* Consider all constants with -msoft-float to be easy.  */
-  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE 
+      || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT)))
       && mode != DImode)
     return 1;
 
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
--- gcc-orig/gcc/config/rs6000/rs6000.c	2008-09-19 19:01:44.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.c	2008-09-20 10:22:26.000000000 -0700
@@ -1556,8 +1556,6 @@ rs6000_override_options (const char *def
 		     | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
   };
 
-  rs6000_init_hard_regno_mode_ok ();
-
   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
 #ifdef OS_MISSING_POWERPC64
   if (OS_MISSING_POWERPC64)
@@ -1968,6 +1966,25 @@ rs6000_override_options (const char *def
      can be optimized to ap = __builtin_next_arg (0).  */
   if (DEFAULT_ABI != ABI_V4)
     targetm.expand_builtin_va_start = NULL;
+
+  /* Set up single/double float flags.  
+     If TARGET_HARD_FLOAT is set, but neither single or double is set, 
+     then set both flags. */
+  if (TARGET_HARD_FLOAT && TARGET_FPRS 
+      && rs6000_single_float == 0 && rs6000_double_float == 0)
+    rs6000_single_float = rs6000_double_float = 1;
+
+  /* Reset single and double FP flags if target is E500. */
+  if (TARGET_E500) 
+  {
+    rs6000_single_float = rs6000_double_float = 0;
+    if (TARGET_E500_SINGLE)
+      rs6000_single_float = 1; 
+    if (TARGET_E500_DOUBLE)
+      rs6000_single_float = rs6000_double_float = 1;
+  }
+
+  rs6000_init_hard_regno_mode_ok ();
 }
 
 /* Implement targetm.vectorize.builtin_mask_for_load.  */
@@ -2477,6 +2494,37 @@ rs6000_handle_option (size_t code, const
 	  return false;
 	}
       break;
+
+    case OPT_msingle_float:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msingle-float option equivalent to -mhard-float");
+      /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
+      rs6000_double_float = 0;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_mdouble_float:
+      /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
+      rs6000_single_float = 1;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_msimple_fpu:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msimple-fpu option ignored");
+      break;
+
+    case OPT_mhard_float:
+      /* -mhard_float implies -msingle-float and -mdouble-float. */
+      rs6000_single_float = rs6000_double_float = 1;
+      break;
+
+    case OPT_msoft_float:
+      /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
+      rs6000_single_float = rs6000_double_float = 0;
+      break;
     }
   return true;
 }
@@ -2546,7 +2594,9 @@ rs6000_file_start (void)
   if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
     {
       fprintf (file, "\t.gnu_attribute 4, %d\n",
-	       (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+	       ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 
+	        : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 
+	        : 2));
       fprintf (file, "\t.gnu_attribute 8, %d\n",
 	       (TARGET_ALTIVEC_ABI ? 2
 		: TARGET_SPE_ABI ? 3
@@ -3691,7 +3741,7 @@ legitimate_lo_sum_address_p (enum machin
 	return false;
       if (GET_MODE_BITSIZE (mode) > 64
 	  || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
-	      && !(TARGET_HARD_FLOAT && TARGET_FPRS
+	      && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
 		   && (mode == DFmode || mode == DDmode))))
 	return false;
 
@@ -3758,7 +3808,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (XEXP (x, 0)) == REG
 	   && GET_CODE (XEXP (x, 1)) != CONST_INT
 	   && GET_MODE_NUNITS (mode) == 1
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || TARGET_POWERPC64
 	       || ((mode != DImode && mode != DFmode && mode != DDmode)
 		   || (TARGET_E500_DOUBLE && mode != DDmode)))
@@ -3827,7 +3877,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && CONSTANT_P (x)
 	   && GET_MODE_NUNITS (mode) == 1
 	   && (GET_MODE_BITSIZE (mode) <= 32
-	       || ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	       || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 		   && (mode == DFmode || mode == DDmode))))
     {
       rtx reg = gen_reg_rtx (Pmode);
@@ -3842,7 +3892,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (x) != CONST_INT
 	   && GET_CODE (x) != CONST_DOUBLE
 	   && CONSTANT_P (x)
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || (mode != DFmode && mode != DDmode))
 	   && mode != DImode
 	   && mode != TImode)
@@ -4259,7 +4309,7 @@ rs6000_legitimize_reload_address (rtx x,
       && mode != TDmode
       && (mode != DImode || TARGET_POWERPC64)
       && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
-	  || (TARGET_FPRS && TARGET_HARD_FLOAT)))
+	  || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
     {
 #if TARGET_MACHO
       if (flag_pic)
@@ -4384,7 +4434,7 @@ rs6000_legitimate_address (enum machine_
       && mode != TImode
       && mode != TFmode
       && mode != TDmode
-      && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+      && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	  || TARGET_POWERPC64
 	  || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
       && (TARGET_POWERPC64 || mode != DImode)
@@ -4839,7 +4889,7 @@ rs6000_emit_move (rtx dest, rtx source, 
     operands[1] = force_reg (mode, operands[1]);
 
   if (mode == SFmode && ! TARGET_POWERPC
-      && TARGET_HARD_FLOAT && TARGET_FPRS
+      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
       && GET_CODE (operands[0]) == MEM)
     {
       int regnum;
@@ -5200,7 +5250,9 @@ rs6000_emit_move (rtx dest, rtx source, 
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)		\
   (SCALAR_FLOAT_MODE_P (MODE)			\
    && (CUM)->fregno <= FP_ARG_MAX_REG		\
-   && TARGET_HARD_FLOAT && TARGET_FPRS)
+   && TARGET_HARD_FLOAT && TARGET_FPRS 		\
+   && (TARGET_DOUBLE_FLOAT_MODE (MODE)		\
+       || TARGET_SINGLE_FLOAT_MODE (MODE)))
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)	\
@@ -5677,9 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || mode == SDmode || mode == DDmode || mode == TDmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)))
+          && (TARGET_SINGLE_FLOAT_MODE (mode)
+              || (TARGET_DOUBLE_FLOAT 
+                  && (mode == DFmode || mode == DDmode || mode == TDmode))
+              || (mode == TFmode && !TARGET_IEEEQUAD)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -5745,7 +5798,8 @@ function_arg_advance (CUMULATIVE_ARGS *c
       cum->words = align_words + n_words;
 
       if (SCALAR_FLOAT_MODE_P (mode)
-	  && TARGET_HARD_FLOAT && TARGET_FPRS)
+	  && TARGET_HARD_FLOAT && TARGET_FPRS
+ 	  && (TARGET_DOUBLE_FLOAT_MODE (mode) || TARGET_SINGLE_FLOAT_MODE (mode)))
 	{
 	  /* _Decimal128 must be passed in an even/odd float register pair.
 	     This assumes that the register number is odd when fregno is
@@ -6239,9 +6293,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)
-	      || mode == SDmode || mode == DDmode || mode == TDmode))
+	  && (TARGET_SINGLE_FLOAT_MODE(mode)
+	       || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode))
+	  && ((mode == TFmode && !TARGET_IEEEQUAD)
+	     || mode == SDmode || mode == DDmode || mode == TDmode)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -6701,11 +6756,17 @@ setup_incoming_varargs (CUMULATIVE_ARGS 
 	   fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
 	   fregno++, off += UNITS_PER_FP_WORD, nregs++)
 	{
-	  mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
-	  MEM_NOTRAP_P (mem) = 1;
-	  set_mem_alias_set (mem, set);
-	  set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
-	  emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
+	  mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			      ? DFmode : SFmode, 
+                             plus_constant (save_area, off));
+  	  MEM_NOTRAP_P (mem) = 1;
+  	  set_mem_alias_set (mem, set);
+	  set_mem_align (mem, GET_MODE_ALIGNMENT (
+			 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			  ? DFmode : SFmode));
+	  emit_move_insn (mem, gen_rtx_REG (
+                          (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			   ? DFmode : SFmode, fregno));
 	}
 
       emit_label (lab);
@@ -6920,18 +6981,19 @@ 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) == TFmode
-	  || TYPE_MODE (type) == SDmode
-	  || TYPE_MODE (type) == DDmode
-	  || TYPE_MODE (type) == TDmode))
+      && (TARGET_SINGLE_FLOAT_MODE (TYPE_MODE (type))
+          || (TARGET_DOUBLE_FLOAT 
+              && (TYPE_MODE (type) == DFmode 
+ 	          || TYPE_MODE (type) == TFmode
+	          || TYPE_MODE (type) == SDmode
+	          || TYPE_MODE (type) == DDmode
+	          || TYPE_MODE (type) == TDmode))))
     {
       /* FP args go in FP registers, if present.  */
       reg = fpr;
       n_reg = (size + 7) / 8;
-      sav_ofs = 8*4;
-      sav_scale = 8;
+      sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
+      sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
       if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
 	align = 8;
     }
@@ -14127,7 +14189,8 @@ rs6000_split_multireg_move (rtx dst, rtx
   mode = GET_MODE (dst);
   nregs = hard_regno_nregs[reg][mode];
   if (FP_REGNO_P (reg))
-    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 
+	((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
   else if (ALTIVEC_REGNO_P (reg))
     reg_mode = V16QImode;
   else if (TARGET_E500_DOUBLE && mode == TFmode)
@@ -16079,11 +16142,14 @@ rs6000_emit_prologue (void)
 	 properly.  */
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + sp_offset + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
 	}
@@ -16190,7 +16256,9 @@ rs6000_emit_prologue (void)
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
 	     && ! call_used_regs[info->first_fp_reg_save+i]))
-	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
+	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, 
+			   (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			    ? DFmode : SFmode,
 			   info->first_fp_reg_save + i,
 			   info->fp_save_offset + sp_offset + 8 * i,
 			   info->total_size);
@@ -16835,11 +16903,14 @@ rs6000_emit_epilogue (int sibcall)
 	}
       for (i = 0; info->first_fp_reg_save + i <= 63; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+ 			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
 	}
@@ -17244,9 +17315,12 @@ rs6000_emit_epilogue (int sibcall)
 			       GEN_INT (info->fp_save_offset
 					+ sp_offset
 					+ 8 * i));
-	  mem = gen_frame_mem (DFmode, addr);
+	  mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				 ? DFmode : SFmode), addr);
 
-	  emit_move_insn (gen_rtx_REG (DFmode,
+ 	  emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT 
+					 && TARGET_DOUBLE_FLOAT)
+				        ? DFmode : SFmode),
 				       info->first_fp_reg_save + i),
 			  mem);
 	}
@@ -22386,7 +22460,10 @@ rs6000_function_value (const_tree valtyp
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
-  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_FPRS 
+           && (TARGET_HARD_FLOAT 
+	       && (TARGET_SINGLE_FLOAT_MODE (mode) 
+	            || TARGET_DOUBLE_FLOAT)))
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
 	   && targetm.calls.split_complex_arg)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000-c.c gcc/gcc/config/rs6000/rs6000-c.c
--- gcc-orig/gcc/config/rs6000/rs6000-c.c	2008-09-19 19:01:44.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000-c.c	2008-09-19 19:04:22.000000000 -0700
@@ -297,7 +297,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     builtin_define ("__PAIRED__");
   if (TARGET_SOFT_FLOAT)
     builtin_define ("_SOFT_FLOAT");
-  if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+  if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+      ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT))
     builtin_define ("_SOFT_DOUBLE");
   /* Used by lwarx/stwcx. errata work-around.  */
   if (rs6000_cpu == PROCESSOR_PPC405)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.h gcc/gcc/config/rs6000/rs6000.h
--- gcc-orig/gcc/config/rs6000/rs6000.h	2008-09-19 19:01:44.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.h	2008-09-20 10:22:29.000000000 -0700
@@ -298,6 +298,17 @@ enum processor_type
    PROCESSOR_CELL
 };
 
+/* FPU operations supported. 
+   Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must 
+   also test TARGET_HARD_FLOAT.  */
+#define TARGET_SINGLE_FLOAT 1
+#define TARGET_DOUBLE_FLOAT 1
+#define TARGET_SINGLE_FPU   0
+#define TARGET_SIMPLE_FPU   0
+
+#define TARGET_SINGLE_FLOAT_MODE(MODE) (TARGET_SINGLE_FLOAT && (MODE) == SFmode)
+#define TARGET_DOUBLE_FLOAT_MODE(MODE) (TARGET_DOUBLE_FLOAT && (MODE) == DFmode)
+
 extern enum processor_type rs6000_cpu;
 
 /* Recast the processor type to the cpu attribute.  */
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.md gcc/gcc/config/rs6000/rs6000.md
--- gcc-orig/gcc/config/rs6000/rs6000.md	2008-09-19 19:01:44.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.md	2008-09-20 10:22:32.000000000 -0700
@@ -202,8 +202,11 @@
 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
 
 ; Any hardware-supported floating-point mode
-(define_mode_iterator FP [(SF "TARGET_HARD_FLOAT")
-  (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
+(define_mode_iterator FP [
+  (SF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
+  (DF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
   (TF "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
@@ -5059,13 +5062,13 @@
 (define_expand "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn_and_split "*extendsfdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "@
    #
    fmr %0,%1
@@ -5081,53 +5084,53 @@
 (define_expand "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*truncdfsf2_fpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "aux_truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5135,14 +5138,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fadds %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5150,7 +5153,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5158,14 +5161,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		  (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsubs %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5173,7 +5176,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5181,14 +5184,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fmuls %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5196,7 +5199,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5204,14 +5207,15 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		(match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fdivs %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
@@ -5219,7 +5223,8 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5247,7 +5252,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5256,7 +5262,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5265,7 +5272,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5274,7 +5282,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5284,7 +5293,7 @@
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5293,7 +5302,7 @@
 	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
    && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
@@ -5303,7 +5312,8 @@
 	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5313,7 +5323,7 @@
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5323,7 +5333,7 @@
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5333,7 +5343,7 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5342,7 +5352,8 @@
 	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5352,27 +5363,31 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
 (define_expand "sqrtsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) 
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT 
+   && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrts %0,%1"
   [(set_attr "type" "ssqrt")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5405,7 +5420,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
    && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
   {
      operands[3] = gen_reg_rtx (SFmode);
@@ -5423,7 +5438,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
    && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
   {
      operands[3] = gen_reg_rtx (DFmode);
@@ -5441,7 +5456,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "sminsf3"
@@ -5450,7 +5466,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5458,7 +5475,8 @@
 	(match_operator:SF 3 "min_max_operator"
 	 [(match_operand:SF 1 "gpc_reg_operand" "")
 	  (match_operand:SF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5519,7 +5537,7 @@
 	 (if_then_else:SF (match_operand 1 "comparison_operator" "")
 			  (match_operand:SF 2 "gpc_reg_operand" "")
 			  (match_operand:SF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5534,7 +5552,7 @@
 			     (match_operand:SF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5544,40 +5562,40 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
 (define_expand "negdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*negdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "absdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*absdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "*nabsdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5585,14 +5603,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*adddf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5600,14 +5618,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		  (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*subdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		  (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5615,14 +5633,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*muldf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5630,14 +5648,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		(match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn "*divdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		(match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5665,7 +5683,7 @@
 	(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			  (match_operand:DF 2 "gpc_reg_operand" "f"))
 		 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5674,7 +5692,7 @@
 	(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5683,7 +5701,7 @@
 	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				  (match_operand:DF 2 "gpc_reg_operand" "f"))
 			 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5693,7 +5711,7 @@
 	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5703,7 +5721,7 @@
 	(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				   (match_operand:DF 2 "gpc_reg_operand" "f"))
 			  (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5713,7 +5731,7 @@
 	(minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
 	          (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5721,7 +5739,8 @@
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5734,7 +5753,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "smindf3"
@@ -5743,7 +5763,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5751,7 +5772,8 @@
 	(match_operator:DF 3 "min_max_operator"
 	 [(match_operand:DF 1 "gpc_reg_operand" "")
 	  (match_operand:DF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5764,7 +5786,7 @@
 	 (if_then_else:DF (match_operand 1 "comparison_operator" "")
 			  (match_operand:DF 2 "gpc_reg_operand" "")
 			  (match_operand:DF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5779,7 +5801,7 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:DF 2 "gpc_reg_operand" "f")
 			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5798,13 +5820,13 @@
 (define_expand "fixuns_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "fix_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 ; For each of these conversions, there is a define_expand, a define_insn
@@ -5820,7 +5842,8 @@
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))
 	      (clobber (match_dup 6))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5850,7 +5873,7 @@
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5879,7 +5902,7 @@
 (define_expand "floatunssisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "floatunssidf2"
@@ -5889,7 +5912,7 @@
 	      (use (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5917,7 +5940,7 @@
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5947,7 +5970,7 @@
 	      (clobber (match_dup 2))
 	      (clobber (match_dup 3))])]
   "(TARGET_POWER2 || TARGET_POWERPC)
-   && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+   && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5983,7 +6006,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
   [(pc)]
@@ -6004,7 +6028,8 @@
   [(set (match_operand:SI 0 "memory_operand" "=Z")
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && TARGET_PPC_GFXOPT"
   "#"
   "&& 1"
@@ -6022,7 +6047,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& 1"
   [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ))
@@ -6039,63 +6065,64 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
 	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
 		   UNSPEC_FCTIWZ))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceildf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceilsf2"
  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floordf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floorsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "rounddf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "roundsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
@@ -6114,24 +6141,31 @@
   "TARGET_HARD_FLOAT && !TARGET_FPRS"
   "")
 
+(define_insn "floatsisf2_internal"
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+        (float:SF (match_operand:SI 1 "gpc_reg_operand" "!f#r")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT"
+  "fcfid %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncdfdi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r")
 	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "floatdisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "
 {
   rtx val = operands[1];
@@ -6153,7 +6187,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))
    (clobber (match_scratch:DF 2 "=f"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -6187,7 +6221,7 @@
 			   (label_ref (match_operand:DI 2 "" ""))
 			   (pc)))
    (set (match_dup 0) (match_dup 1))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   operands[3] = gen_reg_rtx (DImode);
@@ -8219,7 +8253,7 @@
 	(match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))]
   "(gpc_reg_operand (operands[0], SFmode)
    || gpc_reg_operand (operands[1], SFmode))
-   && (TARGET_HARD_FLOAT && TARGET_FPRS)"
+   && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
   "@
    mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
@@ -8357,7 +8391,7 @@
 (define_insn "*movdf_hardfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8452,7 +8486,9 @@
 (define_insn "*movdf_softfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
 	(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
-  "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  "! TARGET_POWERPC64 
+   && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) 
+       || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8495,7 +8531,8 @@
 (define_insn "*movdf_hardfloat64_mfpgpr"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8521,7 +8558,8 @@
 (define_insn "*movdf_hardfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
-  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8614,7 +8652,8 @@
 		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
 	      (use (match_dup 2))])]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
 {
   operands[2] = CONST0_RTX (DFmode);
   /* Generate GOT reference early for SVR4 PIC.  */
@@ -8627,7 +8666,8 @@
        (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(pc)]
@@ -8684,7 +8724,8 @@
   [(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")])
 
@@ -8708,7 +8749,8 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -8738,7 +8780,7 @@
 	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
 		   UNSPEC_FIX_TRUNC_TF))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
   [(set_attr "type" "fp")
    (set_attr "length" "20")])
@@ -8859,7 +8901,8 @@
 			   (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "
 {
   const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
@@ -10010,7 +10053,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    lfsux %3,%0,%2
    lfsu %3,%2(%0)"
@@ -10022,7 +10065,7 @@
 	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    stfsux %3,%0,%2
    stfsu %3,%2(%0)"
@@ -10058,7 +10101,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    lfdux %3,%0,%2
    lfdu %3,%2(%0)"
@@ -10070,7 +10113,7 @@
 	(match_operand:DF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    stfdux %3,%0,%2
    stfdu %3,%2(%0)"
@@ -10091,7 +10134,7 @@
    (set (match_operand:DF 2 "gpc_reg_operand" "")
 	(match_operand:DF 3 "memory_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[0], operands[2])
    && mems_ok_for_quad_peep (operands[1], operands[3])"
   [(set (match_dup 0)
@@ -10113,7 +10156,7 @@
    (set (match_operand:DF 2 "memory_operand" "")
 	(match_operand:DF 3 "gpc_reg_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[1], operands[3])
    && mems_ok_for_quad_peep (operands[0], operands[2])"
   [(set (match_dup 0)
@@ -11899,7 +11942,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
 		      (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11907,7 +11950,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
 		      (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11917,7 +11960,7 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
    (set_attr "length" "12")])
@@ -11935,7 +11978,7 @@
     (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 13))
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.opt gcc/gcc/config/rs6000/rs6000.opt
--- gcc-orig/gcc/config/rs6000/rs6000.opt	2008-09-19 19:01:44.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.opt	2008-09-19 19:04:22.000000000 -0700
@@ -260,3 +260,15 @@ Specify alignment of structure fields de
 mprioritize-restricted-insns=
 Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority)
 Specify scheduling priority for dispatch slot restricted insns
+
+msingle-float
+Target RejectNegative Var(rs6000_single_float)
+Single-precision floating point unit
+
+mdouble-float
+Target RejectNegative Var(rs6000_double_float)
+Double-precision floating point unit
+
+msimple-fpu
+Target RejectNegative Var(rs6000_simple_fpu)
+Floating point unit does not support divide & sqrt
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/singlefp.h gcc/gcc/config/rs6000/singlefp.h
--- gcc-orig/gcc/config/rs6000/singlefp.h	1969-12-31 16:00:00.000000000 -0800
+++ gcc/gcc/config/rs6000/singlefp.h	2008-09-19 19:04:22.000000000 -0700
@@ -0,0 +1,40 @@
+/* Definitions for PowerPC single-precision floating point unit
+   such as Xilinx PowerPC 405/440 APU.
+
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Michael Eager (eager@eagercon.com)
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Undefine definitions from rs6000.h. */
+#undef TARGET_SINGLE_FLOAT
+#undef TARGET_DOUBLE_FLOAT
+#undef TARGET_SINGLE_FPU
+#undef TARGET_SIMPLE_FPU
+#undef UNITS_PER_FP_WORD
+
+/* FPU operations supported. 
+   If TARGET_SINGLE_FPU set, processor supports single fp options. */
+#define TARGET_SINGLE_FLOAT (rs6000_single_float)
+#define TARGET_DOUBLE_FLOAT (rs6000_double_float)
+#define TARGET_SINGLE_FPU   1
+#define TARGET_SIMPLE_FPU   (rs6000_simple_fpu)
+
+/* FP word width depends on single/double fp support. */
+#define UNITS_PER_FP_WORD ((TARGET_SOFT_FLOAT || TARGET_DOUBLE_FLOAT) ? 8 : 4)
+
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config.gcc gcc/gcc/config.gcc
--- gcc-orig/gcc/config.gcc	2008-09-19 19:01:45.000000000 -0700
+++ gcc/gcc/config.gcc	2008-09-19 19:04:22.000000000 -0700
@@ -1791,6 +1791,11 @@ powerpc-*-eabialtivec*)
 	extra_options="${extra_options} rs6000/sysv4.opt"
 	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
 	;;
+powerpc-xilinx-eabi*)
+	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/singlefp.h"
+	extra_options="${extra_options} rs6000/sysv4.opt"
+	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+	;;
 powerpc-*-eabi*)
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
 	extra_options="${extra_options} rs6000/sysv4.opt"
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/doc/invoke.texi gcc/gcc/doc/invoke.texi
--- gcc-orig/gcc/doc/invoke.texi	2008-09-19 19:01:41.000000000 -0700
+++ gcc/gcc/doc/invoke.texi	2008-09-19 19:04:22.000000000 -0700
@@ -715,6 +715,7 @@ See RS/6000 and PowerPC Options.
 -m64  -m32  -mxl-compat  -mno-xl-compat  -mpe @gol
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
+-msingle-float -mdouble-float -msimple-fpu @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
 -mfused-madd  -mno-fused-madd  -mbit-align  -mno-bit-align @gol
 -mstrict-align  -mno-strict-align  -mrelocatable @gol
@@ -13419,7 +13420,8 @@ following options:
 
 @gccoptlist{-maltivec  -mfprnd  -mhard-float  -mmfcrf  -mmultiple @gol
 -mnew-mnemonics  -mpopcntb  -mpower  -mpower2  -mpowerpc64 @gol
--mpowerpc-gpopt  -mpowerpc-gfxopt  -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
+-mpowerpc-gpopt  -mpowerpc-gfxopt  -msingle-float -mdouble-float @gol
+-msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
 
 The particular options set for any particular CPU will vary between
 compiler versions, depending on what setting seems to produce optimal
@@ -13636,6 +13638,17 @@ Generate code that does not use (uses) t
 Software floating point emulation is provided if you use the
 @option{-msoft-float} option, and pass the option to GCC when linking.
 
+@item -msingle-float
+@itemx -mdouble-float
+@opindex msingle-float
+@opindex mdouble-float
+Generate code for single or double-precision floating point operations. 
+@option{-mdouble-float} implies @option{-msingle-float}. 
+
+@item -msimple-fpu
+@opindex msimple-fpu
+Do not generate sqrt and div instructions for hardware floating point unit.
+
 @item -mmultiple
 @itemx -mno-multiple
 @opindex mmultiple

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

* Re: PowerPC -- support single-precision FPU
  2008-09-19 18:37 Michael Eager
@ 2008-09-20  6:21 ` Andrew Pinski
  2008-09-21 19:21   ` Michael Eager
  0 siblings, 1 reply; 26+ messages in thread
From: Andrew Pinski @ 2008-09-20  6:21 UTC (permalink / raw)
  To: Michael Eager; +Cc: gcc-patches

On Fri, Sep 19, 2008 at 10:42 AM, Michael Eager <eager@eagercon.com> wrote:
> The attached patch adds generic support for single-precision
> FPU on PowerPC.  A follow-on patch will use this patch to add
> support for the single-precision FPU on the Xilinx PPC 405/440.

I noticed that "TARGET_SINGLE_FLOAT && (MODE) == SFmode" and
"TARGET_DOUBLE_FLOAT && (MODE) == DFmode" are used in more than once
place, could there be a macro that is defined to those?
Likewise for "((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode)"

Should floatsisf2_internal have the same constraints as floatdidf2?

These three small issues are only the issues I have with the patch.
Everything else looks good (though I cannot approve it).

Thanks,
Andrew Pinski

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

* PowerPC -- support single-precision FPU
@ 2008-09-19 18:37 Michael Eager
  2008-09-20  6:21 ` Andrew Pinski
  0 siblings, 1 reply; 26+ messages in thread
From: Michael Eager @ 2008-09-19 18:37 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 357 bytes --]

The attached patch adds generic support for single-precision
FPU on PowerPC.  A follow-on patch will use this patch to add
support for the single-precision FPU on the Xilinx PPC 405/440.

The default is to build a "classic" PowerPC with double-precision
FPU support.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: changelog --]
[-- Type: text/plain, Size: 3397 bytes --]

2008-09-18  Michael J. Eager  <eager@eagercon.com>

	* config/rs6000/predicates.md (easy_fp_constant): single FP consts are easy
	* config/rs6000/rs6000.c (rs6000_override_options): move 
	rs6000_init_hard_regno_mode_ok after all options changed.
	Set rs6000_single_float, rs6000_double_float if TARGET_HARD_FLOAT.
	(rs6000_handle_option): Process -msingle-float (rs6000_single_float), 
	-mdouble-float (rs6000_double_float), -msimple-fpu flags (rs6000_simple_fpu)
	Add warning messages if single FP not configured.
	(rs6000_file_start): Output gnu_attribute for single-float
	(legitimate_lo_sum_address_p): condition on TARGET_DOUBLE_FLOAT
	(rs6000_legitimize_address): likewise
	(rs6000_legitimize_reload_address): likewise
	(rs6000_emit_move): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(function_arg_advance): likewise
	(function_arg): likewise
	(setup_incoming_varargs): condition on TARGET_DOUBLE_FLOAT
	(rs6000_gimplify_va_arg): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_split_multireg_move): condition on TARGET_DOUBLE_FLOAT
	(rs6000_emit_prologue): likewise
	(rs6000_function_value): condition on TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT
	(rs6000_libcall_value): likewise
	* config/rs6000/rs6000.h (TARGET_SINGLE_FLOAT): New default to 1
	(TARGET_DOUBLE_FLOAT): New default to 1
	(TARGET_SIMPLE_FPU): New default to 0
	(TARGET_SINGLE_FPU): New default to 0
	* config/rs6000/singlefp.h: New; redefine TARGET_SINGLE_FLOAT,
	TARGET_DOUBLE_FLOAT, TARGET_SIMPLE_FPU, TARGET_SINGLE_FPU,
	UNITS_PER_FP_WORD
	* config/rs6000/rs6000.md (define_mode_iterator): condition on TARGET_DOUBLE_FLOAT,
	TARGET_SINGLE_FLOAT
	(extendsfdf2,extendsfdf2_fpr,truncdfsf2,truncdfsf2_fpr, copysigndf3,fseldfsf4,
	negdf2, negdf2_fpr, absdf2, absdf2_fpr, nabsdf2_fpr, adddf3, adddf3_fpr, subdf3,
	subdf3_fpr, muldf3, muldf3_fpr, divdf3, divdf3_fpr, sqrtdf2, smaxdf3, smindf3,
	movdfcc, *fseldfdf4, floatsidf2, *floatsidf2_internal, floatunssidf2, 
	*floatunssidf2_internal, fix_truncdfsi2, *fix_truncdfsi2_internal, 
	fix_truncdfsi2_internal_gfxopt, fix_truncdfsi2_mfpgpr, fctiwz, btruncdf2,
	ceildf2, floordf2, rounddf2, floatdidf2, floatsidf_ppc64_mfpgpr, floatsidf_ppc64,
	floatunssidf_ppc64, fix_truncdfdi2, movdf_hardfloat32, movdf_hardfloat64_mfpgpr,
	movdf_hardfloat64, extenddftf2_fprs, extenddftf2_internal, trunctfdf2_internal2,
	fix_trunc_helper, abstf2_internal, movdf_update1, movdf_update2, cmpdf_internal1,
	cmptf_internal1, *cmptf_internal2): condition on TARGET_DOUBLE_FLOAT
	(aux_truncdfsf2, negsf2, *negsf2, abssf2, *abssf2, addsf3, subsf3, mulsf3,
	divsf3, sqrtsf2, copysignsf3, smaxsf3, sminsf3, movsfcc, *fselsfsf4, 
	fixuns_truncsfsi2, fix_truncsfsi2, floatunssisf2, btruncsf2, ceilsf2, 
	floorsf2, roundsf2, floatsisf2_internal, floatdisf2_internal1, floatdisf2_internal2,
	*movsf_hardfloat, trunctfsf2_fprs, *movsf_update1, *movsf_update2, 
	*cmpsf_internal1): Condition on TARGET_SINGLE_FLOAT.
	(divsf3, sqrtsf2, divdf3, divdf3_fpr): Condition on TARGET_SIMPLE_FPU.
	(floatsisf2_internal): New. 
	* config/rs6000/rs6000.opt (-msingle-floati): New
	(-mdouble-float): New
	(-msimple-fpu): New
	* gcc/doc/invoke.texi (RS/6000 and PowerPC Options): Add 
	-msingle-float, -mdouble-float, -msimple-fpu options
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): set _SOFT_DOUBLE 
	for -msingle-float
	* config.gcc: New config for target=powerpc-xilinx-eabi
	


[-- Attachment #3: gcc.patch --]
[-- Type: text/x-patch, Size: 64179 bytes --]

diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/predicates.md gcc/gcc/config/rs6000/predicates.md
--- gcc-orig/gcc/config/rs6000/predicates.md	2008-09-18 13:33:09.000000000 -0700
+++ gcc/gcc/config/rs6000/predicates.md	2008-09-18 13:36:39.000000000 -0700
@@ -192,7 +192,8 @@
     return 0;
 
   /* Consider all constants with -msoft-float to be easy.  */
-  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE 
+      || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT)))
       && mode != DImode)
     return 1;
 
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
--- gcc-orig/gcc/config/rs6000/rs6000.c	2008-09-18 13:33:09.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.c	2008-09-18 13:36:39.000000000 -0700
@@ -1556,8 +1556,6 @@ rs6000_override_options (const char *def
 		     | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
   };
 
-  rs6000_init_hard_regno_mode_ok ();
-
   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
 #ifdef OS_MISSING_POWERPC64
   if (OS_MISSING_POWERPC64)
@@ -1968,6 +1966,25 @@ rs6000_override_options (const char *def
      can be optimized to ap = __builtin_next_arg (0).  */
   if (DEFAULT_ABI != ABI_V4)
     targetm.expand_builtin_va_start = NULL;
+
+  /* Set up single/double float flags.  
+     If TARGET_HARD_FLOAT is set, but neither single or double is set, 
+     then set both flags. */
+  if (TARGET_HARD_FLOAT && TARGET_FPRS 
+      && rs6000_single_float == 0 && rs6000_double_float == 0)
+    rs6000_single_float = rs6000_double_float = 1;
+
+  /* Reset single and double FP flags if target is E500. */
+  if (TARGET_E500) 
+  {
+    rs6000_single_float = rs6000_double_float = 0;
+    if (TARGET_E500_SINGLE)
+      rs6000_single_float = 1; 
+    if (TARGET_E500_DOUBLE)
+      rs6000_single_float = rs6000_double_float = 1;
+  }
+
+  rs6000_init_hard_regno_mode_ok ();
 }
 
 /* Implement targetm.vectorize.builtin_mask_for_load.  */
@@ -2477,6 +2494,37 @@ rs6000_handle_option (size_t code, const
 	  return false;
 	}
       break;
+
+    case OPT_msingle_float:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msingle-float option equivalent to -mhard-float");
+      /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
+      rs6000_double_float = 0;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_mdouble_float:
+      /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
+      rs6000_single_float = 1;
+      target_flags &= ~MASK_SOFT_FLOAT;
+      target_flags_explicit |= MASK_SOFT_FLOAT;
+      break;
+
+    case OPT_msimple_fpu:
+      if (!TARGET_SINGLE_FPU) 
+	warning (0, "-msimple-fpu option ignored");
+      break;
+
+    case OPT_mhard_float:
+      /* -mhard_float implies -msingle-float and -mdouble-float. */
+      rs6000_single_float = rs6000_double_float = 1;
+      break;
+
+    case OPT_msoft_float:
+      /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
+      rs6000_single_float = rs6000_double_float = 0;
+      break;
     }
   return true;
 }
@@ -2546,7 +2594,9 @@ rs6000_file_start (void)
   if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
     {
       fprintf (file, "\t.gnu_attribute 4, %d\n",
-	       (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+	       ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 
+	        : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 
+	        : 2));
       fprintf (file, "\t.gnu_attribute 8, %d\n",
 	       (TARGET_ALTIVEC_ABI ? 2
 		: TARGET_SPE_ABI ? 3
@@ -3691,7 +3741,7 @@ legitimate_lo_sum_address_p (enum machin
 	return false;
       if (GET_MODE_BITSIZE (mode) > 64
 	  || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
-	      && !(TARGET_HARD_FLOAT && TARGET_FPRS
+	      && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
 		   && (mode == DFmode || mode == DDmode))))
 	return false;
 
@@ -3758,7 +3808,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (XEXP (x, 0)) == REG
 	   && GET_CODE (XEXP (x, 1)) != CONST_INT
 	   && GET_MODE_NUNITS (mode) == 1
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || TARGET_POWERPC64
 	       || ((mode != DImode && mode != DFmode && mode != DDmode)
 		   || (TARGET_E500_DOUBLE && mode != DDmode)))
@@ -3827,7 +3877,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && CONSTANT_P (x)
 	   && GET_MODE_NUNITS (mode) == 1
 	   && (GET_MODE_BITSIZE (mode) <= 32
-	       || ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	       || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 		   && (mode == DFmode || mode == DDmode))))
     {
       rtx reg = gen_reg_rtx (Pmode);
@@ -3842,7 +3892,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (x) != CONST_INT
 	   && GET_CODE (x) != CONST_DOUBLE
 	   && CONSTANT_P (x)
-	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+	   && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	       || (mode != DFmode && mode != DDmode))
 	   && mode != DImode
 	   && mode != TImode)
@@ -4259,7 +4309,7 @@ rs6000_legitimize_reload_address (rtx x,
       && mode != TDmode
       && (mode != DImode || TARGET_POWERPC64)
       && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
-	  || (TARGET_FPRS && TARGET_HARD_FLOAT)))
+	  || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
     {
 #if TARGET_MACHO
       if (flag_pic)
@@ -4384,7 +4434,7 @@ rs6000_legitimate_address (enum machine_
       && mode != TImode
       && mode != TFmode
       && mode != TDmode
-      && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+      && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
 	  || TARGET_POWERPC64
 	  || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
       && (TARGET_POWERPC64 || mode != DImode)
@@ -4839,7 +4889,7 @@ rs6000_emit_move (rtx dest, rtx source, 
     operands[1] = force_reg (mode, operands[1]);
 
   if (mode == SFmode && ! TARGET_POWERPC
-      && TARGET_HARD_FLOAT && TARGET_FPRS
+      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
       && GET_CODE (operands[0]) == MEM)
     {
       int regnum;
@@ -5200,7 +5250,9 @@ rs6000_emit_move (rtx dest, rtx source, 
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)		\
   (SCALAR_FLOAT_MODE_P (MODE)			\
    && (CUM)->fregno <= FP_ARG_MAX_REG		\
-   && TARGET_HARD_FLOAT && TARGET_FPRS)
+   && TARGET_HARD_FLOAT && TARGET_FPRS 		\
+   && ((TARGET_DOUBLE_FLOAT && (MODE) == DFmode)\
+       || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)	\
@@ -5677,9 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else if (DEFAULT_ABI == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || mode == SDmode || mode == DDmode || mode == TDmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)))
+          && ((TARGET_SINGLE_FLOAT && mode == SFmode)
+              || (TARGET_DOUBLE_FLOAT 
+                  && (mode == DFmode || mode == DDmode || mode == TDmode))
+              || (mode == TFmode && !TARGET_IEEEQUAD)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -5745,7 +5798,9 @@ function_arg_advance (CUMULATIVE_ARGS *c
       cum->words = align_words + n_words;
 
       if (SCALAR_FLOAT_MODE_P (mode)
-	  && TARGET_HARD_FLOAT && TARGET_FPRS)
+	  && TARGET_HARD_FLOAT && TARGET_FPRS
+ 	  && ((TARGET_DOUBLE_FLOAT && mode == DFmode)
+ 	      || (TARGET_SINGLE_FLOAT && mode == SFmode)))
 	{
 	  /* _Decimal128 must be passed in an even/odd float register pair.
 	     This assumes that the register number is odd when fregno is
@@ -6239,9 +6294,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
-	  && (mode == SFmode || mode == DFmode
-	      || (mode == TFmode && !TARGET_IEEEQUAD)
-	      || mode == SDmode || mode == DDmode || mode == TDmode))
+	  && (((TARGET_SINGLE_FLOAT && mode == SFmode)
+	       || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode)))
+	  && ((mode == TFmode && !TARGET_IEEEQUAD)
+	     || mode == SDmode || mode == DDmode || mode == TDmode)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
 	     that the register number is odd when fregno is odd.  */
@@ -6701,11 +6757,17 @@ setup_incoming_varargs (CUMULATIVE_ARGS 
 	   fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
 	   fregno++, off += UNITS_PER_FP_WORD, nregs++)
 	{
-	  mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
-	  MEM_NOTRAP_P (mem) = 1;
-	  set_mem_alias_set (mem, set);
-	  set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
-	  emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
+	  mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			      ? DFmode : SFmode, 
+                             plus_constant (save_area, off));
+  	  MEM_NOTRAP_P (mem) = 1;
+  	  set_mem_alias_set (mem, set);
+	  set_mem_align (mem, GET_MODE_ALIGNMENT (
+			 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			  ? DFmode : SFmode));
+	  emit_move_insn (mem, gen_rtx_REG (
+                          (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			   ? DFmode : SFmode, fregno));
 	}
 
       emit_label (lab);
@@ -6920,18 +6982,19 @@ 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) == TFmode
-	  || TYPE_MODE (type) == SDmode
-	  || TYPE_MODE (type) == DDmode
-	  || TYPE_MODE (type) == TDmode))
+      && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
+          || (TARGET_DOUBLE_FLOAT 
+              && (TYPE_MODE (type) == DFmode 
+ 	          || TYPE_MODE (type) == TFmode
+	          || TYPE_MODE (type) == SDmode
+	          || TYPE_MODE (type) == DDmode
+	          || TYPE_MODE (type) == TDmode))))
     {
       /* FP args go in FP registers, if present.  */
       reg = fpr;
       n_reg = (size + 7) / 8;
-      sav_ofs = 8*4;
-      sav_scale = 8;
+      sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
+      sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
       if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
 	align = 8;
     }
@@ -14127,7 +14190,8 @@ rs6000_split_multireg_move (rtx dst, rtx
   mode = GET_MODE (dst);
   nregs = hard_regno_nregs[reg][mode];
   if (FP_REGNO_P (reg))
-    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 
+	((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
   else if (ALTIVEC_REGNO_P (reg))
     reg_mode = V16QImode;
   else if (TARGET_E500_DOUBLE && mode == TFmode)
@@ -16079,11 +16143,14 @@ rs6000_emit_prologue (void)
 	 properly.  */
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + sp_offset + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
 	}
@@ -16190,7 +16257,9 @@ rs6000_emit_prologue (void)
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
 	if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
 	     && ! call_used_regs[info->first_fp_reg_save+i]))
-	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
+	  emit_frame_save (frame_reg_rtx, frame_ptr_rtx, 
+			   (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+			    ? DFmode : SFmode,
 			   info->first_fp_reg_save + i,
 			   info->fp_save_offset + sp_offset + 8 * i,
 			   info->total_size);
@@ -16835,11 +16904,14 @@ rs6000_emit_epilogue (int sibcall)
 	}
       for (i = 0; info->first_fp_reg_save + i <= 63; i++)
 	{
-	  rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+ 	  rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				   ? DFmode : SFmode), 
+ 			         info->first_fp_reg_save + i);
 	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
 				   GEN_INT (info->fp_save_offset
 					    + 8 * i));
-	  rtx mem = gen_frame_mem (DFmode, addr);
+ 	  rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				     ? DFmode : SFmode), addr);
 
 	  RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
 	}
@@ -17244,9 +17316,12 @@ rs6000_emit_epilogue (int sibcall)
 			       GEN_INT (info->fp_save_offset
 					+ sp_offset
 					+ 8 * i));
-	  mem = gen_frame_mem (DFmode, addr);
+	  mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+				 ? DFmode : SFmode), addr);
 
-	  emit_move_insn (gen_rtx_REG (DFmode,
+ 	  emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT 
+					 && TARGET_DOUBLE_FLOAT)
+				        ? DFmode : SFmode),
 				       info->first_fp_reg_save + i),
 			  mem);
 	}
@@ -22386,7 +22461,10 @@ rs6000_function_value (const_tree valtyp
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
-  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_FPRS 
+           && (TARGET_HARD_FLOAT 
+	       && ((TARGET_SINGLE_FLOAT && mode == SFmode) 
+	            || TARGET_DOUBLE_FLOAT)))
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
 	   && targetm.calls.split_complex_arg)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000-c.c gcc/gcc/config/rs6000/rs6000-c.c
--- gcc-orig/gcc/config/rs6000/rs6000-c.c	2008-09-18 13:33:09.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000-c.c	2008-09-18 13:36:39.000000000 -0700
@@ -297,7 +297,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     builtin_define ("__PAIRED__");
   if (TARGET_SOFT_FLOAT)
     builtin_define ("_SOFT_FLOAT");
-  if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+  if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+      ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT))
     builtin_define ("_SOFT_DOUBLE");
   /* Used by lwarx/stwcx. errata work-around.  */
   if (rs6000_cpu == PROCESSOR_PPC405)
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.h gcc/gcc/config/rs6000/rs6000.h
--- gcc-orig/gcc/config/rs6000/rs6000.h	2008-09-18 13:33:09.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.h	2008-09-18 13:36:39.000000000 -0700
@@ -298,6 +298,14 @@ enum processor_type
    PROCESSOR_CELL
 };
 
+/* FPU operations supported. 
+   Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must 
+   also test TARGET_HARD_FLOAT.  */
+#define TARGET_SINGLE_FLOAT 1
+#define TARGET_DOUBLE_FLOAT 1
+#define TARGET_SINGLE_FPU   0
+#define TARGET_SIMPLE_FPU   0
+
 extern enum processor_type rs6000_cpu;
 
 /* Recast the processor type to the cpu attribute.  */
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.md gcc/gcc/config/rs6000/rs6000.md
--- gcc-orig/gcc/config/rs6000/rs6000.md	2008-09-18 13:33:09.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.md	2008-09-18 13:36:39.000000000 -0700
@@ -202,8 +202,11 @@
 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
 
 ; Any hardware-supported floating-point mode
-(define_mode_iterator FP [(SF "TARGET_HARD_FLOAT")
-  (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
+(define_mode_iterator FP [
+  (SF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
+  (DF "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
   (TF "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
@@ -5059,13 +5062,13 @@
 (define_expand "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn_and_split "*extendsfdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "@
    #
    fmr %0,%1
@@ -5081,53 +5084,53 @@
 (define_expand "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*truncdfsf2_fpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "aux_truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn "*abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5135,14 +5138,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fadds %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5150,7 +5153,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5158,14 +5161,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		  (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsubs %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5173,7 +5176,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5181,14 +5184,14 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fmuls %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5196,7 +5199,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5204,14 +5207,15 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
 		(match_operand:SF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fdivs %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
@@ -5219,7 +5223,8 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
 		(match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5247,7 +5252,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5256,7 +5262,8 @@
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
 		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5265,7 +5272,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "fmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5274,7 +5282,8 @@
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5284,7 +5293,7 @@
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5293,7 +5302,7 @@
 	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
    && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
@@ -5303,7 +5312,8 @@
 	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5313,7 +5323,7 @@
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5323,7 +5333,7 @@
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5333,7 +5343,7 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5342,7 +5352,8 @@
 	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5352,27 +5363,31 @@
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
   "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && ! HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
 (define_expand "sqrtsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) 
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT 
+   && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrts %0,%1"
   [(set_attr "type" "ssqrt")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5405,7 +5420,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
    && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
   {
      operands[3] = gen_reg_rtx (SFmode);
@@ -5423,7 +5438,7 @@
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
    && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
   {
      operands[3] = gen_reg_rtx (DFmode);
@@ -5441,7 +5456,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "sminsf3"
@@ -5450,7 +5466,8 @@
 			     (match_operand:SF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5458,7 +5475,8 @@
 	(match_operator:SF 3 "min_max_operator"
 	 [(match_operand:SF 1 "gpc_reg_operand" "")
 	  (match_operand:SF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5519,7 +5537,7 @@
 	 (if_then_else:SF (match_operand 1 "comparison_operator" "")
 			  (match_operand:SF 2 "gpc_reg_operand" "")
 			  (match_operand:SF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5534,7 +5552,7 @@
 			     (match_operand:SF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5544,40 +5562,40 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
 (define_expand "negdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*negdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "absdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*absdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "*nabsdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5585,14 +5603,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*adddf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5600,14 +5618,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		  (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*subdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		  (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
@@ -5615,14 +5633,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		 (match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn "*muldf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
@@ -5630,14 +5648,14 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
 		(match_operand:DF 2 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) && !TARGET_SIMPLE_FPU"
   "")
 
 (define_insn "*divdf3_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
 		(match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5665,7 +5683,7 @@
 	(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			  (match_operand:DF 2 "gpc_reg_operand" "f"))
 		 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5674,7 +5692,7 @@
 	(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
@@ -5683,7 +5701,7 @@
 	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				  (match_operand:DF 2 "gpc_reg_operand" "f"))
 			 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5693,7 +5711,7 @@
 	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))
 		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5703,7 +5721,7 @@
 	(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 				   (match_operand:DF 2 "gpc_reg_operand" "f"))
 			  (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5713,7 +5731,7 @@
 	(minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
 	          (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
 			   (match_operand:DF 2 "gpc_reg_operand" "f"))))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
    && ! HONOR_SIGNED_ZEROS (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
@@ -5721,7 +5739,8 @@
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5734,7 +5753,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 1)
 			 (match_dup 2)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
 
 (define_expand "smindf3"
@@ -5743,7 +5763,8 @@
 			     (match_operand:DF 2 "gpc_reg_operand" ""))
 			 (match_dup 2)
 			 (match_dup 1)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
 
 (define_split
@@ -5751,7 +5772,8 @@
 	(match_operator:DF 3 "min_max_operator"
 	 [(match_operand:DF 1 "gpc_reg_operand" "")
 	  (match_operand:DF 2 "gpc_reg_operand" "")]))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && !flag_trapping_math"
   [(const_int 0)]
   "
 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
@@ -5764,7 +5786,7 @@
 	 (if_then_else:DF (match_operand 1 "comparison_operator" "")
 			  (match_operand:DF 2 "gpc_reg_operand" "")
 			  (match_operand:DF 3 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5779,7 +5801,7 @@
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:DF 2 "gpc_reg_operand" "f")
 			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5798,13 +5820,13 @@
 (define_expand "fixuns_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "fix_truncsfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 ; For each of these conversions, there is a define_expand, a define_insn
@@ -5820,7 +5842,8 @@
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))
 	      (clobber (match_dup 6))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT 
+   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5850,7 +5873,7 @@
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5879,7 +5902,7 @@
 (define_expand "floatunssisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "")
 
 (define_expand "floatunssidf2"
@@ -5889,7 +5912,7 @@
 	      (use (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))])]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5917,7 +5940,7 @@
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
@@ -5947,7 +5970,7 @@
 	      (clobber (match_dup 2))
 	      (clobber (match_dup 3))])]
   "(TARGET_POWER2 || TARGET_POWERPC)
-   && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+   && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
@@ -5983,7 +6006,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
   [(pc)]
@@ -6004,7 +6028,8 @@
   [(set (match_operand:SI 0 "memory_operand" "=Z")
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && TARGET_PPC_GFXOPT"
   "#"
   "&& 1"
@@ -6022,7 +6047,8 @@
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "#"
   "&& 1"
   [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ))
@@ -6039,63 +6065,64 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
 	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
 		   UNSPEC_FCTIWZ))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "btruncsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceildf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "ceilsf2"
  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floordf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "floorsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "rounddf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "roundsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
@@ -6114,24 +6141,31 @@
   "TARGET_HARD_FLOAT && !TARGET_FPRS"
   "")
 
+(define_insn "floatsisf2_internal"
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+        (float:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
+  "fcfid %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncdfdi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r")
 	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "floatdisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
   "
 {
   rtx val = operands[1];
@@ -6153,7 +6187,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))
    (clobber (match_scratch:DF 2 "=f"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -6187,7 +6221,7 @@
 			   (label_ref (match_operand:DI 2 "" ""))
 			   (pc)))
    (set (match_dup 0) (match_dup 1))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "
 {
   operands[3] = gen_reg_rtx (DImode);
@@ -8219,7 +8253,7 @@
 	(match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))]
   "(gpc_reg_operand (operands[0], SFmode)
    || gpc_reg_operand (operands[1], SFmode))
-   && (TARGET_HARD_FLOAT && TARGET_FPRS)"
+   && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
   "@
    mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
@@ -8357,7 +8391,7 @@
 (define_insn "*movdf_hardfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8452,7 +8486,9 @@
 (define_insn "*movdf_softfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
 	(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
-  "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+  "! TARGET_POWERPC64 
+   && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) 
+       || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "*
@@ -8495,7 +8531,8 @@
 (define_insn "*movdf_hardfloat64_mfpgpr"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
-  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8521,7 +8558,8 @@
 (define_insn "*movdf_hardfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
 	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
-  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
+   && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
@@ -8614,7 +8652,8 @@
 		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
 	      (use (match_dup 2))])]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
 {
   operands[2] = CONST0_RTX (DFmode);
   /* Generate GOT reference early for SVR4 PIC.  */
@@ -8627,7 +8666,8 @@
        (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(pc)]
@@ -8684,7 +8724,8 @@
   [(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")])
 
@@ -8708,7 +8749,8 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -8738,7 +8780,7 @@
 	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
 		   UNSPEC_FIX_TRUNC_TF))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
   [(set_attr "type" "fp")
    (set_attr "length" "20")])
@@ -8859,7 +8901,8 @@
 			   (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128"
   "
 {
   const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
@@ -10010,7 +10053,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    lfsux %3,%0,%2
    lfsu %3,%2(%0)"
@@ -10022,7 +10065,7 @@
 	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
   "@
    stfsux %3,%0,%2
    stfsu %3,%2(%0)"
@@ -10058,7 +10101,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    lfdux %3,%0,%2
    lfdu %3,%2(%0)"
@@ -10070,7 +10113,7 @@
 	(match_operand:DF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
   "@
    stfdux %3,%0,%2
    stfdu %3,%2(%0)"
@@ -10091,7 +10134,7 @@
    (set (match_operand:DF 2 "gpc_reg_operand" "")
 	(match_operand:DF 3 "memory_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[0], operands[2])
    && mems_ok_for_quad_peep (operands[1], operands[3])"
   [(set (match_dup 0)
@@ -10113,7 +10156,7 @@
    (set (match_operand:DF 2 "memory_operand" "")
 	(match_operand:DF 3 "gpc_reg_operand" ""))]
   "TARGET_POWER2
-   && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && registers_ok_for_quad_peep (operands[1], operands[3])
    && mems_ok_for_quad_peep (operands[0], operands[2])"
   [(set (match_dup 0)
@@ -11899,7 +11942,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
 		      (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11907,7 +11950,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
 		      (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -11917,7 +11960,7 @@
 	(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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
    (set_attr "length" "12")])
@@ -11935,7 +11978,7 @@
     (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"
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 13))
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.opt gcc/gcc/config/rs6000/rs6000.opt
--- gcc-orig/gcc/config/rs6000/rs6000.opt	2008-09-18 13:33:09.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.opt	2008-09-18 13:36:39.000000000 -0700
@@ -260,3 +260,15 @@ Specify alignment of structure fields de
 mprioritize-restricted-insns=
 Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority)
 Specify scheduling priority for dispatch slot restricted insns
+
+msingle-float
+Target RejectNegative Var(rs6000_single_float)
+Single-precision floating point unit
+
+mdouble-float
+Target RejectNegative Var(rs6000_double_float)
+Double-precision floating point unit
+
+msimple-fpu
+Target RejectNegative Var(rs6000_simple_fpu)
+Floating point unit does not support divide & sqrt
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/singlefp.h gcc/gcc/config/rs6000/singlefp.h
--- gcc-orig/gcc/config/rs6000/singlefp.h	1969-12-31 16:00:00.000000000 -0800
+++ gcc/gcc/config/rs6000/singlefp.h	2008-09-18 13:36:39.000000000 -0700
@@ -0,0 +1,40 @@
+/* Definitions for PowerPC single-precision floating point unit
+   such as Xilinx PowerPC 405/440 APU.
+
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Michael Eager (eager@eagercon.com)
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Undefine definitions from rs6000.h. */
+#undef TARGET_SINGLE_FLOAT
+#undef TARGET_DOUBLE_FLOAT
+#undef TARGET_SINGLE_FPU
+#undef TARGET_SIMPLE_FPU
+#undef UNITS_PER_FP_WORD
+
+/* FPU operations supported. 
+   If TARGET_SINGLE_FPU set, processor supports single fp options. */
+#define TARGET_SINGLE_FLOAT (rs6000_single_float)
+#define TARGET_DOUBLE_FLOAT (rs6000_double_float)
+#define TARGET_SINGLE_FPU   1
+#define TARGET_SIMPLE_FPU   (rs6000_simple_fpu)
+
+/* FP word width depends on single/double fp support. */
+#define UNITS_PER_FP_WORD ((TARGET_SOFT_FLOAT || TARGET_DOUBLE_FLOAT) ? 8 : 4)
+
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config.gcc gcc/gcc/config.gcc
--- gcc-orig/gcc/config.gcc	2008-09-18 13:33:11.000000000 -0700
+++ gcc/gcc/config.gcc	2008-09-18 13:36:39.000000000 -0700
@@ -1791,6 +1791,11 @@ powerpc-*-eabialtivec*)
 	extra_options="${extra_options} rs6000/sysv4.opt"
 	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
 	;;
+powerpc-xilinx-eabi*)
+	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/singlefp.h"
+	extra_options="${extra_options} rs6000/sysv4.opt"
+	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+	;;
 powerpc-*-eabi*)
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
 	extra_options="${extra_options} rs6000/sysv4.opt"
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/doc/invoke.texi gcc/gcc/doc/invoke.texi
--- gcc-orig/gcc/doc/invoke.texi	2008-09-18 13:33:07.000000000 -0700
+++ gcc/gcc/doc/invoke.texi	2008-09-18 13:36:39.000000000 -0700
@@ -715,6 +715,7 @@ See RS/6000 and PowerPC Options.
 -m64  -m32  -mxl-compat  -mno-xl-compat  -mpe @gol
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
+-msingle-float -mdouble-float -msimple-fpu @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
 -mfused-madd  -mno-fused-madd  -mbit-align  -mno-bit-align @gol
 -mstrict-align  -mno-strict-align  -mrelocatable @gol
@@ -13419,7 +13420,8 @@ following options:
 
 @gccoptlist{-maltivec  -mfprnd  -mhard-float  -mmfcrf  -mmultiple @gol
 -mnew-mnemonics  -mpopcntb  -mpower  -mpower2  -mpowerpc64 @gol
--mpowerpc-gpopt  -mpowerpc-gfxopt  -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
+-mpowerpc-gpopt  -mpowerpc-gfxopt  -msingle-float -mdouble-float @gol
+-msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr}
 
 The particular options set for any particular CPU will vary between
 compiler versions, depending on what setting seems to produce optimal
@@ -13636,6 +13638,17 @@ Generate code that does not use (uses) t
 Software floating point emulation is provided if you use the
 @option{-msoft-float} option, and pass the option to GCC when linking.
 
+@item -msingle-float
+@itemx -mdouble-float
+@opindex msingle-float
+@opindex mdouble-float
+Generate code for single or double-precision floating point operations. 
+@option{-mdouble-float} implies @option{-msingle-float}. 
+
+@item -msimple-fpu
+@opindex msimple-fpu
+Do not generate sqrt and div instructions for hardware floating point unit.
+
 @item -mmultiple
 @itemx -mno-multiple
 @opindex mmultiple

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

end of thread, other threads:[~2008-10-06 22:50 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-21 21:18 PowerPC -- support single-precision FPU David Edelsohn
2008-09-21 21:20 ` Michael Eager
2008-09-23 17:14 ` Michael Eager
2008-09-26 16:10   ` RESUBMIT: " Michael Eager
2008-09-26 17:45     ` Janis Johnson
2008-09-26 20:13       ` Michael Eager
2008-09-29 17:42         ` Michael Eager
2008-09-30 10:46           ` Andrew Pinski
2008-09-30 13:53             ` David Edelsohn
2008-09-30 14:12           ` David Edelsohn
2008-10-02 18:22             ` Andreas Tobler
2008-10-02 19:00               ` David Edelsohn
2008-10-02 19:29                 ` Michael Eager
2008-10-02 19:49                   ` David Edelsohn
2008-10-02 19:24               ` Michael Eager
2008-10-02 19:55                 ` Andreas Tobler
2008-10-02 20:00                   ` Michael Eager
2008-10-02 20:14                     ` Andreas Tobler
2008-10-04 20:41                   ` Andreas Tobler
2008-10-06 22:57                     ` David Edelsohn
2008-10-02 20:29                 ` Janis Johnson
2008-10-02 21:25                   ` Michael Eager
2008-10-02 21:47                     ` Joseph S. Myers
  -- strict thread matches above, loose matches on Subject: below --
2008-09-19 18:37 Michael Eager
2008-09-20  6:21 ` Andrew Pinski
2008-09-21 19:21   ` Michael Eager

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