Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 163480)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -1,5 +1,5 @@
 ;; VSX patterns.
-;; Copyright (C) 2009
+;; Copyright (C) 2009, 2010
 ;; Free Software Foundation, Inc.
 ;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com>
 
@@ -73,11 +73,11 @@ (define_mode_attr VSr	[(V16QI "v")
 ;; Map the register class used for float<->int conversions
 (define_mode_attr VSr2	[(V2DF  "wd")
 			 (V4SF  "wf")
-			 (DF    "!f#r")])
+			 (DF    "ws")])
 
 (define_mode_attr VSr3	[(V2DF  "wa")
 			 (V4SF  "wa")
-			 (DF    "!f#r")])
+			 (DF    "ws")])
 
 ;; Map the register class for sp<->dp float conversions, destination
 (define_mode_attr VSr4	[(SF	"ws")
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 163480)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -6435,30 +6435,6 @@ (define_insn "*fselsfdf4"
 
 ;; Conversions to and from floating-point.
 
-(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_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_SINGLE_FLOAT"
- "")
-
-(define_expand "fixuns_truncdfsi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
-  "")
-
-(define_expand "fixuns_truncdfdi2"
-  [(set (match_operand:DI 0 "register_operand" "")
-	(unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_VSX"
-  "")
-
 ; We don't define lfiwax/lfiwzx with the normal definition, because we
 ; don't want to support putting SImode in FPR registers.
 (define_insn "lfiwax"
@@ -6793,46 +6769,85 @@ (define_insn_and_split "*floatunssidf2_i
 }"
   [(set_attr "length" "20")])
 
-(define_expand "fix_truncdfsi2"
-  [(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "")
-		   (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
-	      (clobber (match_dup 2))
-	      (clobber (match_dup 3))])]
-  "(TARGET_POWER2 || TARGET_POWERPC)
-   && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
+(define_expand "fix_trunc<mode>si2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT
+   && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
   "
 {
-  if (TARGET_E500_DOUBLE)
+  if (!<E500_CONVERT>)
     {
-     emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1]));
-     DONE;
-    }
-  operands[2] = gen_reg_rtx (DImode);
-  if (TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
-      && gpc_reg_operand(operands[0], GET_MODE (operands[0])))
-    {
-      operands[3] = gen_reg_rtx (DImode);
-      emit_insn (gen_fix_truncdfsi2_mfpgpr (operands[0], operands[1],
-					    operands[2], operands[3]));
+      rtx tmp, stack;
+
+      if (TARGET_STFIWX)
+	{
+	  tmp = gen_reg_rtx (DImode);
+	  stack = rs6000_allocate_stack_temp (SImode, false, true);
+	  emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1],
+						    tmp, stack));
+	}
+      else
+	{
+	  tmp = gen_reg_rtx (DImode);
+	  stack = rs6000_allocate_stack_temp (DImode, true, false);
+	  emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
+						      tmp, stack));
+	}
       DONE;
     }
-  if (TARGET_PPC_GFXOPT)
+}")
+
+(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
+   (clobber (match_operand:SI 3 "indexed_or_indirect_operand" "=Z"))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
+   && TARGET_STFIWX"
+  "#"
+  "&& reload_completed"
+  [(pc)]
+  "
+{
+  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
+  if (TARGET_MFPGPR && TARGET_POWERPC64 && REG_P (operands[0])
+      && INT_REGNO_P (REGNO (operands[0])))
     {
-      rtx orig_dest = operands[0];
-      if (! memory_operand (orig_dest, GET_MODE (orig_dest)))
-	operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
-      emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
-						     operands[2]));
-      if (operands[0] != orig_dest)
-	emit_move_insn (orig_dest, operands[0]);
-      DONE;
+      rtx reg = gen_lowpart (DImode, operands[0]);
+      emit_move_insn (reg, operands[2]);
     }
-  operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
-}")
+  else
+    {
+      emit_insn (gen_stfiwx (operands[3], operands[2]));
+      emit_move_insn (operands[0], operands[3]);
+    }
+  DONE;
+}"
+  [(set_attr "length" "12")])
+
+(define_insn_and_split "*fix_trunc<mode>si2_mem"
+  [(set (match_operand:SI 0 "memory_operand" "=Z")
+	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
+   (clobber (match_scratch:DI 2 "=d"))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
+   && TARGET_STFIWX"
+  "#"
+  "&& reload_completed"
+  [(pc)]
+  "
+{
+  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
+  emit_insn (gen_stfiwx (operands[0], operands[2]));
+  DONE;
+}"
+  [(set_attr "length" "8")])
 
-(define_insn_and_split "*fix_truncdfsi2_internal"
+(define_insn_and_split "fix_trunc<mode>si2_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
+	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg>")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
@@ -6846,143 +6861,194 @@ (define_insn_and_split "*fix_truncdfsi2_
   gcc_assert (MEM_P (operands[3]));
   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
 
-  emit_insn (gen_fctiwz (operands[2], operands[1]));
+  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
   emit_move_insn (operands[3], operands[2]);
   emit_move_insn (operands[0], lowword);
   DONE;
 }"
   [(set_attr "length" "16")])
 
-(define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
+(define_expand "fix_trunc<mode>di2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
+   && TARGET_FCFID"
+  "")
+
+(define_insn "*fix_trunc<mode>di2_fctidz"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
+    && TARGET_FCFID && !VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "fctidz %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_expand "fixuns_trunc<mode>si2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT
+   && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
+       || <E500_CONVERT>)"
+  "
+{
+  if (!<E500_CONVERT>)
+    {
+      rtx tmp = gen_reg_rtx (DImode);
+      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
+      emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1],
+						   tmp, stack));
+      DONE;
+    }
+}")
+
+(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(unsigned_fix:SI
+	 (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
+   (clobber (match_operand:SI 3 "indexed_or_indirect_operand" "=Z"))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
+   && TARGET_STFIWX"
+  "#"
+  "&& reload_completed"
+  [(pc)]
+  "
+{
+  emit_insn (gen_fctiwuz_<mode> (operands[2], operands[1]));
+  if (TARGET_MFPGPR && TARGET_POWERPC64 && REG_P (operands[0])
+      && INT_REGNO_P (REGNO (operands[0])))
+    {
+      rtx reg = gen_lowpart (DImode, operands[0]);
+      emit_move_insn (reg, operands[2]);
+    }
+  else
+    {
+      emit_insn (gen_stfiwx (operands[3], operands[2]));
+      emit_move_insn (operands[0], operands[3]);
+    }
+  DONE;
+}"
+  [(set_attr "length" "12")])
+
+(define_insn_and_split "*fixuns_trunc<mode>si2_mem"
   [(set (match_operand:SI 0 "memory_operand" "=Z")
-	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
-   && TARGET_DOUBLE_FLOAT 
-   && TARGET_PPC_GFXOPT"
+	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
+   (clobber (match_scratch:DI 2 "=d"))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
+   && TARGET_STFIWX"
   "#"
-  "&& 1"
+  "&& reload_completed"
   [(pc)]
   "
 {
-  emit_insn (gen_fctiwz (operands[2], operands[1]));
+  emit_insn (gen_fctiwuz_<mode> (operands[2], operands[1]));
   emit_insn (gen_stfiwx (operands[0], operands[2]));
   DONE;
 }"
-  [(set_attr "length" "16")])
+  [(set_attr "length" "8")])
 
-(define_insn_and_split "fix_truncdfsi2_mfpgpr"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
-   (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
-  "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))
-   (set (match_dup 3) (match_dup 2))
-   (set (match_dup 0) (subreg:SI (match_dup 3) 4))]
-  ""
-  [(set_attr "length" "12")])
+(define_expand "fixuns_trunc<mode>di2"
+  [(set (match_operand:DI 0 "register_operand" "")
+	(unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
+  "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
+  "")
+
+(define_insn "*fixuns_trunc<mode>di2_fctiduz"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
+    && TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "fctiduz %0,%1"
+  [(set_attr "type" "fp")])
 
 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
 ; because the first makes it clear that operand 0 is not live
 ; before the instruction.
-(define_insn "fctiwz"
+(define_insn "fctiwz_<mode>"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
-	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))]
+	(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))]
 		   UNSPEC_FCTIWZ))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
    && TARGET_DOUBLE_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
-(define_expand "btruncdf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
-  "")
-
-(define_insn "*btruncdf2_fpr"
-  [(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_DOUBLE_FLOAT
-   && !VECTOR_UNIT_VSX_P (DFmode)"
-  "friz %0,%1"
+(define_insn "fctiwuz_<mode>"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(unspec:DI [(unsigned_fix:SI
+		     (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>"))]
+		   UNSPEC_FCTIWUZ))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
+  "fctiwuz %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_SINGLE_FLOAT"
-  "friz %0,%1"
+;; No VSX equivalent to fctid
+(define_insn "lrint<mode>di2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+		   UNSPEC_FCTID))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
+  "fctid %0,%1"
   [(set_attr "type" "fp")])
 
-(define_expand "ceildf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
+(define_expand "btrunc<mode>2"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
+		     UNSPEC_FRIZ))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
   "")
 
-(define_insn "*ceildf2_fpr"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
-   && !VECTOR_UNIT_VSX_P (DFmode)"
-  "frip %0,%1"
+(define_insn "*btrunc<mode>2_fpr"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+		     UNSPEC_FRIZ))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
+   && !VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "friz %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_SINGLE_FLOAT "
+(define_expand "ceil<mode>2"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
+		     UNSPEC_FRIP))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
+  "")
+
+(define_insn "*ceil<mode>2_fpr"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+		     UNSPEC_FRIP))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
+   && !VECTOR_UNIT_VSX_P (<MODE>mode)"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
-(define_expand "floordf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
+(define_expand "floor<mode>2"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
+		     UNSPEC_FRIM))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
   "")
 
-(define_insn "*floordf2_fpr"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))]
-  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
-   && !VECTOR_UNIT_VSX_P (DFmode)"
-  "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_SINGLE_FLOAT "
+(define_insn "*floor<mode>2_fpr"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+		     UNSPEC_FRIM))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
+   && !VECTOR_UNIT_VSX_P (<MODE>mode)"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
 ;; No VSX equivalent to frin
-(define_insn "rounddf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))]
-  "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_SINGLE_FLOAT "
+(define_insn "round<mode>2"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+		     UNSPEC_FRIN))]
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
   "frin %0,%1"
   [(set_attr "type" "fp")])
 
-(define_expand "ftruncdf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-  	(fix:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "VECTOR_UNIT_VSX_P (DFmode)"
-  "")
-
 ; An UNSPEC is used so we don't have to support SImode in FP registers.
 (define_insn "stfiwx"
   [(set (match_operand:SI 0 "memory_operand" "=Z")
@@ -9860,7 +9926,7 @@ (define_insn_and_split "*fix_trunctfsi2_
   gcc_assert (MEM_P (operands[5]));
   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
 
-  emit_insn (gen_fctiwz (operands[4], operands[2]));
+  emit_insn (gen_fctiwz_df (operands[4], operands[2]));
   emit_move_insn (operands[5], operands[4]);
   emit_move_insn (operands[0], lowword);
   DONE;
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-7.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3 -mcpu=power5 -ffast-math" } */
+/* { dg-final { scan-assembler-times "fctiwz" 2 } } */
+/* { dg-final { scan-assembler-not "fctiwuz" } } */
+/* { dg-final { scan-assembler-times "fctidz" 8 } } */
+/* { dg-final { scan-assembler-not "fctiduz" } } */
+/* { dg-final { scan-assembler-not "xscvdpsxds" } } */
+/* { dg-final { scan-assembler-not "xscvdpuxds" } } */
+
+void float_to_int  (int *dest, float  src) { *dest = (int) src; }
+void double_to_int (int *dest, double src) { *dest = (int) src; }
+
+void float_to_uint  (int *dest, float  src) { *dest = (unsigned int) src; }
+void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
+
+void float_to_llong  (long long *dest, float  src) { *dest = (long long) src; }
+void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
+
+void float_to_ullong  (unsigned long long *dest, float  src) { *dest = (unsigned long long) src; }
+void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-8.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3 -mcpu=750 -ffast-math" } */
+/* { dg-final { scan-assembler-times "fctiwz" 6 } } */
+/* { dg-final { scan-assembler-not "fctiwuz" } } */
+/* { dg-final { scan-assembler-not "fctidz" } } */
+/* { dg-final { scan-assembler-not "fctiduz" } } */
+/* { dg-final { scan-assembler-not "xscvdpsxds" } } */
+/* { dg-final { scan-assembler-not "xscvdpuxds" } } */
+
+void float_to_int  (int *dest, float  src) { *dest = (int) src; }
+void double_to_int (int *dest, double src) { *dest = (int) src; }
+
+void float_to_uint  (int *dest, float  src) { *dest = (unsigned int) src; }
+void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
+
+void float_to_llong  (long long *dest, float  src) { *dest = (long long) src; }
+void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
+
+void float_to_ullong  (unsigned long long *dest, float  src) { *dest = (unsigned long long) src; }
+void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-9.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-9.c	(revision 0)
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O3 -mcpu=power7 -ffast-math" } */
+/* { dg-final { scan-assembler-not "lwz" } } */
+/* { dg-final { scan-assembler-not "stw" } } */
+/* { dg-final { scan-assembler-not "ld " } } */
+/* { dg-final { scan-assembler-not "std" } } */
+
+void float_to_llong  (long long *dest, float  src) { *dest = (long long) src; }
+void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-5.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O3 -mcpu=power7 -ffast-math" } */
+/* { dg-final { scan-assembler-times "fctiwz" 2 } } */
+/* { dg-final { scan-assembler-times "fctiwuz" 2 } } */
+/* { dg-final { scan-assembler-times "fctidz" 1 } } */
+/* { dg-final { scan-assembler-times "fctiduz" 1 } } */
+/* { dg-final { scan-assembler-times "xscvdpsxds" 1 } } */
+/* { dg-final { scan-assembler-times "xscvdpuxds" 1 } } */
+
+void float_to_int  (int *dest, float  src) { *dest = (int) src; }
+void double_to_int (int *dest, double src) { *dest = (int) src; }
+
+void float_to_uint  (int *dest, float  src) { *dest = (unsigned int) src; }
+void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
+
+void float_to_llong  (long long *dest, float  src) { *dest = (long long) src; }
+void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
+
+void float_to_ullong  (unsigned long long *dest, float  src) { *dest = (unsigned long long) src; }
+void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-6.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O3 -mcpu=power6 -ffast-math" } */
+/* { dg-final { scan-assembler-times "fctiwz" 2 } } */
+/* { dg-final { scan-assembler-not "fctiwuz" } } */
+/* { dg-final { scan-assembler-times "fctidz" 8 } } */
+/* { dg-final { scan-assembler-not "fctiduz" } } */
+/* { dg-final { scan-assembler-not "xscvdpsxds" } } */
+/* { dg-final { scan-assembler-not "xscvdpuxds" } } */
+
+void float_to_int  (int *dest, float  src) { *dest = (int) src; }
+void double_to_int (int *dest, double src) { *dest = (int) src; }
+
+void float_to_uint  (int *dest, float  src) { *dest = (unsigned int) src; }
+void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
+
+void float_to_llong  (long long *dest, float  src) { *dest = (long long) src; }
+void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
+
+void float_to_ullong  (unsigned long long *dest, float  src) { *dest = (unsigned long long) src; }
+void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
