This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: RFC: Add power7 support to the rs6000 (part 5 of 12)


2009-06-04  Michael Meissner  <meissner@linux.vnet.ibm.com>
	    Pat Haugen  <pthaugen@us.ibm.com>
	    Revital1 Eres <ERES@il.ibm.com>

	* config/rs6000/rs6000.md (UNSPEC_BPERM): Define.
	(cpu attribute): Add power7.
	(toplevel): Include power7.md, vsx.md, and vector.md.
	(sel mode attribute): New attribute for 32/64-bit isel support.
	(tptrsize attribute): New attribute to the appropriate target
	pointer size.
	(mptrsize attribute): New attribute for the appropriate target
	pointer type name.
	(andi./andiu. patterns): Set type to fast_compare for CC0.
	(popcntwsi2): New insn for power7 popcount.
	(popcntddi2): Ditto.
	(popcount<mode>): Add -mpopcntd support.
	(fmaddsf4_power): Name pattern.
	(fmsubsf4_powerpc): Ditto.
	(fmsubsf4_power): Ditto.
	(fmsubsf4_powerpc): Ditto.
	(fnmaddsf4_powerpc_2): Ditto.
	(fnmaddsf4_power_1): Ditto.
	(fnmaddsf4_power_2): Ditto.
	(fnmsubsf4_powerpc_1): Ditto.
	(fnmsubsf4_powerpc_2): Ditto.
	(fnmsubsf4_power_1): Ditto.
	(fnmsubsf4_power_2): Ditto.
	(copysigndf3): Add -mvsx support.
	(mov<mode>cc): Add support for -misel in 64-bit platforms.
	(isel_signed_<mode>): Ditto.
	(isel_unsigned_<mode>): Ditto.
	(negdf2_fpr): If -mvsx, don't match here, let the pattern in
	vsx.md match.
	(absdf2_fpr): Ditto.
	(nabsdf2_fpr): Ditto.
	(adddf3_fpr): Ditto.
	(subdf3_fpr): Ditto.
	(muldf3_fpr): Ditto.
	(divdf3_fpr): Ditto.
	(fred): Ditto.
	(fred_fpr): Ditto.
	(cmpdf_internal1): Ditto.
	(fmadddf4_fpr): Name pattern, if -mvsx, don't match here, let the
	pattern in vsx.md match.
	(fmsubdf4_fpr): Ditto.
	(fnmadddf4_fp_1): Ditto.
	(fnmadddf4_fp_2): Ditto.
	(fnmsubdf4_fp_1): Ditto.
	(fnmsubdf4_fp_2): Ditto.
	(fixuns_truncdfsi2): New expander to match fix unsigned in spe.
	(fixuns_truncdfdi2): New expander for -mvsx.
	(btruncsf2): Fix spacing.
	(btruncdf2): Split insn into expander and pattern.  On the
	pattern, match if not -mvsx.
	(btruncdf2_fprs): Ditto.
	(ceildf2): Ditto.
	(ceildf2_fprs): Ditto.
	(floordf2): Ditto.
	(floordf2_fprs): Ditto.
	(floatdidf2): Ditto.
	(floatdidf2_fprs): Ditto.
	(fix_truncdfdi2): Ditto.
	(fix_truncdfdi2_fpr): Ditto.
	(ftruncdf2): Add expander for VSX.
	(smindi3): Add expander if -misel on 64-bit system.
	(smaxdi3): Ditto.
	(umindi3): Ditto.
	(smaxdi3): Ditto.
	(movdf_hardfloat32): Add VSX support.
	(movdf_hardfloat64_mfpgpr): Ditto.
	(movdf_hardfloat64): Ditto.
	(movti_ppc64): Add prelimary support for moving TImode into VSX
	registers (currently disabled).
	(indirect_jump): Record when an indirect jump is done so we can
	favor not using the CTR register for count down loops.
	(indirect_jump<mode>): Ditto.
	(doloop_end): If an indirect jump has been done, turn off using
	count down loops which want to use the same register.
	(bpermd_<mode>): New builtin for power7 bpermd instruction.

Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk)	(revision 148152)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -101,6 +101,7 @@ (define_constants
    (UNSPEC_RSQRT		48)
    (UNSPEC_TOCREL		49)
    (UNSPEC_MACHOPIC_OFFSET	50)
+   (UNSPEC_BPERM		51)
   ])
 
 ;;
@@ -138,7 +139,7 @@ (define_attr "length" ""
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000.h.
 
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,power7,cell"
   (const (symbol_ref "rs6000_cpu_attr")))
 
 
@@ -167,6 +168,7 @@ (define_attr "cell_micro" "not,condition
 (include "power4.md")
 (include "power5.md")
 (include "power6.md")
+(include "power7.md")
 (include "cell.md")
 (include "xfpu.md")
 
@@ -218,6 +220,19 @@ (define_mode_attr wd [(QI "b") (HI "h") 
 ; DImode bits
 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
 
+;; ISEL/ISEL64 target selection
+(define_mode_attr sel [(SI "") (DI "64")])
+
+;; Suffix for reload patterns
+(define_mode_attr ptrsize [(SI "32bit")
+			   (DI "64bit")])
+
+(define_mode_attr tptrsize [(SI "TARGET_32BIT")
+			    (DI "TARGET_64BIT")])
+
+(define_mode_attr mptrsize [(SI "si")
+			    (DI "di")])
+
 
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
@@ -520,7 +535,7 @@ (define_insn ""
   "@
    {andil.|andi.} %2,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -546,7 +561,7 @@ (define_insn ""
   "@
    {andil.|andi.} %0,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -687,7 +702,7 @@ (define_insn ""
   "@
    {andil.|andi.} %2,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -713,7 +728,7 @@ (define_insn ""
   "@
    {andil.|andi.} %0,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -856,7 +871,7 @@ (define_insn ""
   "@
    {andil.|andi.} %2,%1,0xffff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -882,7 +897,7 @@ (define_insn ""
   "@
    {andil.|andi.} %0,%1,0xffff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1670,7 +1685,7 @@ (define_insn ""
   "@
    nor. %2,%1,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1696,7 +1711,7 @@ (define_insn ""
   "@
    nor. %0,%1,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2221,10 +2236,22 @@ (define_insn "popcntb<mode>2"
   "TARGET_POPCNTB"
   "popcntb %0,%1")
 
+(define_insn "popcntwsi2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(popcount:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
+  "TARGET_POPCNTD"
+  "popcntw %0,%1")
+
+(define_insn "popcntddi2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(popcount:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
+  "TARGET_POPCNTD && TARGET_POWERPC64"
+  "popcntd %0,%1")
+
 (define_expand "popcount<mode>2"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
 	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
-  "TARGET_POPCNTB"
+  "TARGET_POPCNTB || TARGET_POPCNTD"
   {
     rs6000_emit_popcount (operands[0], operands[1]);
     DONE;
@@ -2852,7 +2879,7 @@ (define_insn "andsi3_mc"
    {rlinm|rlwinm} %0,%1,0,%m2,%M2
    {andil.|andi.} %0,%1,%b2
    {andiu.|andis.} %0,%1,%u2"
-  [(set_attr "type" "*,*,compare,compare")])
+  [(set_attr "type" "*,*,fast_compare,fast_compare")])
 
 (define_insn "andsi3_nomc"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
@@ -2895,7 +2922,8 @@ (define_insn "*andsi3_internal2_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
+		     compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,8,8,8,8")])
 
 (define_insn "*andsi3_internal3_mc"
@@ -2915,7 +2943,8 @@ (define_insn "*andsi3_internal3_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
+		     compare,compare,compare")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
 (define_split
@@ -2974,7 +3003,8 @@ (define_insn "*andsi3_internal4"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
+		     compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,8,8,8,8")])
 
 (define_insn "*andsi3_internal5_mc"
@@ -2996,7 +3026,8 @@ (define_insn "*andsi3_internal5_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
+		     compare,compare,compare")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
 (define_split
@@ -3127,7 +3158,7 @@ (define_insn "*boolsi3_internal2"
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3156,7 +3187,7 @@ (define_insn "*boolsi3_internal3"
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3281,7 +3312,7 @@ (define_insn "*boolccsi3_internal2"
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3310,7 +3341,7 @@ (define_insn "*boolccsi3_internal3"
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -5303,7 +5334,7 @@ (define_insn "fres"
   "fres %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn ""
+(define_insn "*fmaddsf4_powerpc"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5314,7 +5345,7 @@ (define_insn ""
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fmaddsf4_power"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			  (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5323,7 +5354,7 @@ (define_insn ""
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fmsubsf4_powerpc"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5334,7 +5365,7 @@ (define_insn ""
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fmsubsf4_power"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5343,7 +5374,7 @@ (define_insn ""
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_powerpc_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5354,7 +5385,7 @@ (define_insn ""
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_powerpc_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5365,7 +5396,7 @@ (define_insn ""
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_power_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				  (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5374,7 +5405,7 @@ (define_insn ""
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_power_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
 			   (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5384,7 +5415,7 @@ (define_insn ""
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_powerpc_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5395,7 +5426,7 @@ (define_insn ""
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_powerpc_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
@@ -5406,7 +5437,7 @@ (define_insn ""
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_power_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
 				   (match_operand:SF 2 "gpc_reg_operand" "f"))
@@ -5415,7 +5446,7 @@ (define_insn ""
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_power_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
 		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
@@ -5496,9 +5527,18 @@ (define_expand "copysigndf3"
 	                     (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
-   && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && ((TARGET_PPC_GFXOPT
+        && !HONOR_NANS (DFmode)
+        && !HONOR_SIGNED_ZEROS (DFmode))
+       || VECTOR_UNIT_VSX_P (DFmode))"
   {
+     if (VECTOR_UNIT_VSX_P (DFmode))
+       {
+	 emit_insn (gen_vsx_copysigndf3 (operands[0], operands[1],
+					 operands[2]));
+	 DONE;
+       }
      operands[3] = gen_reg_rtx (DFmode);
      operands[4] = gen_reg_rtx (DFmode);
      operands[5] = CONST0_RTX (DFmode);
@@ -5542,12 +5582,12 @@ (define_split
   DONE;
 }")
 
-(define_expand "movsicc"
-   [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	 (if_then_else:SI (match_operand 1 "comparison_operator" "")
-			  (match_operand:SI 2 "gpc_reg_operand" "")
-			  (match_operand:SI 3 "gpc_reg_operand" "")))]
-  "TARGET_ISEL"
+(define_expand "mov<mode>cc"
+   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
+	 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
+			   (match_operand:GPR 2 "gpc_reg_operand" "")
+			   (match_operand:GPR 3 "gpc_reg_operand" "")))]
+  "TARGET_ISEL<sel>"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5564,28 +5604,28 @@ (define_expand "movsicc"
 ;; leave out the mode in operand 4 and use one pattern, but reload can
 ;; change the mode underneath our feet and then gets confused trying
 ;; to reload the value.
-(define_insn "isel_signed"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(if_then_else:SI
+(define_insn "isel_signed_<mode>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(if_then_else:GPR
 	 (match_operator 1 "comparison_operator"
 			 [(match_operand:CC 4 "cc_reg_operand" "y")
 			  (const_int 0)])
-	 (match_operand:SI 2 "gpc_reg_operand" "b")
-	 (match_operand:SI 3 "gpc_reg_operand" "b")))]
-  "TARGET_ISEL"
+	 (match_operand:GPR 2 "gpc_reg_operand" "b")
+	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+  "TARGET_ISEL<sel>"
   "*
 { return output_isel (operands); }"
   [(set_attr "length" "4")])
 
-(define_insn "isel_unsigned"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(if_then_else:SI
+(define_insn "isel_unsigned_<mode>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(if_then_else:GPR
 	 (match_operator 1 "comparison_operator"
 			 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
 			  (const_int 0)])
-	 (match_operand:SI 2 "gpc_reg_operand" "b")
-	 (match_operand:SI 3 "gpc_reg_operand" "b")))]
-  "TARGET_ISEL"
+	 (match_operand:GPR 2 "gpc_reg_operand" "b")
+	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+  "TARGET_ISEL<sel>"
   "*
 { return output_isel (operands); }"
   [(set_attr "length" "4")])
@@ -5633,7 +5673,8 @@ (define_expand "negdf2"
 (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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5646,14 +5687,16 @@ (define_expand "absdf2"
 (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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5668,7 +5711,8 @@ (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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_addsub_d")])
@@ -5684,7 +5728,8 @@ (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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_addsub_d")])
@@ -5700,7 +5745,8 @@ (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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_mul_d")])
@@ -5718,7 +5764,8 @@ (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_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
@@ -5734,73 +5781,81 @@ (define_expand "recipdf3"
    DONE;
 })
 
-(define_insn "fred"
+(define_expand "fred"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
-  "TARGET_POPCNTB && flag_finite_math_only"
+  "(TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) && flag_finite_math_only"
+  "")
+
+(define_insn "*fred_fpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
+  "TARGET_POPCNTB && flag_finite_math_only && !VECTOR_UNIT_VSX_P (DFmode)"
   "fre %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn ""
+(define_insn "*fmadddf4_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
+   && VECTOR_UNIT_NONE_P (DFmode)"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_maddsub_d")])
 
-(define_insn ""
+(define_insn "*fmsubdf4_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
+   && VECTOR_UNIT_NONE_P (DFmode)"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_maddsub_d")])
 
-(define_insn ""
+(define_insn "*fnmadddf4_fpr_1"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(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_DOUBLE_FLOAT
-   && HONOR_SIGNED_ZEROS (DFmode)"
+   && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_maddsub_d")])
 
-(define_insn ""
+(define_insn "*fnmadddf4_fpr_2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(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_DOUBLE_FLOAT
-   && ! HONOR_SIGNED_ZEROS (DFmode)"
+   && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_maddsub_d")])
 
-(define_insn ""
+(define_insn "*fnmsubdf4_fpr_1"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(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_DOUBLE_FLOAT
-   && HONOR_SIGNED_ZEROS (DFmode)"
+   && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_maddsub_d")])
 
-(define_insn ""
+(define_insn "*fnmsubdf4_fpr_2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(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_DOUBLE_FLOAT
-   && ! HONOR_SIGNED_ZEROS (DFmode)"
+   && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")
    (set_attr "fp_type" "fp_maddsub_d")])
@@ -5809,7 +5864,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_DOUBLE_FLOAT"
+   && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
@@ -5898,6 +5954,18 @@ (define_expand "fix_truncsfsi2"
  "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"
+  "")
+
 ; For each of these conversions, there is a define_expand, a define_insn
 ; with a '#' template, and a define_split (with C code).  The idea is
 ; to allow constant folding with the template of the define_insn,
@@ -6139,24 +6207,38 @@ (define_insn "fctiwz"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn "btruncdf2"
+(define_expand "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_DOUBLE_FLOAT"
+  "")
+
+(define_insn "*btruncdf2_fprs"
+  [(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"
   [(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 "
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "friz %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn "ceildf2"
+(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_insn "*ceildf2_fprs"
   [(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_DOUBLE_FLOAT"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
@@ -6167,10 +6249,17 @@ (define_insn "ceilsf2"
   "frip %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn "floordf2"
+(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_insn "*floordf2_fprs"
   [(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_DOUBLE_FLOAT"
+  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
@@ -6181,6 +6270,7 @@ (define_insn "floorsf2"
   "frim %0,%1"
   [(set_attr "type" "fp")])
 
+;; No VSX equivalent to frin
 (define_insn "rounddf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
@@ -6195,6 +6285,12 @@ (define_insn "roundsf2"
   "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")
@@ -6210,17 +6306,40 @@ (define_expand "floatsisf2"
   "TARGET_HARD_FLOAT && !TARGET_FPRS"
   "")
 
-(define_insn "floatdidf2"
+(define_expand "floatdidf2"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "")
+	(float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
+  "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
+   && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
+  "")
+
+(define_insn "*floatdidf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
 	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
-  "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
+  "(TARGET_POWERPC64 || TARGET_XILINX_FPU)
+   && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn "fix_truncdfdi2"
+(define_expand "floatunsdidf2"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "")
+	(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
+  "TARGET_VSX"
+  "")
+
+(define_expand "fix_truncdfdi2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))]
+  "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
+    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
+  "")
+
+(define_insn "*fix_truncdfdi2_fpr"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r")
 	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
+  "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT
+    && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
 
@@ -7609,7 +7728,7 @@ (define_insn "anddi3_mc"
    andi. %0,%1,%b2
    andis. %0,%1,%u2
    #"
-  [(set_attr "type" "*,*,*,compare,compare,*")
+  [(set_attr "type" "*,*,*,fast_compare,fast_compare,*")
    (set_attr "length" "4,4,4,4,4,8")])
 
 (define_insn "anddi3_nomc"
@@ -7667,7 +7786,9 @@ (define_insn "*anddi3_internal2_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
+		     fast_compare,compare,compare,compare,compare,compare,\
+		     compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
@@ -7718,7 +7839,9 @@ (define_insn "*anddi3_internal3_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
+		     fast_compare,compare,compare,compare,compare,compare,\
+		     compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
@@ -7858,7 +7981,7 @@ (define_insn "*booldi3_internal2"
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7887,7 +8010,7 @@ (define_insn "*booldi3_internal3"
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7958,7 +8081,7 @@ (define_insn "*boolcdi3_internal2"
   "@
    %q4. %3,%2,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7987,7 +8110,7 @@ (define_insn "*boolcdi3_internal3"
   "@
    %q4. %0,%2,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -8024,7 +8147,7 @@ (define_insn "*boolccdi3_internal2"
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -8053,7 +8176,7 @@ (define_insn "*boolccdi3_internal3"
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -8070,6 +8193,51 @@ (define_split
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
   "")
+
+(define_expand "smindi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
+  DONE;
+}")
+
+(define_expand "smaxdi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
+  DONE;
+}")
+
+(define_expand "umindi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], UMIN, operands[1], operands[2]);
+  DONE;
+}")
+
+(define_expand "umaxdi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], UMAX, operands[1], operands[2]);
+  DONE;
+}")
+
 
 ;; Now define ways of moving data around.
 
@@ -8497,8 +8665,8 @@ (define_split
 ;; The "??" is a kludge until we can figure out a more reasonable way
 ;; of handling these non-offsettable values.
 (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"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=!r, ??r, m, ws, ?wa, ws, ?wa,  Z, ?Z, f, f, m, wa, !r, !r, !r")
+	(match_operand:DF 1 "input_operand"          "r,   m, r, ws,  wa,  Z,   Z, ws, wa, f, m, f,  j,  G,  H,  F"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
@@ -8577,19 +8745,30 @@ (define_insn "*movdf_hardfloat32"
 	  return \"\";
 	}
     case 3:
-      return \"fmr %0,%1\";
     case 4:
-      return \"lfd%U1%X1 %0,%1\";
+      return \"xxlor %x0,%x1,%x1\";
     case 5:
-      return \"stfd%U0%X0 %1,%0\";
     case 6:
+      return \"lxsd%U1x %x0,%y1\";
     case 7:
     case 8:
+      return \"stxsd%U0x %x1,%y0\";
+    case 9:
+      return \"fmr %0,%1\";
+    case 10:
+      return \"lfd%U1%X1 %0,%1\";
+    case 11:
+      return \"stfd%U0%X0 %1,%0\";
+    case 12:
+      return \"xxlxor %x0,%x0,%x0\";
+    case 13:
+    case 14:
+    case 15:
       return \"#\";
     }
 }"
-  [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*")
-   (set_attr "length" "8,16,16,4,4,4,8,12,16")])
+  [(set_attr "type" "two, load, store, fp, fp, fpload, fpload, fpstore, fpstore, fp, fpload, fpstore, vecsimple, *,  *,  *")
+   (set_attr "length" "8,   16,    16,  4,  4,      4,      4,       4,       4,  4,      4,       4,         4, 8, 12, 16")])
 
 (define_insn "*movdf_softfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
@@ -8637,19 +8816,26 @@ (define_insn "*movdf_softfloat32"
 ; ld/std require word-aligned displacements -> 'Y' constraint.
 ; List Y->r and r->Y before r->r for reload.
 (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"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y, r, !r, ws, ?wa, ws, ?wa,  Z, ?Z, f, f, m, wa, *c*l, !r, *h, !r, !r, !r, r, f")
+	(match_operand:DF 1 "input_operand"         "r, Y,  r, ws, ?wa,  Z,   Z, ws, wa, f, m, f,  j,    r,  h,  0,  G,  H,  F, f, r"))]
   "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
-   && TARGET_DOUBLE_FLOAT 
+   && TARGET_DOUBLE_FLOAT
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
    std%U0%X0 %1,%0
    ld%U1%X1 %0,%1
    mr %0,%1
+   xxlor %x0,%x1,%x1
+   xxlor %x0,%x1,%x1
+   lxsd%U1x %x0,%y1
+   lxsd%U1x %x0,%y1
+   stxsd%U0x %x1,%y0
+   stxsd%U0x %x1,%y0
    fmr %0,%1
    lfd%U1%X1 %0,%1
    stfd%U0%X0 %1,%0
+   xxlxor %x0,%x0,%x0
    mt%0 %1
    mf%1 %0
    {cror 0,0,0|nop}
@@ -8658,33 +8844,40 @@ (define_insn "*movdf_hardfloat64_mfpgpr"
    #
    mftgpr %0,%1
    mffgpr %0,%1"
-  [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
-   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
+  [(set_attr "type" "store, load, *, fp, fp, fpload, fpload, fpstore, fpstore, fp, fpload, fpstore, vecsimple, mtjmpr, mfjmpr, *, *,  *,  *, mftgpr, mffgpr")
+   (set_attr "length"   "4,    4, 4,  4,  4,      4,      4,       4,       4,  4,      4,       4,         4,      4,      4, 4, 8, 12, 16,      4,      4")])
 
 ; ld/std require word-aligned displacements -> 'Y' constraint.
 ; List Y->r and r->Y before r->r for reload.
 (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"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y, r, !r, ws, ?wa, ws, ?wa,  Z, ?Z, f, f, m, wa, *c*l, !r, *h, !r, !r, !r")
+	(match_operand:DF 1 "input_operand"         "r, Y,  r, ws,  wa,  Z,   Z, ws, wa, f, m, f,  j,    r,  h,  0,  G,  H,  F"))]
   "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
-   && TARGET_DOUBLE_FLOAT 
+   && TARGET_DOUBLE_FLOAT
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
    std%U0%X0 %1,%0
    ld%U1%X1 %0,%1
    mr %0,%1
+   xxlor %x0,%x1,%x1
+   xxlor %x0,%x1,%x1
+   lxsd%U1x %x0,%y1
+   lxsd%U1x %x0,%y1
+   stxsd%U0x %x1,%y0
+   stxsd%U0x %x1,%y0
    fmr %0,%1
    lfd%U1%X1 %0,%1
    stfd%U0%X0 %1,%0
+   xxlxor %x0,%x0,%x0
    mt%0 %1
    mf%1 %0
    {cror 0,0,0|nop}
    #
    #
    #"
-  [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*")
-   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")])
+  [(set_attr "type" "store, load, *, fp, fp, fpload, fpload, fpstore, fpstore, fp, fpload, fpstore, vecsimple, mtjmpr, mfjmpr,  *,  *,  *,  *")
+   (set_attr "length" "  4,    4, 4,  4,  4,      4,      4,       4,       4,  4,      4,       4,         4,      4,      4,  4,  8, 12, 16")])
 
 (define_insn "*movdf_softfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
@@ -9261,15 +9454,16 @@ (define_insn "*movti_string"
 (define_insn "*movti_ppc64"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")
 	(match_operand:TI 1 "input_operand" "r,r,m"))]
-  "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
-   || gpc_reg_operand (operands[1], TImode))"
+  "(TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
+    || gpc_reg_operand (operands[1], TImode)))
+   && VECTOR_MEM_NONE_P (TImode)"
   "#"
   [(set_attr "type" "*,store,load")])
 
 (define_split
   [(set (match_operand:TI 0 "gpc_reg_operand" "")
 	(match_operand:TI 1 "const_double_operand" ""))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && VECTOR_MEM_NONE_P (TImode)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
   "
@@ -9295,7 +9489,7 @@ (define_split
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
         (match_operand:TI 1 "input_operand" ""))]
-  "reload_completed
+  "reload_completed && VECTOR_MEM_NONE_P (TImode)
    && gpr_or_gpr_p (operands[0], operands[1])"
   [(pc)]
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
@@ -12188,7 +12382,8 @@ (define_insn "*cmpdf_internal1"
   [(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_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
@@ -14326,7 +14521,11 @@ (define_insn "return"
   [(set_attr "type" "jmpreg")])
 
 (define_expand "indirect_jump"
-  [(set (pc) (match_operand 0 "register_operand" ""))])
+  [(set (pc) (match_operand 0 "register_operand" ""))]
+  ""
+{
+  rs6000_set_indirect_jump ();
+})
 
 (define_insn "*indirect_jump<mode>"
   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
@@ -14341,14 +14540,14 @@ (define_expand "tablejump"
   [(use (match_operand 0 "" ""))
    (use (label_ref (match_operand 1 "" "")))]
   ""
-  "
 {
+  rs6000_set_indirect_jump ();
   if (TARGET_32BIT)
     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
   else
     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
   DONE;
-}")
+})
 
 (define_expand "tablejumpsi"
   [(set (match_dup 3)
@@ -14408,6 +14607,11 @@ (define_expand "doloop_end"
   /* Only use this on innermost loops.  */
   if (INTVAL (operands[3]) > 1)
     FAIL;
+  /* Do not try to use decrement and count on code that has an indirect
+     jump or a table jump, because the ctr register is preferred over the
+     lr register.  */
+  if (rs6000_has_indirect_jump_p ())
+    FAIL;
   if (TARGET_64BIT)
     {
       if (GET_MODE (operands[0]) != DImode)
@@ -14861,8 +15065,19 @@ (define_insn "prefetch"
 }"
   [(set_attr "type" "load")])
 
+(define_insn "bpermd_<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
+		   (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
+  "TARGET_POPCNTD"
+  "bpermd %0,%1,%2"
+  [(set_attr "type" "integer")])
+
+
 
 (include "sync.md")
+(include "vector.md")
+(include "vsx.md")
 (include "altivec.md")
 (include "spe.md")
 (include "dfp.md")

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]