diff gcc/config/rs6000/rs6000.md @ 57:326d9e06c2e3

modify c-parser.c
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 15 Feb 2010 00:54:17 +0900
parents 27e6f95b2c21 77e2b8dfacca
children 1b10fe6932e1
line wrap: on
line diff
--- a/gcc/config/rs6000/rs6000.md	Sun Feb 07 18:30:54 2010 +0900
+++ b/gcc/config/rs6000/rs6000.md	Mon Feb 15 00:54:17 2010 +0900
@@ -55,6 +55,7 @@
 
 (define_constants
   [(UNSPEC_FRSP			0)	; frsp for POWER machines
+   (UNSPEC_PROBE_STACK		4)	; probe stack memory reference
    (UNSPEC_TIE			5)	; tie stack contents and stack pointer
    (UNSPEC_TOCPTR		6)	; address of a word pointing to the TOC
    (UNSPEC_TOC			7)	; address of the TOC (more-or-less)
@@ -101,6 +102,7 @@
    (UNSPEC_RSQRT		48)
    (UNSPEC_TOCREL		49)
    (UNSPEC_MACHOPIC_OFFSET	50)
+   (UNSPEC_BPERM		51)
   ])
 
 ;;
@@ -116,7 +118,7 @@
 
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
-(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr"
+(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel"
   (const_string "integer"))
 
 ;; Define floating point instruction sub-types for use with Xfpu.md
@@ -138,7 +140,7 @@
 ;; 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,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2"
   (const (symbol_ref "rs6000_cpu_attr")))
 
 
@@ -157,6 +159,7 @@
 (include "mpc.md")
 (include "40x.md")
 (include "440.md")
+(include "476.md")
 (include "603.md")
 (include "6xx.md")
 (include "7xx.md")
@@ -164,11 +167,14 @@
 (include "8540.md")
 (include "e300c2c3.md")
 (include "e500mc.md")
+(include "e500mc64.md")
 (include "power4.md")
 (include "power5.md")
 (include "power6.md")
+(include "power7.md")
 (include "cell.md")
 (include "xfpu.md")
+(include "a2.md")
 
 (include "predicates.md")
 (include "constraints.md")
@@ -218,6 +224,19 @@
 ; 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 +539,7 @@
   "@
    {andil.|andi.} %2,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -546,7 +565,7 @@
   "@
    {andil.|andi.} %0,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -687,7 +706,7 @@
   "@
    {andil.|andi.} %2,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -713,7 +732,7 @@
   "@
    {andil.|andi.} %0,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -856,7 +875,7 @@
   "@
    {andil.|andi.} %2,%1,0xffff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -882,7 +901,7 @@
   "@
    {andil.|andi.} %0,%1,0xffff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -959,7 +978,7 @@
   [(set_attr "type" "compare")
    (set_attr "length" "4,8")])
 
-;; IBM 405, 440 and 464 half-word multiplication operations.
+;; IBM 405, 440, 464 and 476 half-word multiplication operations.
 
 (define_insn "*macchwc"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
@@ -1423,7 +1442,7 @@
   "mullhwu %0, %1, %2"
   [(set_attr "type" "imul3")])
 
-;; IBM 405, 440 and 464 string-search dlmzb instruction support.
+;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
 (define_insn "dlmzb"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
@@ -1670,7 +1689,7 @@
   "@
    nor. %2,%1,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1696,7 +1715,7 @@
   "@
    nor. %0,%1,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2060,23 +2079,42 @@
   "TARGET_POWER"
   "abs %0,%1")
 
-(define_insn_and_split "abssi2_isel"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-        (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-   (clobber (match_scratch:SI 2 "=&b"))
+(define_insn_and_split "abs<mode>2_isel"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+        (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b")))
+   (clobber (match_scratch:GPR 2 "=&b"))
    (clobber (match_scratch:CC 3 "=y"))]
   "TARGET_ISEL"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2) (neg:SI (match_dup 1)))
+  [(set (match_dup 2) (neg:GPR (match_dup 1)))
    (set (match_dup 3)
 	(compare:CC (match_dup 1)
 		    (const_int 0)))
    (set (match_dup 0)
-	(if_then_else:SI (ge (match_dup 3)
-			     (const_int 0))
-			 (match_dup 1)
-			 (match_dup 2)))]
+	(if_then_else:GPR (ge (match_dup 3)
+			      (const_int 0))
+			  (match_dup 1)
+			  (match_dup 2)))]
+  "")
+
+(define_insn_and_split "nabs<mode>2_isel"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+        (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b"))))
+   (clobber (match_scratch:GPR 2 "=&b"))
+   (clobber (match_scratch:CC 3 "=y"))]
+  "TARGET_ISEL"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 2) (neg:GPR (match_dup 1)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 1)
+		    (const_int 0)))
+   (set (match_dup 0)
+	(if_then_else:GPR (ge (match_dup 3)
+			      (const_int 0))
+			  (match_dup 2)
+			  (match_dup 1)))]
   "")
 
 (define_insn_and_split "abssi2_nopower"
@@ -2221,10 +2259,22 @@
   "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;
@@ -2239,15 +2289,102 @@
     DONE;
   })
 
-(define_insn "bswapsi2"
+;; Since the hardware zeros the upper part of the register, save generating the
+;; AND immediate if we are converting to unsigned
+(define_insn "*bswaphi2_extenddi"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(zero_extend:DI
+	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
+  "TARGET_POWERPC64"
+  "lhbrx %0,%y1"
+  [(set_attr "length" "4")
+   (set_attr "type" "load")])
+
+(define_insn "*bswaphi2_extendsi"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(zero_extend:SI
+	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
+  "TARGET_POWERPC"
+  "lhbrx %0,%y1"
+  [(set_attr "length" "4")
+   (set_attr "type" "load")])
+
+(define_expand "bswaphi2"
+  [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
+		   (bswap:HI
+		    (match_operand:HI 1 "reg_or_mem_operand" "")))
+	      (clobber (match_scratch:SI 2 ""))])]
+  ""
+{
+  if (!REG_P (operands[0]) && !REG_P (operands[1]))
+    operands[1] = force_reg (HImode, operands[1]);
+})
+
+(define_insn "bswaphi2_internal"
+  [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
+	(bswap:HI
+	 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
+   (clobber (match_scratch:SI 2 "=X,X,&r"))]
+  "TARGET_POWERPC"
+  "@
+   lhbrx %0,%y1
+   sthbrx %1,%y0
+   #"
+  [(set_attr "length" "4,4,12")
+   (set_attr "type" "load,store,*")])
+
+(define_split
+  [(set (match_operand:HI 0 "gpc_reg_operand" "")
+	(bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
+   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
+  "TARGET_POWERPC && reload_completed"
+  [(set (match_dup 3)
+	(zero_extract:SI (match_dup 4)
+			 (const_int 8)
+			 (const_int 16)))
+   (set (match_dup 2)
+	(and:SI (ashift:SI (match_dup 4)
+			   (const_int 8))
+		(const_int 65280)))		;; 0xff00
+   (set (match_dup 3)
+	(ior:SI (match_dup 3)
+		(match_dup 2)))]
+  "
+{
+  operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
+  operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
+}")
+
+(define_insn "*bswapsi2_extenddi"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(zero_extend:DI
+	 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
+  "TARGET_POWERPC64"
+  "lwbrx %0,%y1"
+  [(set_attr "length" "4")
+   (set_attr "type" "load")])
+
+(define_expand "bswapsi2"
+  [(set (match_operand:SI 0 "reg_or_mem_operand" "")
+	(bswap:SI
+	 (match_operand:SI 1 "reg_or_mem_operand" "")))]
+  ""
+{
+  if (!REG_P (operands[0]) && !REG_P (operands[1]))
+    operands[1] = force_reg (SImode, operands[1]);
+})
+
+(define_insn "*bswapsi2_internal"
   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
-	(bswap:SI (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
+	(bswap:SI
+	 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
   ""
   "@
    {lbrx|lwbrx} %0,%y1
    {stbrx|stwbrx} %1,%y0
    #"
-  [(set_attr "length" "4,4,12")])
+  [(set_attr "length" "4,4,12")
+   (set_attr "type" "load,store,*")])
 
 (define_split
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -2266,6 +2403,300 @@
 		   (const_int 16)))]
   "")
 
+(define_expand "bswapdi2"
+  [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
+		   (bswap:DI
+		    (match_operand:DI 1 "reg_or_mem_operand" "")))
+	      (clobber (match_scratch:DI 2 ""))
+	      (clobber (match_scratch:DI 3 ""))
+	      (clobber (match_scratch:DI 4 ""))])]
+  ""
+{
+  if (!REG_P (operands[0]) && !REG_P (operands[1]))
+    operands[1] = force_reg (DImode, operands[1]);
+
+  if (!TARGET_POWERPC64)
+    {
+      /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
+	 that uses 64-bit registers needs the same scratch registers as 64-bit
+	 mode.  */
+      emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
+      DONE;
+    }
+})
+
+;; Power7/cell has ldbrx/stdbrx, so use it directly
+(define_insn "*bswapdi2_ldbrx"
+  [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
+	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
+   (clobber (match_scratch:DI 2 "=X,X,&r"))
+   (clobber (match_scratch:DI 3 "=X,X,&r"))
+   (clobber (match_scratch:DI 4 "=X,X,&r"))]
+  "TARGET_POWERPC64 && TARGET_LDBRX
+   && (REG_P (operands[0]) || REG_P (operands[1]))"
+  "@
+   ldbrx %0,%y1
+   stdbrx %1,%y0
+   #"
+  [(set_attr "length" "4,4,36")
+   (set_attr "type" "load,store,*")])
+
+;; Non-power7/cell, fall back to use lwbrx/stwbrx
+(define_insn "*bswapdi2_64bit"
+  [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
+	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
+   (clobber (match_scratch:DI 2 "=&b,&b,&r"))
+   (clobber (match_scratch:DI 3 "=&r,&r,&r"))
+   (clobber (match_scratch:DI 4 "=&r,X,&r"))]
+  "TARGET_POWERPC64 && !TARGET_LDBRX
+   && (REG_P (operands[0]) || REG_P (operands[1]))"
+  "#"
+  [(set_attr "length" "16,12,36")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
+  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx dest   = operands[0];
+  rtx src    = operands[1];
+  rtx op2    = operands[2];
+  rtx op3    = operands[3];
+  rtx op4    = operands[4];
+  rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 4);
+  rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, 4);
+  rtx addr1;
+  rtx addr2;
+  rtx word_high;
+  rtx word_low;
+
+  addr1 = XEXP (src, 0);
+  if (GET_CODE (addr1) == PLUS)
+    {
+      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+      addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
+    }
+  else
+    {
+      emit_move_insn (op2, GEN_INT (4));
+      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
+    }
+
+  if (BYTES_BIG_ENDIAN)
+    {
+      word_high = change_address (src, SImode, addr1);
+      word_low  = change_address (src, SImode, addr2);
+    }
+  else
+    {
+      word_high = change_address (src, SImode, addr2);
+      word_low  = change_address (src, SImode, addr1);
+    }
+
+  emit_insn (gen_bswapsi2 (op3_32, word_low));
+  emit_insn (gen_bswapsi2 (op4_32, word_high));
+  emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
+  emit_insn (gen_iordi3 (dest, dest, op4));
+}")
+
+(define_split
+  [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
+	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 4 "" ""))]
+  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx dest   = operands[0];
+  rtx src    = operands[1];
+  rtx op2    = operands[2];
+  rtx op3    = operands[3];
+  rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4);
+  rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4);
+  rtx addr1;
+  rtx addr2;
+  rtx word_high;
+  rtx word_low;
+
+  addr1 = XEXP (dest, 0);
+  if (GET_CODE (addr1) == PLUS)
+    {
+      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+      addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
+    }
+  else
+    {
+      emit_move_insn (op2, GEN_INT (4));
+      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
+    }
+
+  emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
+  if (BYTES_BIG_ENDIAN)
+    {
+      word_high = change_address (dest, SImode, addr1);
+      word_low  = change_address (dest, SImode, addr2);
+      emit_insn (gen_bswapsi2 (word_high, src_si));
+      emit_insn (gen_bswapsi2 (word_low, op3_si));
+    }
+  else
+    {
+      word_high = change_address (dest, SImode, addr2);
+      word_low  = change_address (dest, SImode, addr1);
+      emit_insn (gen_bswapsi2 (word_low, src_si));
+      emit_insn (gen_bswapsi2 (word_high, op3_si));
+    }
+}")
+
+(define_split
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 4 "" ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx dest    = operands[0];
+  rtx src     = operands[1];
+  rtx op2     = operands[2];
+  rtx op3     = operands[3];
+  rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, 4);
+  rtx src_si  = simplify_gen_subreg (SImode, src, DImode, 4);
+  rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, 4);
+  rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, 4);
+
+  emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
+  emit_insn (gen_bswapsi2 (dest_si, src_si));
+  emit_insn (gen_bswapsi2 (op3_si, op2_si));
+  emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
+  emit_insn (gen_iordi3 (dest, dest, op3));
+}")
+
+(define_insn "bswapdi2_32bit"
+  [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
+	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
+   (clobber (match_scratch:SI 2 "=&b,&b,X"))]
+  "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
+  "#"
+  [(set_attr "length" "16,12,36")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
+   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
+  "!TARGET_POWERPC64 && reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx dest   = operands[0];
+  rtx src    = operands[1];
+  rtx op2    = operands[2];
+  rtx dest_hi = simplify_gen_subreg (SImode, dest, DImode, 0);
+  rtx dest_lo = simplify_gen_subreg (SImode, dest, DImode, 4);
+  rtx addr1;
+  rtx addr2;
+  rtx word_high;
+  rtx word_low;
+
+  addr1 = XEXP (src, 0);
+  if (GET_CODE (addr1) == PLUS)
+    {
+      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+      addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
+    }
+  else
+    {
+      emit_move_insn (op2, GEN_INT (4));
+      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
+    }
+
+  if (BYTES_BIG_ENDIAN)
+    {
+      word_high = change_address (src, SImode, addr1);
+      word_low  = change_address (src, SImode, addr2);
+    }
+  else
+    {
+      word_high = change_address (src, SImode, addr2);
+      word_low  = change_address (src, SImode, addr1);
+    }
+
+  emit_insn (gen_bswapsi2 (dest_hi, word_low));
+  emit_insn (gen_bswapsi2 (dest_lo, word_high));
+}")
+
+(define_split
+  [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
+	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
+   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
+  "!TARGET_POWERPC64 && reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx dest     = operands[0];
+  rtx src      = operands[1];
+  rtx op2      = operands[2];
+  rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0);
+  rtx src_low  = simplify_gen_subreg (SImode, src, DImode, 4);
+  rtx addr1;
+  rtx addr2;
+  rtx word_high;
+  rtx word_low;
+
+  addr1 = XEXP (dest, 0);
+  if (GET_CODE (addr1) == PLUS)
+    {
+      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+      addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
+    }
+  else
+    {
+      emit_move_insn (op2, GEN_INT (4));
+      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
+    }
+
+  if (BYTES_BIG_ENDIAN)
+    {
+      word_high = change_address (dest, SImode, addr1);
+      word_low  = change_address (dest, SImode, addr2);
+    }
+  else
+    {
+      word_high = change_address (dest, SImode, addr2);
+      word_low  = change_address (dest, SImode, addr1);
+    }
+
+  emit_insn (gen_bswapsi2 (word_high, src_low));
+  emit_insn (gen_bswapsi2 (word_low, src_high));
+}")
+
+(define_split
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
+   (clobber (match_operand:SI 2 "" ""))]
+  "!TARGET_POWERPC64 && reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx dest      = operands[0];
+  rtx src       = operands[1];
+  rtx src_high  = simplify_gen_subreg (SImode, src, DImode, 0);
+  rtx src_low   = simplify_gen_subreg (SImode, src, DImode, 4);
+  rtx dest_high = simplify_gen_subreg (SImode, dest, DImode, 0);
+  rtx dest_low  = simplify_gen_subreg (SImode, dest, DImode, 4);
+
+  emit_insn (gen_bswapsi2 (dest_high, src_low));
+  emit_insn (gen_bswapsi2 (dest_low, src_high));
+}")
+
 (define_expand "mulsi3"
   [(use (match_operand:SI 0 "gpc_reg_operand" ""))
    (use (match_operand:SI 1 "gpc_reg_operand" ""))
@@ -2852,7 +3283,7 @@
    {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 +3326,8 @@
    #
    #
    #"
-  [(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 +3347,8 @@
    #
    #
    #"
-  [(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 +3407,8 @@
    #
    #
    #"
-  [(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 +3430,8 @@
    #
    #
    #"
-  [(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 +3562,7 @@
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3156,7 +3591,7 @@
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3281,7 +3716,7 @@
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3310,7 +3745,7 @@
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3961,6 +4396,17 @@
    {rlinm|rlwinm} %0,%1,%h2,0xffffffff"
   [(set_attr "type" "var_shift_rotate,integer")])
 
+(define_insn "*rotlsi3_64"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+  	(zero_extend:DI
+	    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+		       (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
+  "TARGET_64BIT"
+  "@
+   {rlnm|rlwnm} %0,%1,%2,0xffffffff
+   {rlinm|rlwinm} %0,%1,%h2,0xffffffff"
+  [(set_attr "type" "var_shift_rotate,integer")])
+
 (define_insn "*rotlsi3_internal2"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
@@ -4305,6 +4751,17 @@
    {sli|slwi} %0,%1,%h2"
   [(set_attr "type" "var_shift_rotate,shift")])
 
+(define_insn "*ashlsi3_64"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+  	(zero_extend:DI
+	    (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+		       (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
+  "TARGET_POWERPC64"
+  "@
+   {sl|slw} %0,%1,%2
+   {sli|slwi} %0,%1,%h2"
+  [(set_attr "type" "var_shift_rotate,shift")])
+
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
@@ -4542,6 +4999,17 @@
   {sri|srwi} %0,%1,%h2"
   [(set_attr "type" "integer,var_shift_rotate,shift")])
 
+(define_insn "*lshrsi3_64"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+  	(zero_extend:DI
+	    (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
+  "TARGET_POWERPC64"
+  "@
+  {sr|srw} %0,%1,%2
+  {sri|srwi} %0,%1,%h2"
+  [(set_attr "type" "var_shift_rotate,shift")])
+
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
 	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
@@ -4970,6 +5438,17 @@
    {srai|srawi} %0,%1,%h2"
   [(set_attr "type" "var_shift_rotate,shift")])
 
+(define_insn "*ashrsi3_64"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+  	(sign_extend:DI
+	    (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
+  "TARGET_POWERPC64"
+  "@
+   {sra|sraw} %0,%1,%2
+   {srai|srawi} %0,%1,%h2"
+  [(set_attr "type" "var_shift_rotate,shift")])
+
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
@@ -5119,7 +5598,7 @@
   "")
 
 (define_insn_and_split "*extendsfdf2_fpr"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "@
@@ -5142,7 +5621,7 @@
 
 (define_insn "*truncdfsf2_fpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
-	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
+	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
@@ -5303,7 +5782,7 @@
   "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 +5793,7 @@
   [(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 +5802,7 @@
   "{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 +5813,7 @@
   [(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,18 +5822,18 @@
   "{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"))
 			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT"
   "fnmadds %0,%1,%2,%3"
   [(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 +5844,7 @@
   [(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 +5853,7 @@
   "{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,18 +5863,18 @@
   "{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"))
 			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
   "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
-   && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
+   && TARGET_SINGLE_FLOAT"
   "fnmsubs %0,%1,%2,%3"
   [(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 +5885,7 @@
   [(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 +5894,7 @@
   "{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 +5975,18 @@
 	                     (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], CONST0_RTX (DFmode)));
+	 DONE;
+       }
      operands[3] = gen_reg_rtx (DFmode);
      operands[4] = gen_reg_rtx (DFmode);
      operands[5] = CONST0_RTX (DFmode);
@@ -5542,12 +6030,12 @@
   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,31 +6052,33 @@
 ;; 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
+  [(set_attr "type" "isel")
+   (set_attr "length" "4")])
+
+(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")])
+  [(set_attr "type" "isel")
+   (set_attr "length" "4")])
 
 (define_expand "movsfcc"
    [(set (match_operand:SF 0 "gpc_reg_operand" "")
@@ -5616,7 +6106,7 @@
 
 (define_insn "*fseldfsf4"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
-	(if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
+	(if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
 			 (match_operand:SF 2 "gpc_reg_operand" "f")
 			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
@@ -5631,9 +6121,10 @@
   "")
 
 (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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5644,16 +6135,18 @@
   "")
 
 (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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
+  "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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5665,10 +6158,11 @@
   "")
 
 (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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+		 (match_operand:DF 2 "gpc_reg_operand" "d")))]
+  "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")])
@@ -5681,10 +6175,11 @@
   "")
 
 (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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "d")
+		  (match_operand:DF 2 "gpc_reg_operand" "d")))]
+  "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")])
@@ -5697,10 +6192,11 @@
   "")
 
 (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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+		 (match_operand:DF 2 "gpc_reg_operand" "d")))]
+  "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")])
@@ -5715,17 +6211,18 @@
   "")
 
 (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"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(div:DF (match_operand:DF 1 "gpc_reg_operand" "d")
+		(match_operand:DF 2 "gpc_reg_operand" "d")))]
+  "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")])
 
 (define_expand "recipdf3"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")
-		    (match_operand:DF 2 "gpc_reg_operand" "f")]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")
+		    (match_operand:DF 2 "gpc_reg_operand" "d")]
 		   UNSPEC_FRES))]
   "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_POPCNTB && !optimize_size
    && flag_finite_math_only && !flag_trapping_math"
@@ -5734,82 +6231,91 @@
    DONE;
 })
 
-(define_insn "fred"
+(define_expand "fred"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))]
+  "(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"
+  "TARGET_POPCNTB && flag_finite_math_only && !VECTOR_UNIT_VSX_P (DFmode)"
   "fre %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn ""
-  [(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"
+(define_insn "*fmadddf4_fpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+			  (match_operand:DF 2 "gpc_reg_operand" "d"))
+		 (match_operand:DF 3 "gpc_reg_operand" "d")))]
+  "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 ""
-  [(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"
+(define_insn "*fmsubdf4_fpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+			   (match_operand:DF 2 "gpc_reg_operand" "d"))
+		  (match_operand:DF 3 "gpc_reg_operand" "d")))]
+  "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 ""
-  [(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"))))]
+(define_insn "*fnmadddf4_fpr_1"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+				  (match_operand:DF 2 "gpc_reg_operand" "d"))
+			 (match_operand:DF 3 "gpc_reg_operand" "d"))))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
-   && 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 ""
-  [(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")))]
+(define_insn "*fnmadddf4_fpr_2"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d"))
+			   (match_operand:DF 2 "gpc_reg_operand" "d"))
+		  (match_operand:DF 3 "gpc_reg_operand" "d")))]
   "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 ""
-  [(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"))))]
+(define_insn "*fnmsubdf4_fpr_1"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+				   (match_operand:DF 2 "gpc_reg_operand" "d"))
+			  (match_operand:DF 3 "gpc_reg_operand" "d"))))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
-   && 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 ""
-  [(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"))))]
+(define_insn "*fnmsubdf4_fpr_2"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(minus:DF (match_operand:DF 3 "gpc_reg_operand" "d")
+	          (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
+			   (match_operand:DF 2 "gpc_reg_operand" "d"))))]
   "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 "sqrtdf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
   "(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")])
 
@@ -5865,21 +6371,21 @@
 }")
 
 (define_insn "*fseldfdf4"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
 			     (match_operand:DF 4 "zero_fp_constant" "F"))
-			 (match_operand:DF 2 "gpc_reg_operand" "f")
-			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
+			 (match_operand:DF 2 "gpc_reg_operand" "d")
+			 (match_operand:DF 3 "gpc_reg_operand" "d")))]
   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
 (define_insn "*fselsfdf4"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
 	(if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
 			     (match_operand:SF 4 "zero_fp_constant" "F"))
-			 (match_operand:DF 2 "gpc_reg_operand" "f")
-			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
+			 (match_operand:DF 2 "gpc_reg_operand" "d")
+			 (match_operand:DF 3 "gpc_reg_operand" "d")))]
   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
@@ -5898,6 +6404,18 @@
  "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,
@@ -5935,16 +6453,16 @@
 }")
 
 (define_insn_and_split "*floatsidf2_internal"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
 	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
-   (use (match_operand:DF 3 "gpc_reg_operand" "f"))
+   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
-   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
-  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
+  ""
   [(pc)]
   "
 {
@@ -6003,15 +6521,15 @@
 }")
 
 (define_insn_and_split "*floatunssidf2_internal"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
 	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
-   (use (match_operand:DF 3 "gpc_reg_operand" "f"))
+   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
-   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
+   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "#"
-  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
+  ""
   [(pc)]
   "
 {
@@ -6072,13 +6590,13 @@
 
 (define_insn_and_split "*fix_truncdfsi2_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
+	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
+   (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 
    && TARGET_DOUBLE_FLOAT"
   "#"
-  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
+  ""
   [(pc)]
   "
 {
@@ -6095,8 +6613,8 @@
 
 (define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
   [(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"))]
+	(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"
@@ -6113,8 +6631,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" "f")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
+	(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"
@@ -6131,32 +6649,46 @@
 ; because the first makes it clear that operand 0 is not live
 ; before the instruction.
 (define_insn "fctiwz"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
-	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(unspec:DI [(fix:SI (match_operand:DF 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_insn "btruncdf2"
+(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"
+  "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"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
+(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_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"
   [(set_attr "type" "fp")])
 
@@ -6167,10 +6699,17 @@
   "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))]
+(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_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")])
 
@@ -6181,9 +6720,10 @@
   "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))]
+  [(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")])
@@ -6195,10 +6735,16 @@
   "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")
-	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")]
+	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
 		   UNSPEC_STFIWX))]
   "TARGET_PPC_GFXOPT"
   "stfiwx %1,%y0"
@@ -6210,17 +6756,41 @@
   "TARGET_HARD_FLOAT && !TARGET_FPRS"
   "")
 
-(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_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
+(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" "=d")
+	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))]
+  "(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"
-  [(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"
+(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" "=!d#r")
+	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))]
+  "(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")])
 
@@ -6247,8 +6817,8 @@
 ;; from double rounding.
 (define_insn_and_split "floatdisf2_internal1"
   [(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"))]
+        (float:SF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))
+   (clobber (match_scratch:DF 2 "=d"))]
   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "#"
   "&& reload_completed"
@@ -6649,11 +7219,24 @@
 
 ;; PowerPC64 DImode operations.
 
-(define_insn_and_split "absdi2"
+(define_expand "absdi2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	(abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
+  "TARGET_POWERPC64"
+  "
+{
+  if (TARGET_ISEL)
+    emit_insn (gen_absdi2_isel (operands[0], operands[1]));
+  else
+    emit_insn (gen_absdi2_internal (operands[0], operands[1]));
+  DONE;
+}")
+
+(define_insn_and_split "absdi2_internal"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
         (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
    (clobber (match_scratch:DI 2 "=&r,&r"))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && !TARGET_ISEL"
   "#"
   "&& reload_completed"
   [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
@@ -6665,7 +7248,7 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
         (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
    (clobber (match_scratch:DI 2 "=&r,&r"))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && !TARGET_ISEL"
   "#"
   "&& reload_completed"
   [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
@@ -7609,7 +8192,7 @@
    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 +8250,9 @@
    #
    #
    #"
-  [(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 +8303,9 @@
    #
    #
    #"
-  [(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 +8445,7 @@
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7887,7 +8474,7 @@
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7958,7 +8545,7 @@
   "@
    %q4. %3,%2,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7987,7 +8574,7 @@
   "@
    %q4. %0,%2,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -8024,7 +8611,7 @@
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -8053,7 +8640,7 @@
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -8070,6 +8657,51 @@
 	(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.
 
@@ -8143,8 +8775,8 @@
 (define_insn "*movsi_internal1"
   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h")
 	(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))]
-  "gpc_reg_operand (operands[0], SImode)
-   || gpc_reg_operand (operands[1], SImode)"
+  "!TARGET_SINGLE_FPU &&
+   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
   "@
    mr %0,%1
    {cal|la} %0,%a1
@@ -8162,6 +8794,30 @@
   [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
 
+(define_insn "*movsi_internal1_single"
+  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h,m,*f")
+        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0,f,m"))]
+  "TARGET_SINGLE_FPU &&
+   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
+  "@
+   mr %0,%1
+   {cal|la} %0,%a1
+   {l%U1%X1|lwz%U1%X1} %0,%1
+   {st%U0%X0|stw%U0%X0} %1,%0
+   {lil|li} %0,%1
+   {liu|lis} %0,%v1
+   #
+   {cal|la} %0,%a1
+   mf%1 %0
+   mt%0 %1
+   mt%0 %1
+   mt%0 %1
+   {cror 0,0,0|nop}
+   stfs%U0%X0 %1, %0
+   lfs%U1%X1 %0, %1"
+  [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*,*,*")
+   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4,4,4")])
+
 ;; Split a load of a large constant into the appropriate two-insn
 ;; sequence.
 
@@ -8473,8 +9129,8 @@
 ;; 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,d,d,m,wa,!r,!r,!r")
+	(match_operand:DF 1 "input_operand" "r,m,r,ws,wa,Z,Z,ws,wa,d,m,d,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))"
@@ -8553,25 +9209,36 @@
 	  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")
 	(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
   "! TARGET_POWERPC64 
-   && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) 
+   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
@@ -8613,19 +9280,26 @@
 ; 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,d,d,m,wa,*c*l,!r,*h,!r,!r,!r,r,d")
+	(match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F,d,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}
@@ -8634,33 +9308,40 @@
    #
    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,d,d,m,wa,*c*l,!r,*h,!r,!r,!r")
+	(match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,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")
@@ -8691,8 +9372,8 @@
 ; otherwise reload, given m->f, will try to pick f->f and reload it,
 ; which doesn't make progress.  Likewise r->Y must be before r->r.
 (define_insn_and_split "*movtf_internal"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r")
-	(match_operand:TF 1 "input_operand"         "f,o,f,YGHF,r,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,d,d,r,Y,r")
+	(match_operand:TF 1 "input_operand"         "d,o,d,YGHF,r,r"))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
    && (gpc_reg_operand (operands[0], TFmode)
@@ -8746,9 +9427,9 @@
 })
 
 (define_insn_and_split "*extenddftf2_internal"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
-       (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
-   (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,d,&d,r")
+       (float_extend:TF (match_operand:DF 1 "input_operand" "dr,md,md,rmGHF")))
+   (use (match_operand:DF 2 "zero_reg_mem_operand" "rd,m,d,n"))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && TARGET_LONG_DOUBLE_128"
@@ -8789,8 +9470,8 @@
   "")
 
 (define_insn_and_split "trunctfdf2_internal1"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
-	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
+	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "@
@@ -8805,8 +9486,8 @@
   [(set_attr "type" "fp")])
 
 (define_insn "trunctfdf2_internal2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && TARGET_LONG_DOUBLE_128"
@@ -8831,8 +9512,8 @@
 
 (define_insn_and_split "trunctfsf2_fprs"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
-	(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
-   (clobber (match_scratch:DF 2 "=f"))]
+	(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
+   (clobber (match_scratch:DF 2 "=d"))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
    && TARGET_LONG_DOUBLE_128"
@@ -8861,10 +9542,10 @@
 ; fadd, but rounding towards zero.
 ; This is probably not the optimal code sequence.
 (define_insn "fix_trunc_helper"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
 		   UNSPEC_FIX_TRUNC_TF))
-   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
+   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
   "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")
@@ -8905,15 +9586,15 @@
 
 (define_insn_and_split "*fix_trunctfsi2_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-        (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
-   (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
-   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
-   (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
+        (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
+   (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
+   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
+   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
-  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[5]))"
+  ""
   [(pc)]
 {
   rtx lowword;
@@ -8938,8 +9619,8 @@
   "")
 
 (define_insn "negtf2_internal"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
-	(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
+	(neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "*
@@ -9004,8 +9685,8 @@
 ; List r->r after r->"o<>", otherwise reload will try to reload a
 ; non-offsettable address by using r->r which won't make progress.
 (define_insn "*movdi_internal32"
-  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
-	(match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))]
+  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*d,*d,m,r")
+	(match_operand:DI 1 "input_operand" "r,r,m,d,m,d,IJKnGHF"))]
   "! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
@@ -9049,8 +9730,8 @@
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_insn "*movdi_mfpgpr"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h,r,*f")
-	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0,*f,r"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,r,*d")
+	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,*d,r"))]
   "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
@@ -9074,8 +9755,8 @@
    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")])
 
 (define_insn "*movdi_internal64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h")
-	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h")
+	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0"))]
   "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS)
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
@@ -9237,15 +9918,16 @@
 (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" "*,load,store")])
+  [(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))]
   "
@@ -9271,7 +9953,7 @@
 (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; })
@@ -10269,7 +10951,7 @@
   [(set_attr "type" "store_ux,store_u")])
 
 (define_insn "*movdf_update1"
-  [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
+  [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
 	(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
@@ -10285,7 +10967,7 @@
 (define_insn "*movdf_update2"
   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
-	(match_operand:DF 3 "gpc_reg_operand" "f,f"))
+	(match_operand:DF 3 "gpc_reg_operand" "d,d"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
@@ -10374,7 +11056,7 @@
 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
 
-(define_insn "tls_gd_aix<TLSmode:tls_abi_suffix>"
+(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
 	      (match_operand 4 "" "g")))
@@ -10384,10 +11066,21 @@
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
   "addi %0,%1,%2@got@tlsgd\;bl %z3\;%."
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)
+			 (match_dup 2)]
+			UNSPEC_TLSGD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 3))
+		   	 (match_dup 4)))
+	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "type" "two")
    (set_attr "length" "12")])
 
-(define_insn "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
+(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
 	      (match_operand 4 "" "g")))
@@ -10407,10 +11100,62 @@
   else
     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
 }
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)
+			 (match_dup 2)]
+			UNSPEC_TLSGD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 3))
+		   	 (match_dup 4)))
+	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
-(define_insn "tls_ld_aix<TLSmode:tls_abi_suffix>"
+(define_insn "*tls_gd<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+			UNSPEC_TLSGD))]
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
+  "addi %0,%1,%2@got@tlsgd"
+  [(set_attr "length" "4")])
+
+(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
+		   UNSPEC_TLSGD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "bl %z1(%3@tlsgd)\;%."
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
+
+(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
+		   UNSPEC_TLSGD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
+{
+  if (flag_pic)
+    {
+      if (TARGET_SECURE_PLT && flag_pic == 2)
+	return "bl %z1+32768(%3@tlsgd)@plt";
+      return "bl %z1(%3@tlsgd)@plt";
+    }
+  return "bl %z1(%3@tlsgd)";
+}
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
+(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
 	      (match_operand 3 "" "g")))
@@ -10419,9 +11164,19 @@
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
   "addi %0,%1,%&@got@tlsld\;bl %z2\;%."
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)]
+			UNSPEC_TLSLD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 2))
+		   	 (match_dup 3)))
+	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "length" "12")])
 
-(define_insn "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
+(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
 	      (match_operand 3 "" "g")))
@@ -10440,8 +11195,56 @@
   else
     return "addi %0,%1,%&@got@tlsld\;bl %z2";
 }
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)]
+			UNSPEC_TLSLD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 2))
+		   	 (match_dup 3)))
+	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "length" "8")])
 
+(define_insn "*tls_ld<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
+			UNSPEC_TLSLD))]
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
+  "addi %0,%1,%&@got@tlsld"
+  [(set_attr "length" "4")])
+
+(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "bl %z1(%&@tlsld)\;%."
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
+
+(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
+{
+  if (flag_pic)
+    {
+      if (TARGET_SECURE_PLT && flag_pic == 2)
+	return "bl %z1+32768(%&@tlsld)@plt";
+      return "bl %z1(%&@tlsld)@plt";
+    }
+  return "bl %z1(%&@tlsld)";
+}
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
 	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
@@ -11776,267 +12579,103 @@
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
   ""
   "")
+
+(define_insn "probe_stack"
+  [(set (match_operand 0 "memory_operand" "=m")
+        (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
+  ""
+  "{st%U0%X0|stw%U0%X0} 0,%0"
+  [(set_attr "type" "store")
+   (set_attr "length" "4")])
 
 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
 ;; signed & unsigned, and one type of branch.
 ;;
 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
-;; insns, and branches.  We store the operands of compares until we see
-;; how it is used.
-(define_expand "cmp<mode>"
-  [(set (cc0)
-        (compare (match_operand:GPR 0 "gpc_reg_operand" "")
-  		 (match_operand:GPR 1 "reg_or_short_operand" "")))]
-  ""
-  "
-{
-  /* Take care of the possibility that operands[1] might be negative but
+;; insns, and branches.
+
+(define_expand "cbranch<mode>4"
+  [(use (match_operator 0 "rs6000_cbranch_operator"
+         [(match_operand:GPR 1 "gpc_reg_operand" "")
+          (match_operand:GPR 2 "reg_or_short_operand" "")]))
+   (use (match_operand 3 ""))]
+  ""
+  "
+{
+  /* Take care of the possibility that operands[2] might be negative but
      this might be a logical operation.  That insn doesn't exist.  */
-  if (GET_CODE (operands[1]) == CONST_INT
-      && INTVAL (operands[1]) < 0)
-    operands[1] = force_reg (<MODE>mode, operands[1]);
-
-  rs6000_compare_op0 = operands[0];
-  rs6000_compare_op1 = operands[1];
-  rs6000_compare_fp_p = 0;
+  if (GET_CODE (operands[2]) == CONST_INT
+      && INTVAL (operands[2]) < 0)
+    {
+      operands[2] = force_reg (<MODE>mode, operands[2]);
+      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
+				    GET_MODE (operands[0]),
+				    operands[1], operands[2]);
+   }
+
+  rs6000_emit_cbranch (<MODE>mode, operands);
   DONE;
 }")
 
-(define_expand "cmp<mode>"
-  [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "")
-		       (match_operand:FP 1 "gpc_reg_operand" "")))]
-  ""
-  "
-{
-  rs6000_compare_op0 = operands[0];
-  rs6000_compare_op1 = operands[1];
-  rs6000_compare_fp_p = 1;
+(define_expand "cbranch<mode>4"
+  [(use (match_operator 0 "rs6000_cbranch_operator"
+         [(match_operand:FP 1 "gpc_reg_operand" "")
+          (match_operand:FP 2 "gpc_reg_operand" "")]))
+   (use (match_operand 3 ""))]
+  ""
+  "
+{
+  rs6000_emit_cbranch (<MODE>mode, operands);
   DONE;
 }")
 
-(define_expand "beq"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }")
-
-(define_expand "bne"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }")
-
-(define_expand "bge"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }")
-
-(define_expand "bgt"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }")
-
-(define_expand "ble"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }")
-
-(define_expand "blt"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }")
-
-(define_expand "bgeu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }")
-
-(define_expand "bgtu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }")
-
-(define_expand "bleu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }")
-
-(define_expand "bltu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }")
-
-(define_expand "bunordered"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "bordered"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
-
-(define_expand "buneq"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
-
-(define_expand "bunge"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
-
-(define_expand "bungt"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
-
-(define_expand "bunle"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
-
-(define_expand "bunlt"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
-
-(define_expand "bltgt"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
-
-;; For SNE, we would prefer that the xor/abs sequence be used for integers.
-;; For SEQ, likewise, except that comparisons with zero should be done
-;; with an scc insns.  However, due to the order that combine see the
-;; resulting insns, we must, in fact, allow SEQ for integers.  Fail in
-;; the cases we don't want to handle.
-(define_expand "seq"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }")
-
-(define_expand "sne"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p)
+(define_expand "cstore<mode>4"
+  [(use (match_operator 1 "rs6000_cbranch_operator"
+         [(match_operand:GPR 2 "gpc_reg_operand" "")
+          (match_operand:GPR 3 "reg_or_short_operand" "")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
+  ""
+  "
+{
+  /* Take care of the possibility that operands[3] might be negative but
+     this might be a logical operation.  That insn doesn't exist.  */
+  if (GET_CODE (operands[3]) == CONST_INT
+      && INTVAL (operands[3]) < 0)
+    {
+      operands[3] = force_reg (<MODE>mode, operands[3]);
+      operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
+				    GET_MODE (operands[1]),
+				    operands[2], operands[3]);
+    }
+
+  /* For SNE, we would prefer that the xor/abs sequence be used for integers.
+     For SEQ, likewise, except that comparisons with zero should be done
+     with an scc insns.  However, due to the order that combine see the
+     resulting insns, we must, in fact, allow SEQ for integers.  Fail in
+     the cases we don't want to handle or are best handled by portable
+     code.  */
+  if (GET_CODE (operands[1]) == NE)
     FAIL;
-
-  rs6000_emit_sCOND (NE, operands[0]);
+  if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
+       || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
+      && operands[3] == const0_rtx)
+    FAIL;
+  rs6000_emit_sCOND (<MODE>mode, operands);
   DONE;
 }")
 
-;; A >= 0 is best done the portable way for A an integer.
-(define_expand "sge"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
-    FAIL;
-
-  rs6000_emit_sCOND (GE, operands[0]);
-  DONE;
-}")
-
-;; A > 0 is best done using the portable sequence, so fail in that case.
-(define_expand "sgt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
-    FAIL;
-
-  rs6000_emit_sCOND (GT, operands[0]);
-  DONE;
-}")
-
-;; A <= 0 is best done the portable way for A an integer.
-(define_expand "sle"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
-    FAIL;
-
-  rs6000_emit_sCOND (LE, operands[0]);
-  DONE;
-}")
-
-;; A < 0 is best done in the portable way for A an integer.
-(define_expand "slt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
-    FAIL;
-
-  rs6000_emit_sCOND (LT, operands[0]);
+(define_expand "cstore<mode>4"
+  [(use (match_operator 1 "rs6000_cbranch_operator"
+         [(match_operand:FP 2 "gpc_reg_operand" "")
+          (match_operand:FP 3 "gpc_reg_operand" "")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
+  ""
+  "
+{
+  rs6000_emit_sCOND (<MODE>mode, operands);
   DONE;
 }")
 
-(define_expand "sgeu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
-
-(define_expand "sgtu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
-
-(define_expand "sleu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
-
-(define_expand "sltu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
-
-(define_expand "sunordered"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "sordered"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
-
-(define_expand "suneq"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
-
-(define_expand "sunge"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
-
-(define_expand "sungt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
-
-(define_expand "sunle"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
-
-(define_expand "sunlt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
-
-(define_expand "sltgt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
 
 (define_expand "stack_protect_set"
   [(match_operand 0 "memory_operand" "")
@@ -12079,16 +12718,16 @@
    (match_operand 2 "" "")]
   ""
 {
+  rtx test, op0, op1;
 #ifdef TARGET_THREAD_SSP_OFFSET
   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
   operands[1] = gen_rtx_MEM (Pmode, addr);
 #endif
-  rs6000_compare_op0 = operands[0];
-  rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
-				       UNSPEC_SP_TEST);
-  rs6000_compare_fp_p = 0;
-  emit_jump_insn (gen_beq (operands[2]));
+  op0 = operands[0];
+  op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
+  test = gen_rtx_EQ (VOIDmode, op0, op1);
+  emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
   DONE;
 })
 
@@ -12242,17 +12881,18 @@
 
 (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"
+	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d")
+		      (match_operand:DF 2 "gpc_reg_operand" "d")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && !VECTOR_UNIT_VSX_P (DFmode)"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
 ;; Only need to compare second words if first words equal
 (define_insn "*cmptf_internal1"
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
-	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
-		      (match_operand:TF 2 "gpc_reg_operand" "f")))]
+	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
+		      (match_operand:TF 2 "gpc_reg_operand" "d")))]
   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
@@ -12261,16 +12901,16 @@
 
 (define_insn_and_split "*cmptf_internal2"
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
-	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
-		      (match_operand:TF 2 "gpc_reg_operand" "f")))
-    (clobber (match_scratch:DF 3 "=f"))
-    (clobber (match_scratch:DF 4 "=f"))
-    (clobber (match_scratch:DF 5 "=f"))
-    (clobber (match_scratch:DF 6 "=f"))
-    (clobber (match_scratch:DF 7 "=f"))
-    (clobber (match_scratch:DF 8 "=f"))
-    (clobber (match_scratch:DF 9 "=f"))
-    (clobber (match_scratch:DF 10 "=f"))]
+	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
+		      (match_operand:TF 2 "gpc_reg_operand" "d")))
+    (clobber (match_scratch:DF 3 "=d"))
+    (clobber (match_scratch:DF 4 "=d"))
+    (clobber (match_scratch:DF 5 "=d"))
+    (clobber (match_scratch:DF 6 "=d"))
+    (clobber (match_scratch:DF 7 "=d"))
+    (clobber (match_scratch:DF 8 "=d"))
+    (clobber (match_scratch:DF 9 "=d"))
+    (clobber (match_scratch:DF 10 "=d"))]
   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "#"
@@ -14659,17 +15299,16 @@
   "{t 31,0,0|trap}"
   [(set_attr "type" "trap")])
 
-(define_expand "conditional_trap"
-  [(trap_if (match_operator 0 "trap_comparison_operator"
-			    [(match_dup 2) (match_dup 3)])
-	    (match_operand 1 "const_int_operand" ""))]
-  ""
-  "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
-   operands[2] = rs6000_compare_op0;
-   operands[3] = rs6000_compare_op1;")
-
-(define_insn ""
-  [(trap_if (match_operator 0 "trap_comparison_operator"
+(define_expand "ctrap<mode>4"
+  [(trap_if (match_operator 0 "ordered_comparison_operator"
+			    [(match_operand:GPR 1 "register_operand")
+			     (match_operand:GPR 2 "reg_or_short_operand")])
+	    (match_operand 3 "zero_constant" ""))]
+  ""
+  "")
+
+(define_insn ""
+  [(trap_if (match_operator 0 "ordered_comparison_operator"
                             [(match_operand:GPR 1 "register_operand" "r")
                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
 	    (const_int 0))]
@@ -14736,7 +15375,7 @@
 		    (set (match_operand:P 3 "memory_operand" "=m")
 			 (match_operand:P 4 "gpc_reg_operand" "r"))])]
   ""
-  "bl %z1"
+  "bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -14746,9 +15385,9 @@
 		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
                     (use (match_operand:P 2 "gpc_reg_operand" "r"))
 		    (set (match_operand:DF 3 "memory_operand" "=m")
-			 (match_operand:DF 4 "gpc_reg_operand" "f"))])]
-  ""
-  "bl %z1"
+			 (match_operand:DF 4 "gpc_reg_operand" "d"))])]
+  ""
+  "bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -14843,7 +15482,7 @@
 		   (set (match_operand:P 4 "gpc_reg_operand" "=r")
 			(match_operand:P 5 "memory_operand" "m"))])]
  ""
- "bl %z2"
+ "bl %2"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
@@ -14856,7 +15495,7 @@
 		   (set (match_operand:P 4 "gpc_reg_operand" "=r")
 			(match_operand:P 5 "memory_operand" "m"))])]
  ""
- "b %z2"
+ "b %2"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
@@ -14866,10 +15505,23 @@
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (match_operand:P 3 "gpc_reg_operand" "r"))
-		   (set (match_operand:DF 4 "gpc_reg_operand" "=f")
+		   (set (match_operand:DF 4 "gpc_reg_operand" "=d")
 			(match_operand:DF 5 "memory_operand" "m"))])]
  ""
- "b %z2"
+ "b %2"
+ [(set_attr "type" "branch")
+  (set_attr "length" "4")])
+
+(define_insn "*return_and_restore_fpregs_aix_<mode>"
+ [(match_parallel 0 "any_parallel_operand"
+		  [(return)
+		   (use (match_operand:P 1 "register_operand" "l"))
+		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
+		   (use (match_operand:P 3 "gpc_reg_operand" "r"))
+		   (set (match_operand:DF 4 "gpc_reg_operand" "=d")
+			(match_operand:DF 5 "memory_operand" "m"))])]
+ ""
+ "b %2"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
@@ -14918,8 +15570,19 @@
 }"
   [(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")