diff gcc/config/rs6000/rs6000.md @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents ab0bcb71f44d 84e7813d76e9
children 351920fa3827
line wrap: on
line diff
--- a/gcc/config/rs6000/rs6000.md	Thu Oct 25 08:08:40 2018 +0900
+++ b/gcc/config/rs6000/rs6000.md	Thu Oct 25 10:21:07 2018 +0900
@@ -1,5 +1,5 @@
 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
-;; Copyright (C) 1990-2017 Free Software Foundation, Inc.
+;; Copyright (C) 1990-2018 Free Software Foundation, Inc.
 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 ;; This file is part of GCC.
@@ -130,16 +130,13 @@
    UNSPEC_CDTBCD
    UNSPEC_CBCDTD
    UNSPEC_DIVE
-   UNSPEC_DIVEO
    UNSPEC_DIVEU
-   UNSPEC_DIVEUO
    UNSPEC_UNPACK_128BIT
    UNSPEC_PACK_128BIT
    UNSPEC_LSQ
    UNSPEC_FUSION_GPR
    UNSPEC_STACK_CHECK
    UNSPEC_FUSION_P9
-   UNSPEC_FUSION_ADDIS
    UNSPEC_ADD_ROUND_TO_ODD
    UNSPEC_SUB_ROUND_TO_ODD
    UNSPEC_MUL_ROUND_TO_ODD
@@ -166,8 +163,15 @@
    UNSPECV_MFTB			; move from time base
    UNSPECV_NLGR			; non-local goto receiver
    UNSPECV_MFFS			; Move from FPSCR
-   UNSPECV_MTFSF		; Move to FPSCR Fields
+   UNSPECV_MFFSL		; Move from FPSCR light instruction version
+   UNSPECV_MFFSCRN		; Move from FPSCR float rounding mode
+   UNSPECV_MFFSCDRN		; Move from FPSCR decimal float rounding mode
+   UNSPECV_MTFSF		; Move to FPSCR Fields 8 to 15
+   UNSPECV_MTFSF_HI		; Move to FPSCR Fields 0 to 7
+   UNSPECV_MTFSB0		; Set FPSCR Field bit to 0
+   UNSPECV_MTFSB1		; Set FPSCR Field bit to 1
    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
+   UNSPECV_SPEC_BARRIER         ; Speculation barrier
   ])
 
 
@@ -181,8 +185,8 @@
    load,store,fpload,fpstore,vecload,vecstore,
    cmp,
    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
-   cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
-   fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
+   cr_logical,mfcr,mfcrf,mtcr,
+   fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
    veclogical,veccmpfx,vecexts,vecmove,
@@ -205,6 +209,9 @@
 ;; This is used for load insns.
 (define_attr "sign_extend" "no,yes" (const_string "no"))
 
+;; Does this cr_logical instruction have three operands?  That is, BT != BB.
+(define_attr "cr_logical_3op" "no,yes" (const_string "no"))
+
 ;; Does this instruction use indexed (that is, reg+reg) addressing?
 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
 ;; it is automatically set based on that.  If a load or store instruction
@@ -242,21 +249,8 @@
 ;; Is copying of this instruction disallowed?
 (define_attr "cannot_copy" "no,yes" (const_string "no"))
 
-;; Define floating point instruction sub-types for use with Xfpu.md
-(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
-
-;; Length (in bytes).
-; '(pc)' in the following doesn't include the instruction itself; it is
-; calculated as if the instruction had zero size.
-(define_attr "length" ""
-  (if_then_else (eq_attr "type" "branch")
-		(if_then_else (and (ge (minus (match_dup 0) (pc))
-				       (const_int -32768))
-				   (lt (minus (match_dup 0) (pc))
-				       (const_int 32764)))
-			      (const_int 4)
-			      (const_int 8))
-		(const_int 4)))
+;; Length of the instruction (in bytes).
+(define_attr "length" "" (const_int 4))
 
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000-opts.h.
@@ -267,7 +261,7 @@
    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
    power4,power5,power6,power7,power8,power9,
    rs64a,mpccore,cell,ppca2,titan"
-  (const (symbol_ref "rs6000_cpu_attr")))
+  (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
 
 
 ;; If this instruction is microcoded on the CELL processor
@@ -307,7 +301,6 @@
 (include "power8.md")
 (include "power9.md")
 (include "cell.md")
-(include "xfpu.md")
 (include "a2.md")
 (include "titan.md")
 
@@ -323,6 +316,9 @@
 ; of whole values in GPRs.
 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
 
+; And again, for patterns that need two (potentially) different integer modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
+
 ; Any supported integer mode.
 (define_mode_iterator INT [QI HI SI DI TI PTI])
 
@@ -376,8 +372,8 @@
 
 ; Any hardware-supported floating-point mode
 (define_mode_iterator FP [
-  (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
-  (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
+  (SF "TARGET_HARD_FLOAT")
+  (DF "TARGET_HARD_FLOAT")
   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
   (KF "TARGET_FLOAT128_TYPE")
@@ -386,10 +382,8 @@
 
 ; Any fma capable floating-point mode.
 (define_mode_iterator FMA_F [
-  (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
-  (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
-       || VECTOR_UNIT_VSX_P (DFmode)")
-  (V2SF "TARGET_PAIRED_FLOAT")
+  (SF "TARGET_HARD_FLOAT")
+  (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
@@ -423,6 +417,12 @@
 ; Iterator for 128-bit VSX types for pack/unpack
 (define_mode_iterator FMOVE128_VSX [V1TI KF])
 
+; Iterators for converting to/from TFmode
+(define_mode_iterator IFKF [IF KF])
+
+; Constraints for moving IF/KFmode.
+(define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
+
 ; Whether a floating point move is ok, don't allow SD without hardware FP
 (define_mode_attr fmove_ok [(SF "")
 			    (DF "")
@@ -513,7 +513,7 @@
 ; SF/DF constraint for arithmetic on altivec registers
 (define_mode_attr Fa		[(SF "wu") (DF "wv")])
 
-; s/d suffix for things like fp_addsub_s/fp_addsub_d
+; s/d suffix for things like sdiv/ddiv
 (define_mode_attr Fs		[(SF "s")  (DF "d")])
 
 ; FRE/FRES support
@@ -543,7 +543,7 @@
 (define_code_attr su [(sign_extend	"s")
 		      (zero_extend	"u")
 		      (fix		"s")
-		      (unsigned_fix	"s")
+		      (unsigned_fix	"u")
 		      (float		"s")
 		      (unsigned_float	"u")])
 
@@ -614,9 +614,6 @@
 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
 				 (DF "TARGET_FCFID")])
 
-(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
-				(DF "TARGET_DOUBLE_FLOAT")])
-
 ;; Mode iterator for logical operations on 128-bit types
 (define_mode_iterator BOOL_128		[TI
 					 PTI
@@ -997,7 +994,7 @@
 		     "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
 
 	(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
-		     "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
+		     "YZ, r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
   ""
   "@
    lwa%U1%X1 %0,%1
@@ -1037,7 +1034,7 @@
   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
 
-  if (VECTOR_ELT_ORDER_BIG)
+  if (BYTES_BIG_ENDIAN)
     {
       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
@@ -1569,12 +1566,12 @@
   "dlmzb. %0,%1,%2")
 
 (define_expand "strlensi"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-        (unspec:SI [(match_operand:BLK 1 "general_operand" "")
-                    (match_operand:QI 2 "const_int_operand" "")
-                    (match_operand 3 "const_int_operand" "")]
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+        (unspec:SI [(match_operand:BLK 1 "general_operand")
+                    (match_operand:QI 2 "const_int_operand")
+                    (match_operand 3 "const_int_operand")]
                    UNSPEC_DLMZB_STRLEN))
-   (clobber (match_scratch:CC 4 "=x"))]
+   (clobber (match_scratch:CC 4))]
   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
 {
   rtx result = operands[0];
@@ -1623,9 +1620,9 @@
 ;; Fixed-point arithmetic insns.
 
 (define_expand "add<mode>3"
-  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
-	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
-		  (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
+  [(set (match_operand:SDI 0 "gpc_reg_operand")
+	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
+		  (match_operand:SDI 2 "reg_or_add_cint_operand")))]
   ""
 {
   if (<MODE>mode == DImode && !TARGET_POWERPC64)
@@ -1798,9 +1795,9 @@
 ;; add should be last in case the result gets used in an address.
 
 (define_split
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
-		  (match_operand:GPR 2 "non_add_cint_operand" "")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
+		  (match_operand:GPR 2 "non_add_cint_operand")))]
   ""
   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
@@ -1912,6 +1909,16 @@
   "adde %0,%1,%2"
   [(set_attr "type" "add")])
 
+(define_insn "*add<mode>3_carry_in_internal2"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+			    (reg:GPR CA_REGNO))
+		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "adde %0,%1,%2"
+  [(set_attr "type" "add")])
+
 (define_insn "add<mode>3_carry_in_0"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
 	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
@@ -1933,8 +1940,8 @@
 
 
 (define_expand "one_cmpl<mode>2"
-  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
-	(not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:SDI 0 "gpc_reg_operand")
+	(not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
   ""
 {
   if (<MODE>mode == DImode && !TARGET_POWERPC64)
@@ -1993,9 +2000,9 @@
 
 
 (define_expand "sub<mode>3"
-  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
-	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
-		   (match_operand:SDI 2 "gpc_reg_operand" "")))]
+  [(set (match_operand:SDI 0 "gpc_reg_operand")
+	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
+		   (match_operand:SDI 2 "gpc_reg_operand")))]
   ""
 {
   if (<MODE>mode == DImode && !TARGET_POWERPC64)
@@ -2321,8 +2328,8 @@
 
 
 (define_expand "popcount<mode>2"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
   "TARGET_POPCNTB || TARGET_POPCNTD"
 {
   rs6000_emit_popcount (operands[0], operands[1]);
@@ -2346,8 +2353,8 @@
 
 
 (define_expand "parity<mode>2"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
   "TARGET_POPCNTB"
 {
   rs6000_emit_parity (operands[0], operands[1]);
@@ -2377,8 +2384,7 @@
 	 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
   "TARGET_POWERPC64"
   "l<wd>brx %0,%y1"
-  [(set_attr "length" "4")
-   (set_attr "type" "load")])
+  [(set_attr "type" "load")])
 
 (define_insn "*bswaphi2_extendsi"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -2386,8 +2392,7 @@
 	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
   ""
   "lhbrx %0,%y1"
-  [(set_attr "length" "4")
-   (set_attr "type" "load")])
+  [(set_attr "type" "load")])
 
 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
 ;; the register allocator from converting a gpr<-gpr swap into a store and then
@@ -2429,13 +2434,15 @@
   [(set_attr "type" "store")])
 
 (define_insn_and_split "bswaphi2_reg"
-  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
+  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
 	(bswap:HI
-	 (match_operand:HI 1 "gpc_reg_operand" "r")))
-   (clobber (match_scratch:SI 2 "=&r"))]
-  ""
-  "#"
-  "reload_completed"
+	 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
+   (clobber (match_scratch:SI 2 "=&r,X"))]
+  ""
+  "@
+   #
+   xxbrh %x0,%x1"
+  "reload_completed && int_reg_operand (operands[0], HImode)"
   [(set (match_dup 3)
 	(and:SI (lshiftrt:SI (match_dup 4)
 			     (const_int 8))
@@ -2451,18 +2458,20 @@
   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
 }
-  [(set_attr "length" "12")
-   (set_attr "type" "*")])
+  [(set_attr "length" "12,4")
+   (set_attr "type" "*,vecperm")])
 
 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
 ;; zero_extract insns do not change for -mlittle.
 (define_insn_and_split "bswapsi2_reg"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
 	(bswap:SI
-	 (match_operand:SI 1 "gpc_reg_operand" "r")))]
-  ""
-  "#"
-  "reload_completed"
+	 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
+  ""
+  "@
+   #
+   xxbrw %x0,%x1"
+  "reload_completed && int_reg_operand (operands[0], SImode)"
   [(set (match_dup 0)					; DABC
 	(rotate:SI (match_dup 1)
 		   (const_int 24)))
@@ -2478,18 +2487,20 @@
 			(const_int 255))
 		(and:SI (match_dup 0)
 			(const_int -256))))]
-  "")
+  ""
+  [(set_attr "length" "12,4")
+   (set_attr "type" "*,vecperm")])
 
 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
 ;; complex code.
 
 (define_expand "bswapdi2"
-  [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
+  [(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 ""))])]
+		    (match_operand:DI 1 "reg_or_mem_operand")))
+	      (clobber (match_scratch:DI 2))
+	      (clobber (match_scratch:DI 3))])]
   ""
 {
   rtx dest = operands[0];
@@ -2504,6 +2515,8 @@
 	emit_insn (gen_bswapdi2_load (dest, src));
       else if (MEM_P (dest))
 	emit_insn (gen_bswapdi2_store (dest, src));
+      else if (TARGET_P9_VECTOR)
+	emit_insn (gen_bswapdi2_xxbrd (dest, src));
       else
 	emit_insn (gen_bswapdi2_reg (dest, src));
       DONE;
@@ -2534,12 +2547,19 @@
   "stdbrx %1,%y0"
   [(set_attr "type" "store")])
 
+(define_insn "bswapdi2_xxbrd"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
+	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
+  "TARGET_P9_VECTOR"
+  "xxbrd %x0,%x1"
+  [(set_attr "type" "vecperm")])
+
 (define_insn "bswapdi2_reg"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
 	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
    (clobber (match_scratch:DI 2 "=&r"))
    (clobber (match_scratch:DI 3 "=&r"))]
-  "TARGET_POWERPC64 && TARGET_LDBRX"
+  "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
   "#"
   [(set_attr "length" "36")])
 
@@ -2557,13 +2577,12 @@
   [(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" ""))]
+  [(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"))]
   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
   [(const_int 0)]
-  "
 {
   rtx dest   = operands[0];
   rtx src    = operands[1];
@@ -2618,16 +2637,15 @@
   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
   emit_insn (gen_iordi3 (dest, dest, op3));
   DONE;
-}")
+})
 
 (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" ""))]
+  [(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"))]
   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
   [(const_int 0)]
-  "
 {
   rtx dest   = operands[0];
   rtx src    = operands[1];
@@ -2681,16 +2699,15 @@
       emit_insn (gen_bswapsi2 (word1, op3_si));
     }
   DONE;
-}")
+})
 
 (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" ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  [(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"))]
+  "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
   [(const_int 0)]
-  "
 {
   rtx dest    = operands[0];
   rtx src     = operands[1];
@@ -2708,7 +2725,7 @@
   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
   emit_insn (gen_iordi3 (dest, dest, op3));
   DONE;
-}")
+})
 
 (define_insn "bswapdi2_32bit"
   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
@@ -2719,12 +2736,11 @@
   [(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" ""))]
+  [(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];
@@ -2769,15 +2785,14 @@
      thus allowing us to omit an early clobber on the output.  */
   emit_insn (gen_bswapsi2 (dest1, word2));
   DONE;
-}")
+})
 
 (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" ""))]
+  [(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];
@@ -2818,15 +2833,14 @@
   emit_insn (gen_bswapsi2 (word2, src1));
   emit_insn (gen_bswapsi2 (word1, src2));
   DONE;
-}")
+})
 
 (define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
-   (clobber (match_operand:SI 2 "" ""))]
+  [(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];
@@ -2838,7 +2852,7 @@
   emit_insn (gen_bswapsi2 (dest1, src2));
   emit_insn (gen_bswapsi2 (dest2, src1));
   DONE;
-}")
+})
 
 
 (define_insn "mul<mode>3"
@@ -2851,9 +2865,9 @@
    mulli %0,%1,%2"
    [(set_attr "type" "mul")
     (set (attr "size")
-      (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
+      (cond [(match_operand:GPR 2 "s8bit_cint_operand")
 		(const_string "8")
-             (match_operand:GPR 2 "short_cint_operand" "")
+             (match_operand:GPR 2 "short_cint_operand")
 		(const_string "16")]
 	(const_string "<bits>")))])
 
@@ -3022,9 +3036,9 @@
 ;; modulus.  If it isn't a power of two, force operands into register and do
 ;; a normal divide.
 (define_expand "div<mode>3"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
-		 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(div:GPR (match_operand:GPR 1 "gpc_reg_operand")
+		 (match_operand:GPR 2 "reg_or_cint_operand")))]
   ""
 {
   if (CONST_INT_P (operands[2])
@@ -3164,10 +3178,10 @@
 ;; after a divide.
 
 (define_peephole2
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
-		 (match_operand:GPR 2 "gpc_reg_operand" "")))
-   (set (match_operand:GPR 3 "gpc_reg_operand" "")
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(div:GPR (match_operand:GPR 1 "gpc_reg_operand")
+		 (match_operand:GPR 2 "gpc_reg_operand")))
+   (set (match_operand:GPR 3 "gpc_reg_operand")
 	(mod:GPR (match_dup 1)
 		 (match_dup 2)))]
   "TARGET_MODULO
@@ -3186,10 +3200,10 @@
 		   (match_dup 3)))])
 
 (define_peephole2
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
-		  (match_operand:GPR 2 "gpc_reg_operand" "")))
-   (set (match_operand:GPR 3 "gpc_reg_operand" "")
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
+		  (match_operand:GPR 2 "gpc_reg_operand")))
+   (set (match_operand:GPR 3 "gpc_reg_operand")
 	(umod:GPR (match_dup 1)
 		  (match_dup 2)))]
   "TARGET_MODULO
@@ -3215,9 +3229,9 @@
 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
 
 (define_expand "and<mode>3"
-  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
-	(and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
-		 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
+  [(set (match_operand:SDI 0 "gpc_reg_operand")
+	(and:SDI (match_operand:SDI 1 "gpc_reg_operand")
+		 (match_operand:SDI 2 "reg_or_cint_operand")))]
   ""
 {
   if (<MODE>mode == DImode && !TARGET_POWERPC64)
@@ -3513,9 +3527,9 @@
 
 
 (define_expand "<code><mode>3"
-  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
-	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
-		    (match_operand:SDI 2 "reg_or_cint_operand" "")))]
+  [(set (match_operand:SDI 0 "gpc_reg_operand")
+	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
+		    (match_operand:SDI 2 "reg_or_cint_operand")))]
   ""
 {
   if (<MODE>mode == DImode && !TARGET_POWERPC64)
@@ -3544,9 +3558,9 @@
 })
 
 (define_split
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
-		    (match_operand:GPR 2 "non_logical_cint_operand" "")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
+		    (match_operand:GPR 2 "non_logical_cint_operand")))]
   ""
   [(set (match_dup 3)
 	(iorxor:GPR (match_dup 1)
@@ -3829,11 +3843,19 @@
 
 ; Special case for less-than-0.  We can do it with just one machine
 ; instruction, but the generic optimizers do not realise it is cheap.
-(define_insn "*lt0_disi"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
-	       (const_int 0)))]
+(define_insn "*lt0_<mode>di"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
+		(const_int 0)))]
   "TARGET_POWERPC64"
+  "srdi %0,%1,63"
+  [(set_attr "type" "shift")])
+
+(define_insn "*lt0_<mode>si"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
+		(const_int 0)))]
+  ""
   "rlwinm %0,%1,1,31,31"
   [(set_attr "type" "shift")])
 
@@ -4036,6 +4058,47 @@
    (set_attr "length" "8")])
 
 
+; Yet another case is an rldimi with the second value coming from memory.
+; The zero_extend that should become part of the rldimi is merged into the
+; load from memory instead.  Split things properly again.
+(define_split
+  [(set (match_operand:DI 0 "gpc_reg_operand")
+	(ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
+			   (match_operand:SI 2 "const_int_operand"))
+		(zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
+  "INTVAL (operands[2]) == <bits>"
+  [(set (match_dup 4)
+	(zero_extend:DI (match_dup 3)))
+   (set (match_dup 0)
+	(ior:DI (and:DI (match_dup 4)
+			(match_dup 5))
+		(ashift:DI (match_dup 1)
+			   (match_dup 2))))]
+{
+  operands[4] = gen_reg_rtx (DImode);
+  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
+})
+
+; rlwimi, too.
+(define_split
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
+			   (match_operand:SI 2 "const_int_operand"))
+		(zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
+  "INTVAL (operands[2]) == <bits>"
+  [(set (match_dup 4)
+	(zero_extend:SI (match_dup 3)))
+   (set (match_dup 0)
+	(ior:SI (and:SI (match_dup 4)
+			(match_dup 5))
+		(ashift:SI (match_dup 1)
+			   (match_dup 2))))]
+{
+  operands[4] = gen_reg_rtx (SImode);
+  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
+})
+
+
 ;; Now the simple shifts.
 
 (define_insn "rotl<mode>3"
@@ -4439,9 +4502,9 @@
 ;; Builtins to replace a division to generate FRE reciprocal estimate
 ;; instructions and the necessary fixup instructions
 (define_expand "recip<mode>3"
-  [(match_operand:RECIPF 0 "gpc_reg_operand" "")
-   (match_operand:RECIPF 1 "gpc_reg_operand" "")
-   (match_operand:RECIPF 2 "gpc_reg_operand" "")]
+  [(match_operand:RECIPF 0 "gpc_reg_operand")
+   (match_operand:RECIPF 1 "gpc_reg_operand")
+   (match_operand:RECIPF 2 "gpc_reg_operand")]
   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
 {
    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
@@ -4454,9 +4517,9 @@
 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
 (define_split
-  [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
-	(div:RECIPF (match_operand 1 "gpc_reg_operand" "")
-		    (match_operand 2 "gpc_reg_operand" "")))]
+  [(set (match_operand:RECIPF 0 "gpc_reg_operand")
+	(div:RECIPF (match_operand 1 "gpc_reg_operand")
+		    (match_operand 2 "gpc_reg_operand")))]
   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
    && can_create_pseudo_p () && flag_finite_math_only
    && !flag_trapping_math && flag_reciprocal_math"
@@ -4469,8 +4532,8 @@
 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
 ;; appropriate fixup.
 (define_expand "rsqrt<mode>2"
-  [(match_operand:RECIPF 0 "gpc_reg_operand" "")
-   (match_operand:RECIPF 1 "gpc_reg_operand" "")]
+  [(match_operand:RECIPF 0 "gpc_reg_operand")
+   (match_operand:RECIPF 1 "gpc_reg_operand")]
   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
 {
   rs6000_emit_swsqrt (operands[0], operands[1], 1);
@@ -4483,108 +4546,102 @@
 ;; -mupper-regs-{df,sf} option is enabled.
 
 (define_expand "abs<mode>2"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_INSN"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*abs<mode>2_fpr"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
 	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fabs %0,%1
    xsabsdp %x0,%x1"
-  [(set_attr "type" "fpsimple")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fpsimple")])
 
 (define_insn "*nabs<mode>2_fpr"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
 	(neg:SFDF
 	 (abs:SFDF
 	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fnabs %0,%1
    xsnabsdp %x0,%x1"
-  [(set_attr "type" "fpsimple")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fpsimple")])
 
 (define_expand "neg<mode>2"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_INSN"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*neg<mode>2_fpr"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
 	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fneg %0,%1
    xsnegdp %x0,%x1"
-  [(set_attr "type" "fpsimple")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fpsimple")])
 
 (define_expand "add<mode>3"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
-		   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_INSN"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
+		   (match_operand:SFDF 2 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*add<mode>3_fpr"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
 	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
 		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fadd<Ftrad> %0,%1,%2
    xsadd<Fvsx> %x0,%x1,%x2"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 (define_expand "sub<mode>3"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
-		    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_INSN"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
+		    (match_operand:SFDF 2 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*sub<mode>3_fpr"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
 	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
 		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fsub<Ftrad> %0,%1,%2
    xssub<Fvsx> %x0,%x1,%x2"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 (define_expand "mul<mode>3"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
-		   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_INSN"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
+		   (match_operand:SFDF 2 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*mul<mode>3_fpr"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
 	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
 		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fmul<Ftrad> %0,%1,%2
    xsmul<Fvsx> %x0,%x1,%x2"
-  [(set_attr "type" "dmul")
-   (set_attr "fp_type" "fp_mul_<Fs>")])
+  [(set_attr "type" "dmul")])
 
 (define_expand "div<mode>3"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
-		  (match_operand:SFDF 2 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
+		  (match_operand:SFDF 2 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
 {
   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
       && can_create_pseudo_p () && flag_finite_math_only
@@ -4599,29 +4656,25 @@
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
 	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
 		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
-  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
+  "TARGET_HARD_FLOAT"
   "@
    fdiv<Ftrad> %0,%1,%2
    xsdiv<Fvsx> %x0,%x1,%x2"
-  [(set_attr "type" "<Fs>div")
-   (set_attr "fp_type" "fp_div_<Fs>")])
+  [(set_attr "type" "<Fs>div")])
 
 (define_insn "*sqrt<mode>2_internal"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
 	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
-  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
-   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
+  "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
   "@
    fsqrt<Ftrad> %0,%1
    xssqrt<Fvsx> %x0,%x1"
-  [(set_attr "type" "<Fs>sqrt")
-   (set_attr "fp_type" "fp_sqrt_<Fs>")])
+  [(set_attr "type" "<Fs>sqrt")])
 
 (define_expand "sqrt<mode>2"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
-   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
 {
   if (<MODE>mode == SFmode
       && TARGET_RECIP_PRECISION
@@ -4661,7 +4714,7 @@
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
 	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
 		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fcmpu %0,%1,%2
    xscmpudp %0,%x1,%x2"
@@ -4671,7 +4724,7 @@
 (define_expand "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT"
 {
   if (HONOR_SNANS (SFmode))
     operands[1] = force_reg (SFmode, operands[1]);
@@ -4680,7 +4733,7 @@
 (define_insn_and_split "*extendsfdf2_fpr"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
 	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
+  "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
   "@
    #
    fmr %0,%1
@@ -4700,22 +4753,22 @@
 (define_insn "*extendsfdf2_snan"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
 	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
+  "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
   "@
    frsp %0,%1
    xsrsp %x0,%x1"
   [(set_attr "type" "fp")])
 
 (define_expand "truncdfsf2"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*truncdfsf2_fpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
 	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT"
   "@
    frsp %0,%1
    xsrsp %x0,%x1"
@@ -4726,12 +4779,12 @@
 ;; when little-endian.
 (define_expand "signbit<mode>2"
   [(set (match_dup 2)
-	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
+	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
    (set (match_dup 3)
    	(subreg:DI (match_dup 2) 0))
    (set (match_dup 4)
    	(match_dup 5))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
+   (set (match_operand:SI 0 "gpc_reg_operand")
   	(match_dup 6))]
   "TARGET_HARD_FLOAT
    && (!FLOAT128_IEEE_P (<MODE>mode)
@@ -4739,12 +4792,19 @@
 {
   if (FLOAT128_IEEE_P (<MODE>mode))
     {
+      rtx dest = operands[0];
+      rtx src = operands[1];
+      rtx tmp = gen_reg_rtx (DImode);
+      rtx dest_di = gen_lowpart (DImode, dest);
+
       if (<MODE>mode == KFmode)
-	emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
+	emit_insn (gen_signbitkf2_dm (tmp, src));
       else if (<MODE>mode == TFmode)
-	emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
+	emit_insn (gen_signbittf2_dm (tmp, src));
       else
 	gcc_unreachable ();
+
+      emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
       DONE;
     }
   operands[2] = gen_reg_rtx (DFmode);
@@ -4765,17 +4825,77 @@
     }
 })
 
+;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
+;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
+;; register allocator would typically move the entire _Float128 item to GPRs (2
+;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
+;;
+;; After register allocation, if the _Float128 had originally been in GPRs, the
+;; split allows the post reload phases to eliminate the move, and do the shift
+;; directly with the register that contains the signbit.
+(define_insn_and_split "signbit<mode>2_dm"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
+		   UNSPEC_SIGNBIT))]
+  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+  "@
+   mfvsrd %0,%x1
+   #"
+  "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
+  [(set (match_dup 0)
+	(match_dup 2))]
+{
+  operands[2] = gen_highpart (DImode, operands[1]);
+}
+ [(set_attr "type" "mftgpr,*")])
+
+;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
+;; register and then doing a direct move if the value comes from memory.  On
+;; little endian, we have to load the 2nd double-word to get the sign bit.
+(define_insn_and_split "*signbit<mode>2_dm_mem"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
+	(unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
+		   UNSPEC_SIGNBIT))]
+  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+  "#"
+  "&& 1"
+  [(set (match_dup 0)
+	(match_dup 2))]
+{
+  rtx dest = operands[0];
+  rtx src = operands[1];
+  rtx addr = XEXP (src, 0);
+
+  if (WORDS_BIG_ENDIAN)
+    operands[2] = adjust_address (src, DImode, 0);
+
+  else if (REG_P (addr) || SUBREG_P (addr))
+    operands[2] = adjust_address (src, DImode, 8);
+
+  else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
+	   && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
+    operands[2] = adjust_address (src, DImode, 8);
+
+  else
+    {
+      rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
+      emit_insn (gen_rtx_SET (tmp, addr));
+      operands[2] = change_address (src, DImode,
+				    gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
+    }
+})
+
 (define_expand "copysign<mode>3"
   [(set (match_dup 3)
-        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
+        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
    (set (match_dup 4)
 	(neg:SFDF (abs:SFDF (match_dup 1))))
-   (set (match_operand:SFDF 0 "gpc_reg_operand" "")
-        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
+   (set (match_operand:SFDF 0 "gpc_reg_operand")
+        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
 			       (match_dup 5))
 			 (match_dup 3)
 			 (match_dup 4)))]
-  "TARGET_HARD_FLOAT && <TARGET_FLOAT>
+  "TARGET_HARD_FLOAT
    && ((TARGET_PPC_GFXOPT
         && !HONOR_NANS (<MODE>mode)
         && !HONOR_SIGNED_ZEROS (<MODE>mode))
@@ -4794,54 +4914,6 @@
    operands[5] = CONST0_RTX (<MODE>mode);
   })
 
-;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
-;; and load.
-(define_insn_and_split "signbit<mode>2_dm"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
-	(unspec:SI
-	 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
-	 UNSPEC_SIGNBIT))]
-  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
-  "#"
-  "&& reload_completed"
-  [(const_int 0)]
-{
-  rs6000_split_signbit (operands[0], operands[1]);
-  DONE;
-}
- [(set_attr "length" "8,8,4")
-  (set_attr "type" "mftgpr,load,integer")])
-
-(define_insn_and_split "*signbit<mode>2_dm_<su>ext"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
-	(any_extend:DI
-	 (unspec:SI
-	  [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
-	  UNSPEC_SIGNBIT)))]
-  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
-  "#"
-  "&& reload_completed"
-  [(const_int 0)]
-{
-  rs6000_split_signbit (operands[0], operands[1]);
-  DONE;
-}
- [(set_attr "length" "8,8,4")
-  (set_attr "type" "mftgpr,load,integer")])
-
-;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
-;; floating point types, which makes normal SUBREG's problematical.  Instead
-;; use a special pattern to avoid using a normal movdi.
-(define_insn "signbit<mode>2_dm2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
-		    (const_int 0)]
-		   UNSPEC_SIGNBIT))]
-  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
-  "mfvsrd %0,%x1"
- [(set_attr "type" "mftgpr")])
-
-
 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
 ;; compiler from optimizing -0.0
 (define_insn "copysign<mode>3_fcpsgn"
@@ -4849,7 +4921,7 @@
 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
 		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
 		     UNSPEC_COPYSIGN))]
-  "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
+  "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
   "@
    fcpsgn %0,%2,%1
    xscpsgndp %x0,%x2,%x1"
@@ -4869,10 +4941,10 @@
 ;; to allow either DF/SF to use only traditional registers.
 
 (define_expand "s<minmax><mode>3"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
-			(match_operand:SFDF 2 "gpc_reg_operand" "")))]
-  "TARGET_MINMAX_<MODE>"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
+			(match_operand:SFDF 2 "gpc_reg_operand")))]
+  "TARGET_MINMAX"
 {
   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
   DONE;
@@ -4882,7 +4954,7 @@
   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
 	(fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
 			(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
-  "TARGET_VSX && TARGET_<MODE>_FPR"
+  "TARGET_VSX && TARGET_HARD_FLOAT"
 {
   return (TARGET_P9_MINMAX
 	  ? "xs<minmax>cdp %x0,%x1,%x2"
@@ -4895,10 +4967,10 @@
 ;; instruction.
 
 (define_insn_and_split "*s<minmax><mode>3_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
-			(match_operand:SFDF 2 "gpc_reg_operand" "")))]
-  "!TARGET_VSX && TARGET_MINMAX_<MODE>"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
+			(match_operand:SFDF 2 "gpc_reg_operand")))]
+  "!TARGET_VSX && TARGET_MINMAX"
   "#"
   "&& 1"
   [(const_int 0)]
@@ -4908,18 +4980,17 @@
 })
 
 (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" "")))]
+   [(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"
-  "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
     DONE;
   else
     FAIL;
-}")
+})
 
 ;; We use the BASE_REGS for the isel input operands because, if rA is
 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
@@ -4989,18 +5060,17 @@
 
 ;; Floating point conditional move
 (define_expand "mov<mode>cc"
-   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
-	 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
-			    (match_operand:SFDF 2 "gpc_reg_operand" "")
-			    (match_operand:SFDF 3 "gpc_reg_operand" "")))]
-  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
-  "
+   [(set (match_operand:SFDF 0 "gpc_reg_operand")
+	 (if_then_else:SFDF (match_operand 1 "comparison_operator")
+			    (match_operand:SFDF 2 "gpc_reg_operand")
+			    (match_operand:SFDF 3 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
     DONE;
   else
     FAIL;
-}")
+})
 
 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
@@ -5009,7 +5079,7 @@
 	     (match_operand:SFDF2 4 "zero_fp_constant" "F"))
 	 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
 	 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
-  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
+  "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
@@ -5112,7 +5182,7 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
 	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
 		   UNSPEC_LFIWAX))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
+  "TARGET_HARD_FLOAT && TARGET_LFIWAX"
   "@
    lfiwax %0,%y1
    lxsiwax %x0,%y1
@@ -5129,12 +5199,11 @@
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
 	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
    (clobber (match_scratch:DI 2 "=wi"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
+  "TARGET_HARD_FLOAT && TARGET_LFIWAX
    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
   "#"
   ""
   [(pc)]
-  "
 {
   rtx dest = operands[0];
   rtx src = operands[1];
@@ -5162,7 +5231,7 @@
     }
   emit_insn (gen_floatdi<mode>2 (dest, tmp));
   DONE;
-}"
+}
   [(set_attr "length" "12")
    (set_attr "type" "fpload")])
 
@@ -5172,11 +5241,10 @@
 	 (sign_extend:DI
 	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
    (clobber (match_scratch:DI 2 "=wi"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
+  "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
   "#"
   ""
   [(pc)]
-  "
 {
   operands[1] = rs6000_address_for_fpconvert (operands[1]);
   if (GET_CODE (operands[2]) == SCRATCH)
@@ -5187,7 +5255,7 @@
     emit_insn (gen_lfiwax (operands[2], operands[1]));
   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
   DONE;
-}"
+}
   [(set_attr "length" "8")
    (set_attr "type" "fpload")])
 
@@ -5195,7 +5263,7 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
 	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
 		   UNSPEC_LFIWZX))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
+  "TARGET_HARD_FLOAT && TARGET_LFIWZX"
   "@
    lfiwzx %0,%y1
    lxsiwzx %x0,%y1
@@ -5207,11 +5275,10 @@
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
 	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
    (clobber (match_scratch:DI 2 "=wi"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
+  "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
   "#"
   ""
   [(pc)]
-  "
 {
   rtx dest = operands[0];
   rtx src = operands[1];
@@ -5239,7 +5306,7 @@
     }
   emit_insn (gen_floatdi<mode>2 (dest, tmp));
   DONE;
-}"
+}
   [(set_attr "length" "12")
    (set_attr "type" "fpload")])
 
@@ -5249,11 +5316,10 @@
 	 (zero_extend:DI
 	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
    (clobber (match_scratch:DI 2 "=wi"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
+  "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
   "#"
   ""
   [(pc)]
-  "
 {
   operands[1] = rs6000_address_for_fpconvert (operands[1]);
   if (GET_CODE (operands[2]) == SCRATCH)
@@ -5264,7 +5330,7 @@
     emit_insn (gen_lfiwzx (operands[2], operands[1]));
   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
   DONE;
-}"
+}
   [(set_attr "length" "8")
    (set_attr "type" "fpload")])
 
@@ -5274,15 +5340,14 @@
 ; then to have the insns split later (between sched1 and final).
 
 (define_expand "floatsidf2"
-  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
-		   (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
+  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
+		   (float:DF (match_operand:SI 1 "nonimmediate_operand")))
 	      (use (match_dup 2))
 	      (use (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))
 	      (clobber (match_dup 6))])]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "
+  "TARGET_HARD_FLOAT"
 {
   if (TARGET_LFIWAX && TARGET_FCFID)
     {
@@ -5306,7 +5371,7 @@
   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
   operands[5] = gen_reg_rtx (DFmode);
   operands[6] = gen_reg_rtx (SImode);
-}")
+})
 
 (define_insn_and_split "*floatsidf2_internal"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
@@ -5316,11 +5381,10 @@
    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
-  "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "!TARGET_FCFID && TARGET_HARD_FLOAT"
   "#"
   ""
   [(pc)]
-  "
 {
   rtx lowword, highword;
   gcc_assert (MEM_P (operands[4]));
@@ -5336,7 +5400,7 @@
   emit_move_insn (operands[5], operands[4]);
   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
   DONE;
-}"
+}
   [(set_attr "length" "24")
    (set_attr "type" "fp")])
 
@@ -5344,13 +5408,12 @@
 ;; conversion for 32-bit without fast math, because we don't have the insn to
 ;; generate the fixup swizzle to avoid double rounding problems.
 (define_expand "floatunssisf2"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
+  "TARGET_HARD_FLOAT
    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
-       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
+       || (TARGET_FCFID
 	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
-  "
 {
   if (TARGET_LFIWZX && TARGET_FCFIDUS)
     {
@@ -5366,17 +5429,16 @@
       emit_insn (gen_floatdisf2 (operands[0], dreg));
       DONE;
     }
-}")
+})
 
 (define_expand "floatunssidf2"
-  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
-		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
+  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
+		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
 	      (use (match_dup 2))
 	      (use (match_dup 3))
 	      (clobber (match_dup 4))
 	      (clobber (match_dup 5))])]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "
+  "TARGET_HARD_FLOAT"
 {
   if (TARGET_LFIWZX && TARGET_FCFID)
     {
@@ -5399,7 +5461,7 @@
   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
   operands[5] = gen_reg_rtx (DFmode);
-}")
+})
 
 (define_insn_and_split "*floatunssidf2_internal"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
@@ -5408,12 +5470,11 @@
    (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" "=&d"))]
-  "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
+  "!TARGET_FCFIDU && TARGET_HARD_FLOAT
    && !(TARGET_FCFID && TARGET_POWERPC64)"
   "#"
   ""
   [(pc)]
-  "
 {
   rtx lowword, highword;
   gcc_assert (MEM_P (operands[4]));
@@ -5427,7 +5488,7 @@
   emit_move_insn (operands[5], operands[4]);
   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
   DONE;
-}"
+}
   [(set_attr "length" "20")
    (set_attr "type" "fp")])
 
@@ -5492,9 +5553,9 @@
 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
 		   (unsigned_float:FP_ISA3
-		    (match_operand:QHI 1 "input_operand" "")))
-	      (clobber (match_scratch:DI 2 ""))
-	      (clobber (match_scratch:DI 3 ""))])]
+		    (match_operand:QHI 1 "input_operand")))
+	      (clobber (match_scratch:DI 2))
+	      (clobber (match_scratch:DI 3))])]
   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
 {
   if (MEM_P (operands[1]))
@@ -5535,12 +5596,11 @@
 })
 
 (define_expand "fix_trunc<mode>si2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
-  "
-{
-  if (!TARGET_P8_VECTOR)
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT"
+{
+  if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
     {
       rtx src = force_reg (<MODE>mode, operands[1]);
 
@@ -5555,7 +5615,7 @@
 	}
       DONE;
     }
-}")
+})
 
 ; Like the convert to float patterns, this insn must be split before
 ; register allocation so that it can allocate the memory slot if it
@@ -5564,10 +5624,8 @@
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
 	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
    (clobber (match_scratch:DI 2 "=d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
-   && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
-   && TARGET_STFIWX && can_create_pseudo_p ()
-   && !TARGET_P8_VECTOR"
+  "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
+   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
   "#"
   ""
   [(pc)]
@@ -5608,11 +5666,11 @@
 	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
+  "TARGET_HARD_FLOAT
+   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
   "#"
   ""
   [(pc)]
-  "
 {
   rtx lowword;
   gcc_assert (MEM_P (operands[3]));
@@ -5622,82 +5680,97 @@
   emit_move_insn (operands[3], operands[2]);
   emit_move_insn (operands[0], lowword);
   DONE;
-}"
+}
   [(set_attr "length" "16")
    (set_attr "type" "fp")])
 
 (define_expand "fix_trunc<mode>di2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
+  [(set (match_operand:DI 0 "gpc_reg_operand")
+	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT && TARGET_FCFID"
   "")
 
 (define_insn "*fix_trunc<mode>di2_fctidz"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
 	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
+  "TARGET_HARD_FLOAT && TARGET_FCFID"
   "@
    fctidz %0,%1
    xscvdpsxds %x0,%x1"
   [(set_attr "type" "fp")])
 
-(define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
-  [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
-		   (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
-	      (clobber (match_scratch:DI 2))])]
-  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
-{
-  if (MEM_P (operands[0]))
-    operands[0] = rs6000_address_for_fpconvert (operands[0]);
-})
-
-(define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
-  [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
-	(fix:QHI
-	 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
-   (clobber (match_scratch:DI 2 "=X,wi"))]
-  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
+;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
+;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
+;; vector registers, so we need to do direct moves to the GPRs, but SImode
+;; values can go in VSX registers.  Keeping the direct move part through
+;; register allocation prevents the register allocator from doing a direct move
+;; of the SImode value to a GPR, and then a store/load.
+(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
+  [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
+	(any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
+   (clobber (match_scratch:SI 2 "=X,X,wi"))]
+  "TARGET_DIRECT_MOVE"
+  "@
+   fctiw<u>z %0,%1
+   xscvdp<su>xws %x0,%x1
+   #"
+  "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
+  [(set (match_dup 2)
+	(any_fix:SI (match_dup 1)))
+   (set (match_dup 3)
+	(match_dup 2))]
+{
+  operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
+}
+  [(set_attr "length" "4,4,8")
+   (set_attr "type" "fp")])
+
+(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
+	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
+  "TARGET_DIRECT_MOVE"
+  "@
+   fctiw<u>z %0,%1
+   xscvdp<su>xws %x0,%x1"
+  [(set_attr "type" "fp")])
+
+;; Keep the convert and store together through register allocation to prevent
+;; the register allocator from getting clever and doing a direct move to a GPR
+;; and then store for reg+offset stores.
+(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
+  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
+	(any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
+   (clobber (match_scratch:SI 2 "=wa"))]
+    "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
   "#"
   "&& reload_completed"
-  [(const_int 0)]
-{
-  rtx dest = operands[0];
-  rtx src = operands[1];
-
-  if (vsx_register_operand (dest, <QHI:MODE>mode))
-    {
-      rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
-      emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
-    }
-  else
-    {
-      rtx tmp = operands[2];
-      rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
-
-      emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
-      emit_move_insn (dest, tmp2);
-    }
-  DONE;
+  [(set (match_dup 2)
+	(any_fix:SI (match_dup 1)))
+   (set (match_dup 0)
+	(match_dup 3))]
+{
+  operands[3] = (<QHSI:MODE>mode == SImode
+		 ? operands[2]
+		 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
 })
 
 (define_expand "fixuns_trunc<mode>si2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
-  "
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
 {
   if (!TARGET_P8_VECTOR)
     {
       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
       DONE;
     }
-}")
+})
 
 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
 	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
    (clobber (match_scratch:DI 2 "=d"))]
-  "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
+  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
    && TARGET_STFIWX && can_create_pseudo_p ()
    && !TARGET_P8_VECTOR"
   "#"
@@ -5738,76 +5811,133 @@
 (define_insn "fixuns_trunc<mode>di2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
 	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
+  "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
   "@
    fctiduz %0,%1
    xscvdpuxds %x0,%x1"
   [(set_attr "type" "fp")])
 
-(define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
-  [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
-		   (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
-	      (clobber (match_scratch:DI 2))])]
-  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
-{
-  if (MEM_P (operands[0]))
-    operands[0] = rs6000_address_for_fpconvert (operands[0]);
-})
-
-(define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
-  [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
-	(unsigned_fix:QHI
-	 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
-   (clobber (match_scratch:DI 2 "=X,wi"))]
-  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
-  "#"
-  "&& reload_completed"
-  [(const_int 0)]
-{
-  rtx dest = operands[0];
-  rtx src = operands[1];
-
-  if (vsx_register_operand (dest, <QHI:MODE>mode))
-    {
-      rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
-      emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
-    }
-  else
-    {
-      rtx tmp = operands[2];
-      rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
-
-      emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
-      emit_move_insn (dest, tmp2);
-    }
-  DONE;
-})
-
-;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
-;; older machines, we have to use an UNSPEC to produce a SImode and move it
-;; to another location, since SImode is not allowed in vector registers.
-(define_insn "*fctiw<u>z_<mode>_smallint"
-  [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
-	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
-  "@
-   fctiw<u>z %0,%1
-   xscvdp<su>xws %x0,%x1"
+(define_insn "rs6000_mtfsb0"
+  [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
+		    UNSPECV_MTFSB0)]
+  "TARGET_HARD_FLOAT"
+  "mtfsb0 %0"
+  [(set_attr "type" "fp")])
+
+(define_insn "rs6000_mtfsb1"
+  [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
+		    UNSPECV_MTFSB1)]
+  "TARGET_HARD_FLOAT"
+  "mtfsb1 %0"
+  [(set_attr "type" "fp")])
+
+(define_insn "rs6000_mffscrn"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
+			    UNSPECV_MFFSCRN))]
+   "TARGET_P9_MISC"
+   "mffscrn %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_insn "rs6000_mffscdrn"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+   (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
+   (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
+  "TARGET_P9_MISC"
+  "mffscdrn %0,%1"
   [(set_attr "type" "fp")])
 
-;; Combiner pattern to prevent moving the result of converting a floating point
-;; value to 32-bit integer to GPR in order to save it.
-(define_insn_and_split "*fctiw<u>z_<mode>_mem"
-  [(set (match_operand:SI 0 "memory_operand" "=Z")
-	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
-   (clobber (match_scratch:SI 2 "=wa"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 2)
-	(any_fix:SI (match_dup 1)))
-   (set (match_dup 0)
-	(match_dup 2))])
+(define_expand "rs6000_set_fpscr_rn"
+ [(match_operand:DI 0 "reg_or_cint_operand")]
+  "TARGET_HARD_FLOAT"
+{
+  rtx tmp_df = gen_reg_rtx (DFmode);
+
+  /* The floating point rounding control bits are FPSCR[62:63]. Put the
+     new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
+  if (TARGET_P9_MISC)
+    {
+      rtx src_df = force_reg (DImode, operands[0]);
+      src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
+      emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
+      DONE;
+    }
+
+  if (CONST_INT_P (operands[0]))
+    {
+      if ((INTVAL (operands[0]) & 0x1) == 0x1)
+	emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
+      else
+	emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
+
+      if ((INTVAL (operands[0]) & 0x2) == 0x2)
+	emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
+      else
+	emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
+    }
+  else
+    {
+      rtx tmp_rn = gen_reg_rtx (DImode);
+      rtx tmp_di = gen_reg_rtx (DImode);
+
+      /* Extract new RN mode from operand.  */
+      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
+
+      /* Insert new RN mode into FSCPR.  */
+      emit_insn (gen_rs6000_mffs (tmp_df));
+      tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
+      emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
+      emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
+
+      /* Need to write to field k=15.  The fields are [0:15].  Hence with
+	 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
+	 8-bit field[0:7]. Need to set the bit that corresponds to the
+	 value of i that you want [0:7].  */
+      tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
+      emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
+    }
+  DONE;
+})
+
+(define_expand "rs6000_set_fpscr_drn"
+  [(match_operand:DI 0  "gpc_reg_operand")]
+  "TARGET_HARD_FLOAT"
+{
+  rtx tmp_df = gen_reg_rtx (DFmode);
+
+  /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
+     new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
+  if (TARGET_P9_MISC)
+    {
+      rtx src_df = gen_reg_rtx (DFmode);
+
+      emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
+      src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
+      emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
+    }
+  else
+    {
+      rtx tmp_rn = gen_reg_rtx (DImode);
+      rtx tmp_di = gen_reg_rtx (DImode);
+
+      /* Extract new DRN mode from operand.  */
+      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
+      emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
+
+      /* Insert new RN mode into FSCPR.  */
+      emit_insn (gen_rs6000_mffs (tmp_df));
+      tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
+      emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
+      emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
+
+      /* Need to write to field 7.  The fields are [0:15].  The equation to
+	 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
+	 i to 0x1 to get field 7 where i selects the field.  */
+      tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
+      emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
+    }
+  DONE;
+})
 
 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
@@ -5818,7 +5948,7 @@
 	(unspec:DI [(fix:SI
 		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
 		   UNSPEC_FCTIWZ))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT"
   "@
    fctiwz %0,%1
    xscvdpsxws %x0,%x1"
@@ -5829,7 +5959,7 @@
 	(unspec:DI [(unsigned_fix:SI
 		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
 		   UNSPEC_FCTIWUZ))]
-  "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
+  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
   "@
    fctiwuz %0,%1
    xscvdpuxws %x0,%x1"
@@ -5841,7 +5971,7 @@
 (define_insn "*friz"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
 	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
+  "TARGET_HARD_FLOAT && TARGET_FPRND
    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
   "@
    friz %0,%1
@@ -5860,7 +5990,7 @@
 	 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
    (clobber (match_scratch:DI 2 "=d"))
    (clobber (match_scratch:DI 3 "=d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
+  "TARGET_HARD_FLOAT
    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
   "#"
@@ -5893,7 +6023,7 @@
 	 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
    (clobber (match_scratch:DI 2 "=d"))
    (clobber (match_scratch:DI 3 "=d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
+  "TARGET_HARD_FLOAT
    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
    && can_create_pseudo_p ()"
   "#"
@@ -5920,20 +6050,12 @@
   [(set_attr "type" "fpload")
    (set_attr "length" "16")])
 
-(define_insn "lrintsfsi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
-	(unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
-		   UNSPEC_FCTIW))]
-  "TARGET_SF_FPR && TARGET_FPRND"
-  "fctiw %0,%1"
-  [(set_attr "type" "fp")])
-
 ;; No VSX equivalent to fctid
 (define_insn "lrint<mode>di2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
 	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
 		   UNSPEC_FCTID))]
-  "TARGET_<MODE>_FPR && TARGET_FPRND"
+  "TARGET_HARD_FLOAT && TARGET_FPRND"
   "fctid %0,%1"
   [(set_attr "type" "fp")])
 
@@ -5941,62 +6063,57 @@
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
 		     UNSPEC_FRIZ))]
-  "TARGET_<MODE>_FPR && TARGET_FPRND"
+  "TARGET_HARD_FLOAT && TARGET_FPRND"
   "@
    friz %0,%1
    xsrdpiz %x0,%x1"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 (define_insn "ceil<mode>2"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
 		     UNSPEC_FRIP))]
-  "TARGET_<MODE>_FPR && TARGET_FPRND"
+  "TARGET_HARD_FLOAT && TARGET_FPRND"
   "@
    frip %0,%1
    xsrdpip %x0,%x1"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 (define_insn "floor<mode>2"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
 		     UNSPEC_FRIM))]
-  "TARGET_<MODE>_FPR && TARGET_FPRND"
+  "TARGET_HARD_FLOAT && TARGET_FPRND"
   "@
    frim %0,%1
    xsrdpim %x0,%x1"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 ;; No VSX equivalent to frin
 (define_insn "round<mode>2"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
 		     UNSPEC_FRIN))]
-  "TARGET_<MODE>_FPR && TARGET_FPRND"
+  "TARGET_HARD_FLOAT && TARGET_FPRND"
   "frin %0,%1"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 (define_insn "*xsrdpi<mode>2"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
 		     UNSPEC_XSRDPI))]
-  "TARGET_<MODE>_FPR && TARGET_VSX"
+  "TARGET_HARD_FLOAT && TARGET_VSX"
   "xsrdpi %x0,%x1"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 (define_expand "lround<mode>di2"
   [(set (match_dup 2)
-	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
 		     UNSPEC_XSRDPI))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
+   (set (match_operand:DI 0 "gpc_reg_operand")
 	(unspec:DI [(match_dup 2)]
 		   UNSPEC_FCTID))]
-  "TARGET_<MODE>_FPR && TARGET_VSX"
+  "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
 {
   operands[2] = gen_reg_rtx (<MODE>mode);
 })
@@ -6018,13 +6135,12 @@
 ;; conversion for 32-bit without fast math, because we don't have the insn to
 ;; generate the fixup swizzle to avoid double rounding problems.
 (define_expand "floatsisf2"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-        (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+        (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
+  "TARGET_HARD_FLOAT
    && ((TARGET_FCFIDS && TARGET_LFIWAX)
-       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
+       || (TARGET_FCFID
 	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
-  "
 {
   if (TARGET_FCFIDS && TARGET_LFIWAX)
     {
@@ -6047,12 +6163,12 @@
       emit_insn (gen_floatdisf2 (operands[0], dreg));
       DONE;
     }
-}")
+})
 
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
 	(float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
-  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "TARGET_FCFID && TARGET_HARD_FLOAT"
   "@
    fcfid %0,%1
    xscvsxddp %x0,%x1"
@@ -6067,7 +6183,7 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
 	(float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
    (clobber (match_scratch:DI 2 "=d,wi"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
+  "TARGET_HARD_FLOAT && TARGET_FCFID"
   "#"
   "&& reload_completed"
   [(set (match_dup 2) (match_dup 1))
@@ -6077,9 +6193,9 @@
    (set_attr "type" "fpload")])
 
 (define_expand "floatunsdidf2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
+  [(set (match_operand:DF 0 "gpc_reg_operand")
 	(unsigned_float:DF
-	 (match_operand:DI 1 "gpc_reg_operand" "")))]
+	 (match_operand:DI 1 "gpc_reg_operand")))]
   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
   "")
 
@@ -6090,8 +6206,7 @@
   "@
    fcfidu %0,%1
    xscvuxddp %x0,%x1"
-  [(set_attr "type" "fp")
-   (set_attr "length" "4")])
+  [(set_attr "type" "fp")])
 
 (define_insn_and_split "*floatunsdidf2_mem"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
@@ -6107,11 +6222,10 @@
    (set_attr "type" "fpload")])
 
 (define_expand "floatdisf2"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-        (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+        (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
+  "TARGET_FCFID && TARGET_HARD_FLOAT
    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
-  "
 {
   if (!TARGET_FCFIDS)
     {
@@ -6126,13 +6240,12 @@
       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
       DONE;
     }
-}")
+})
 
 (define_insn "floatdisf2_fcfids"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
 	(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
-   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
+  "TARGET_HARD_FLOAT && TARGET_FCFIDS"
   "@
    fcfids %0,%1
    xscvsxdsp %x0,%x1"
@@ -6142,17 +6255,15 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
 	(float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
    (clobber (match_scratch:DI 2 "=d,d,wi"))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
-   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
+  "TARGET_HARD_FLOAT && TARGET_FCFIDS"
   "#"
   "&& reload_completed"
   [(pc)]
-  "
 {
   emit_move_insn (operands[2], operands[1]);
   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
   DONE;
-}"
+}
   [(set_attr "length" "8")])
 
 ;; This is not IEEE compliant if rounding mode is "round to nearest".
@@ -6163,7 +6274,7 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
    (clobber (match_scratch:DF 2 "=d"))]
-  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
+  "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -6179,11 +6290,11 @@
 ;; by a bit that won't be lost at that stage, but is below the SFmode
 ;; rounding position.
 (define_expand "floatdisf2_internal2"
-  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
+  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
 					      (const_int 53)))
 	      (clobber (reg:DI CA_REGNO))])
-   (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
-					   (const_int 2047)))
+   (set (match_operand:DI 0 "") (and:DI (match_dup 1)
+					(const_int 2047)))
    (set (match_dup 3) (plus:DI (match_dup 3)
 			       (const_int 1)))
    (set (match_dup 0) (plus:DI (match_dup 0)
@@ -6195,29 +6306,25 @@
    (set (match_dup 0) (and:DI (match_dup 0)
 			      (const_int -2048)))
    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
-			   (label_ref (match_operand:DI 2 "" ""))
+			   (label_ref (match_operand:DI 2 ""))
 			   (pc)))
    (set (match_dup 0) (match_dup 1))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
-   && !TARGET_FCFIDS"
-  "
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
 {
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (CCUNSmode);
-}")
+})
 
 (define_expand "floatunsdisf2"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
-   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
+  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
   "")
 
 (define_insn "floatunsdisf2_fcfidus"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
-   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
+  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
   "@
    fcfidus %0,%1
    xscvuxdsp %x0,%x1"
@@ -6227,17 +6334,15 @@
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
 	(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
    (clobber (match_scratch:DI 2 "=d,d,wi"))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
-   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
+  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
   "#"
   "&& reload_completed"
   [(pc)]
-  "
 {
   emit_move_insn (operands[2], operands[1]);
   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
   DONE;
-}"
+}
   [(set_attr "length" "8")
    (set_attr "type" "fpload")])
 
@@ -6248,9 +6353,9 @@
 ;; also allow for the output being the same as one of the inputs.
 
 (define_expand "addti3"
-  [(set (match_operand:TI 0 "gpc_reg_operand" "")
-	(plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
-		 (match_operand:TI 2 "reg_or_short_operand" "")))]
+  [(set (match_operand:TI 0 "gpc_reg_operand")
+	(plus:TI (match_operand:TI 1 "gpc_reg_operand")
+		 (match_operand:TI 2 "reg_or_short_operand")))]
   "TARGET_64BIT"
 {
   rtx lo0 = gen_lowpart (DImode, operands[0]);
@@ -6271,9 +6376,9 @@
 })
 
 (define_expand "subti3"
-  [(set (match_operand:TI 0 "gpc_reg_operand" "")
-	(minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
-		  (match_operand:TI 2 "gpc_reg_operand" "")))]
+  [(set (match_operand:TI 0 "gpc_reg_operand")
+	(minus:TI (match_operand:TI 1 "reg_or_short_operand")
+		  (match_operand:TI 2 "gpc_reg_operand")))]
   "TARGET_64BIT"
 {
   rtx lo0 = gen_lowpart (DImode, operands[0]);
@@ -6296,73 +6401,73 @@
 ;; 128-bit logical operations expanders
 
 (define_expand "and<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
-	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
-		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
+	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
+		      (match_operand:BOOL_128 2 "vlogical_operand")))]
   ""
   "")
 
 (define_expand "ior<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
-        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
-		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
+        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
+		      (match_operand:BOOL_128 2 "vlogical_operand")))]
   ""
   "")
 
 (define_expand "xor<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
-        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
-		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
+        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
+		      (match_operand:BOOL_128 2 "vlogical_operand")))]
   ""
   "")
 
 (define_expand "one_cmpl<mode>2"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
-        (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
+        (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
   ""
   "")
 
 (define_expand "nor<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
 	(and:BOOL_128
-	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
-	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
+	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
+	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
   ""
   "")
 
 (define_expand "andc<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
         (and:BOOL_128
-	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
-	 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
+	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
+	 (match_operand:BOOL_128 1 "vlogical_operand")))]
   ""
   "")
 
 ;; Power8 vector logical instructions.
 (define_expand "eqv<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
 	(not:BOOL_128
-	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
-		       (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
+	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
+		       (match_operand:BOOL_128 2 "vlogical_operand"))))]
   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
   "")
 
 ;; Rewrite nand into canonical form
 (define_expand "nand<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
 	(ior:BOOL_128
-	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
-	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
+	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
+	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
   "")
 
 ;; The canonical form is to have the negated element first, so we need to
 ;; reverse arguments.
 (define_expand "orc<mode>3"
-  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
+  [(set (match_operand:BOOL_128 0 "vlogical_operand")
 	(ior:BOOL_128
-	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
-	 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
+	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
+	 (match_operand:BOOL_128 1 "vlogical_operand")))]
   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
   "")
 
@@ -6656,11 +6761,10 @@
 ;; Set up a register with a value from the GOT table
 
 (define_expand "movsi_got"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(unspec:SI [(match_operand:SI 1 "got_operand" "")
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(unspec:SI [(match_operand:SI 1 "got_operand")
 		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
-  "
 {
   if (GET_CODE (operands[1]) == CONST)
     {
@@ -6681,7 +6785,7 @@
     }
 
   operands[2] = rs6000_got_register (operands[1]);
-}")
+})
 
 (define_insn "*movsi_got_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -6695,9 +6799,9 @@
 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
 ;; didn't get allocated to a hard register.
 (define_split
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
-		    (match_operand:SI 2 "memory_operand" "")]
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(unspec:SI [(match_operand:SI 1 "got_no_const_operand")
+		    (match_operand:SI 2 "memory_operand")]
 		   UNSPEC_MOVSI_GOT))]
   "DEFAULT_ABI == ABI_V4
     && flag_pic == 1
@@ -6717,8 +6821,7 @@
                            (match_operand 2 "" ""))))]
   "TARGET_MACHO && ! TARGET_64BIT"
   "lwz %0,lo16(%2)(%1)"
-  [(set_attr "type" "load")
-   (set_attr "length" "4")])
+  [(set_attr "type" "load")])
 
 ;;		MR           LA           LWZ          LFIWZX       LXSIWZX
 ;;		STW          STFIWX       STXSIWX      LI           LIS
@@ -6740,8 +6843,8 @@
 		 O,          wM,          wS,          r,           wIwH,
 		 *h,         r,           r,           0"))]
 
-  "!TARGET_SINGLE_FPU &&
-   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
+  "gpc_reg_operand (operands[0], SImode)
+   || gpc_reg_operand (operands[1], SImode)"
   "@
    mr %0,%1
    la %0,%a1
@@ -6781,28 +6884,6 @@
 		 4,          4,           8,           4,           4,
 		 4,          4,           4,           4")])
 
-(define_insn "*movsi_internal1_single"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
-        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
-  "TARGET_SINGLE_FPU &&
-   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
-  "@
-   mr %0,%1
-   la %0,%a1
-   lwz%U1%X1 %0,%1
-   stw%U0%X0 %1,%0
-   li %0,%1
-   lis %0,%v1
-   #
-   mf%1 %0
-   mt%0 %1
-   mt%0 %1
-   nop
-   stfs%U0%X0 %1,%0
-   lfs%U1%X1 %0,%1"
-  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
-   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
-
 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
 ;;
@@ -6956,8 +7037,8 @@
 ;; sequence.
 
 (define_split
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(match_operand:SI 1 "const_int_operand" ""))]
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(match_operand:SI 1 "const_int_operand"))]
   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
    && (INTVAL (operands[1]) & 0xffff) != 0"
   [(set (match_dup 0)
@@ -6965,13 +7046,12 @@
    (set (match_dup 0)
 	(ior:SI (match_dup 0)
 		(match_dup 3)))]
-  "
 {
   if (rs6000_emit_set_const (operands[0], operands[1]))
     DONE;
   else
     FAIL;
-}")
+})
 
 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
 (define_split
@@ -7017,10 +7097,13 @@
   "")
 
 (define_expand "mov<mode>"
-  [(set (match_operand:INT 0 "general_operand" "")
-	(match_operand:INT 1 "any_operand" ""))]
-  ""
-  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
+  [(set (match_operand:INT 0 "general_operand")
+	(match_operand:INT 1 "any_operand"))]
+  ""
+{
+  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
+  DONE;
+})
 
 ;;		MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
 ;;		XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
@@ -7070,8 +7153,8 @@
 ;; an integer register or memory, we store just the high-order 4 bits.
 ;; This lets us not shift in the most common case of CR0.
 (define_expand "movcc"
-  [(set (match_operand:CC 0 "nonimmediate_operand" "")
-	(match_operand:CC 1 "nonimmediate_operand" ""))]
+  [(set (match_operand:CC 0 "nonimmediate_operand")
+	(match_operand:CC 1 "nonimmediate_operand"))]
   ""
   "")
 
@@ -7095,25 +7178,21 @@
    mt%0 %1
    lwz%U1%X1 %0,%1
    stw%U0%X0 %1,%0"
-  [(set (attr "type")
-     (cond [(eq_attr "alternative" "0,3")
-		(const_string "cr_logical")
-	    (eq_attr "alternative" "1,2")
-		(const_string "mtcr")
-	    (eq_attr "alternative" "6,7")
-		(const_string "integer")
-	    (eq_attr "alternative" "8")
-		(const_string "mfjmpr")
-	    (eq_attr "alternative" "9")
-		(const_string "mtjmpr")
-	    (eq_attr "alternative" "10")
-		(const_string "load")
-	    (eq_attr "alternative" "11")
-		(const_string "store")
-	    (match_test "TARGET_MFCRF")
-		(const_string "mfcrf")
-	   ]
-	(const_string "mfcr")))
+  [(set_attr_alternative "type"
+     [(const_string "cr_logical")
+      (const_string "mtcr")
+      (const_string "mtcr")
+      (const_string "cr_logical")
+      (if_then_else (match_test "TARGET_MFCRF")
+		    (const_string "mfcrf") (const_string "mfcr"))
+      (if_then_else (match_test "TARGET_MFCRF")
+		    (const_string "mfcrf") (const_string "mfcr"))
+      (const_string "integer")
+      (const_string "integer")
+      (const_string "mfjmpr")
+      (const_string "mtjmpr")
+      (const_string "load")
+      (const_string "store")])
    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
 
 ;; For floating-point, we normally deal with the floating-point registers
@@ -7124,21 +7203,23 @@
 
 ;; Move 32-bit binary/decimal floating point
 (define_expand "mov<mode>"
-  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
-	(match_operand:FMOVE32 1 "any_operand" ""))]
+  [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
+	(match_operand:FMOVE32 1 "any_operand"))]
   "<fmove_ok>"
-  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
+{
+  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
+  DONE;
+})
 
 (define_split
-  [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
-	(match_operand:FMOVE32 1 "const_double_operand" ""))]
+  [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
+	(match_operand:FMOVE32 1 "const_double_operand"))]
   "reload_completed
    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
        || (GET_CODE (operands[0]) == SUBREG
 	   && GET_CODE (SUBREG_REG (operands[0])) == REG
 	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
   [(set (match_dup 2) (match_dup 3))]
-  "
 {
   long l;
 
@@ -7150,7 +7231,7 @@
     operands[2] = gen_lowpart (SImode, operands[0]);
 
   operands[3] = gen_int_mode (l, SImode);
-}")
+})
 
 ;; Originally, we tried to keep movsf and movsd common, but the differences
 ;; addressing was making it rather difficult to hide with mode attributes.  In
@@ -7176,7 +7257,7 @@
 	  r,         r,         *h,         0"))]
   "(register_operand (operands[0], SFmode)
    || register_operand (operands[1], SFmode))
-   && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
+   && TARGET_HARD_FLOAT
    && (TARGET_ALLOW_SF_SUBREG
        || valid_sf_si_move (operands[0], operands[1], SFmode))"
   "@
@@ -7212,7 +7293,7 @@
 	  f,         r,         r,         *h,        0"))]
   "(register_operand (operands[0], SDmode)
    || register_operand (operands[1], SDmode))
-   && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
+   && TARGET_HARD_FLOAT"
   "@
    lwz%U1%X1 %0,%1
    lfiwzx %0,%y1
@@ -7229,9 +7310,17 @@
 	"load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
 	 fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
 
+;;	MR           MT%0       MF%0       LWZ        STW        LI
+;;	LIS          G-const.   F/n-const  NOP
 (define_insn "*mov<mode>_softfloat"
-  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
-	(match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
+  [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
+	"=r,         cl,        r,         r,         m,         r,
+          r,         r,         r,         *h")
+
+	(match_operand:FMOVE32 1 "input_operand"
+	 "r,         r,         h,         m,         r,         I,
+          L,         G,         Fn,        0"))]
+
   "(gpc_reg_operand (operands[0], <MODE>mode)
    || gpc_reg_operand (operands[1], <MODE>mode))
    && TARGET_SOFT_FLOAT"
@@ -7246,8 +7335,13 @@
    #
    #
    nop"
-  [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
-   (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
+  [(set_attr "type"
+	"*,          mtjmpr,    mfjmpr,    load,      store,     *,
+         *,          *,         *,         *")
+
+   (set_attr "length"
+	"4,          4,         4,         4,         4,         4,
+         4,          4,         8,         4")])
 
 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
@@ -7321,14 +7415,17 @@
 
 ;; Move 64-bit binary/decimal floating point
 (define_expand "mov<mode>"
-  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
-	(match_operand:FMOVE64 1 "any_operand" ""))]
-  ""
-  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
+  [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
+	(match_operand:FMOVE64 1 "any_operand"))]
+  ""
+{
+  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
+  DONE;
+})
 
 (define_split
-  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
-	(match_operand:FMOVE64 1 "const_int_operand" ""))]
+  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
+	(match_operand:FMOVE64 1 "const_int_operand"))]
   "! TARGET_POWERPC64 && reload_completed
    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
        || (GET_CODE (operands[0]) == SUBREG
@@ -7336,7 +7433,6 @@
 	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 1))]
-  "
 {
   int endian = (WORDS_BIG_ENDIAN == 0);
   HOST_WIDE_INT value = INTVAL (operands[1]);
@@ -7345,11 +7441,11 @@
   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
   operands[4] = GEN_INT (value >> 32);
   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
-}")
+})
 
 (define_split
-  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
-	(match_operand:FMOVE64 1 "const_double_operand" ""))]
+  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
+	(match_operand:FMOVE64 1 "const_double_operand"))]
   "! TARGET_POWERPC64 && reload_completed
    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
        || (GET_CODE (operands[0]) == SUBREG
@@ -7357,7 +7453,6 @@
 	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
-  "
 {
   int endian = (WORDS_BIG_ENDIAN == 0);
   long l[2];
@@ -7368,18 +7463,17 @@
   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
   operands[4] = gen_int_mode (l[endian], SImode);
   operands[5] = gen_int_mode (l[1 - endian], SImode);
-}")
+})
 
 (define_split
-  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
-	(match_operand:FMOVE64 1 "const_double_operand" ""))]
+  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
+	(match_operand:FMOVE64 1 "const_double_operand"))]
   "TARGET_POWERPC64 && reload_completed
    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
        || (GET_CODE (operands[0]) == SUBREG
 	   && GET_CODE (SUBREG_REG (operands[0])) == REG
 	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
   [(set (match_dup 2) (match_dup 3))]
-  "
 {
   int endian = (WORDS_BIG_ENDIAN == 0);
   long l[2];
@@ -7393,7 +7487,7 @@
          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
 
   operands[3] = gen_int_mode (val, DImode);
-}")
+})
 
 ;; Don't have reload use general registers to load a constant.  It is
 ;; less efficient than loading the constant into an FP register, since
@@ -7410,10 +7504,23 @@
 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
 ;; except for 0.0 which can be created on VSX with an xor instruction.
 
+;;           STFD         LFD         FMR         LXSD        STXSD
+;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
+;;           LWZ          STW         MR
+
+
 (define_insn "*mov<mode>_hardfloat32"
-  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
-	(match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 
+  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
+            "=m,          d,          d,          <f64_p9>,   wY,
+              <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
+              Y,          r,          !r")
+
+	(match_operand:FMOVE64 1 "input_operand"
+             "d,          m,          d,          wY,         <f64_p9>,
+              Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
+              r,          Y,          r"))]
+
+  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
   "@
@@ -7422,35 +7529,66 @@
    fmr %0,%1
    lxsd %0,%1
    stxsd %1,%0
-   lxsd%U1x %x0,%y1
-   stxsd%U0x %x1,%y0
+   lxsdx %x0,%y1
+   stxsdx %x1,%y0
    xxlor %x0,%x1,%x1
    xxlxor %x0,%x0,%x0
    #
    #
    #
    #"
-  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
+  [(set_attr "type"
+            "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
+             fpload,      fpstore,    veclogical, veclogical, two,
+             store,       load,       two")
+
    (set_attr "size" "64")
-   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
+   (set_attr "length"
+            "4,           4,          4,          4,          4,
+             4,           4,          4,          4,          8,
+             8,           8,          8")])
+
+;;           STW      LWZ     MR      G-const H-const F-const
 
 (define_insn "*mov<mode>_softfloat32"
-  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
-	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
-  "! TARGET_POWERPC64 
-   && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
+  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
+           "=Y,       r,      r,      r,      r,      r")
+
+	(match_operand:FMOVE64 1 "input_operand"
+            "r,       Y,      r,      G,      H,      F"))]
+
+  "!TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
   "#"
-  [(set_attr "type" "store,load,two,*,*,*")
-   (set_attr "length" "8,8,8,8,12,16")])
+  [(set_attr "type"
+            "store,   load,   two,    *,      *,      *")
+
+   (set_attr "length"
+             "8,      8,      8,      8,      12,     16")])
 
 ; ld/std require word-aligned displacements -> 'Y' constraint.
 ; List Y->r and r->Y before r->r for reload.
+
+;;           STFD         LFD         FMR         LXSD        STXSD
+;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
+;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
+;;           NOP          MFTGPR      MFFGPR      MFVSRD      MTVSRD
+
 (define_insn "*mov<mode>_hardfloat64"
-  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
-	(match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
+  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
+           "=m,           d,          d,          <f64_p9>,   wY,
+             <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
+             YZ,          r,          !r,         *c*l,       !r,
+            *h,           r,          wg,         r,          <f64_dm>")
+
+	(match_operand:FMOVE64 1 "input_operand"
+            "d,           m,          d,          wY,         <f64_p9>,
+             Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
+             r,           YZ,         r,          r,          h,
+             0,           wg,         r,          <f64_dm>,   r"))]
+
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
   "@
@@ -7459,8 +7597,8 @@
    fmr %0,%1
    lxsd %0,%1
    stxsd %1,%0
-   lxsd%U1x %x0,%y1
-   stxsd%U0x %x1,%y0
+   lxsdx %x0,%y1
+   stxsdx %x1,%y0
    xxlor %x0,%x1,%x1
    xxlxor %x0,%x0,%x0
    li %0,0
@@ -7474,13 +7612,27 @@
    mffgpr %0,%1
    mfvsrd %0,%x1
    mtvsrd %x0,%1"
-  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
+  [(set_attr "type"
+            "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
+             fpload,      fpstore,    veclogical, veclogical, integer,
+             store,       load,       *,          mtjmpr,     mfjmpr,
+             *,           mftgpr,     mffgpr,     mftgpr,    mffgpr")
+
    (set_attr "size" "64")
    (set_attr "length" "4")])
 
+;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
+;;           H-const  F-const  Special
+
 (define_insn "*mov<mode>_softfloat64"
-  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
-	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
+  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
+           "=Y,       r,      r,      cl,     r,      r,
+             r,       r,      *h")
+
+	(match_operand:FMOVE64 1 "input_operand"
+            "r,       Y,      r,      r,      h,      G,
+             H,       F,      0"))]
+
   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -7494,14 +7646,22 @@
    #
    #
    nop"
-  [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
-   (set_attr "length" "4,4,4,4,4,8,12,16,4")])
+  [(set_attr "type"
+            "store,   load,   *,      mtjmpr, mfjmpr, *,
+             *,       *,      *")
+
+   (set_attr "length"
+            "4,       4,      4,      4,      4,      8,
+             12,      16,     4")])
 
 (define_expand "mov<mode>"
-  [(set (match_operand:FMOVE128 0 "general_operand" "")
-	(match_operand:FMOVE128 1 "any_operand" ""))]
-  ""
-  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
+  [(set (match_operand:FMOVE128 0 "general_operand")
+	(match_operand:FMOVE128 1 "any_operand"))]
+  ""
+{
+  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
+  DONE;
+})
 
 ;; It's important to list Y->r and r->Y before r->r because otherwise
 ;; reload, given m->r, will try to pick r->r and reload it, which
@@ -7564,8 +7724,8 @@
   [(set_attr "length" "20,20,16")])
 
 (define_expand "extenddf<mode>2"
-  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
-	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
+	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
 {
   if (FLOAT128_IEEE_P (<MODE>mode))
@@ -7600,7 +7760,7 @@
 	(float_extend:IBM128
 	 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
-  "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
+  "!TARGET_VSX && TARGET_HARD_FLOAT
    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
   "#"
   "&& reload_completed"
@@ -7633,8 +7793,8 @@
 })
 
 (define_expand "extendsf<mode>2"
-  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
-	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
+	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
 {
   if (FLOAT128_IEEE_P (<MODE>mode))
@@ -7649,8 +7809,8 @@
 })
 
 (define_expand "trunc<mode>df2"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:DF 0 "gpc_reg_operand")
+	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
 {
   if (FLOAT128_IEEE_P (<MODE>mode))
@@ -7681,40 +7841,25 @@
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
 	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
-   && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
+   && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_addsub_d")])
+  [(set_attr "type" "fp")])
 
 (define_expand "trunc<mode>sf2"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
 {
   if (FLOAT128_IEEE_P (<MODE>mode))
     rs6000_expand_float128_convert (operands[0], operands[1], false);
-  else if (<MODE>mode == TFmode)
-    emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
-  else if (<MODE>mode == IFmode)
-    emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
-  else
-    gcc_unreachable ();
-  DONE;
-})
-
-(define_insn_and_split "trunc<mode>sf2_fprs"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
-	(float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
-   (clobber (match_scratch:DF 2 "=d"))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 
-   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 2)
-	(float_truncate:DF (match_dup 1)))
-   (set (match_dup 0)
-	(float_truncate:SF (match_dup 2)))]
-  "")
+  else
+    {
+      rtx tmp = gen_reg_rtx (DFmode);
+      emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
+      emit_insn (gen_truncdfsf2 (operands[0], tmp));
+    }
+  DONE;
+})
 
 (define_expand "floatsi<mode>2"
   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
@@ -7753,14 +7898,14 @@
 	(unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
 		   UNSPEC_FIX_TRUNC_TF))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
+  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
   [(set_attr "type" "fp")
    (set_attr "length" "20")])
 
 (define_expand "fix_trunc<mode>si2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand")
+	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
 {
   rtx op0 = operands[0];
@@ -7783,8 +7928,8 @@
 })
 
 (define_expand "fix_trunc<mode>si2_fprs"
-  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
-		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
+  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
+		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
 	      (clobber (match_dup 2))
 	      (clobber (match_dup 3))
 	      (clobber (match_dup 4))
@@ -7823,8 +7968,8 @@
 })
 
 (define_expand "fix_trunc<mode>di2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand")
+	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   if (!TARGET_FLOAT128_HW)
@@ -7835,8 +7980,8 @@
 })
 
 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
-  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
-	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:SDI 0 "gpc_reg_operand")
+	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], true);
@@ -7844,8 +7989,8 @@
 })
 
 (define_expand "floatdi<mode>2"
-  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
-	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
+	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   if (!TARGET_FLOAT128_HW)
@@ -7856,8 +8001,8 @@
 })
 
 (define_expand "floatunsdi<IEEE128:mode>2"
-  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
-	(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
+	(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   if (!TARGET_FLOAT128_HW)
@@ -7868,8 +8013,8 @@
 })
 
 (define_expand "floatuns<IEEE128:mode>2"
-  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
-	(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
+	(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rtx op0 = operands[0];
@@ -7883,11 +8028,10 @@
 })
 
 (define_expand "neg<mode>2"
-  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
-	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
+	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
   "FLOAT128_IEEE_P (<MODE>mode)
    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
-  "
 {
   if (FLOAT128_IEEE_P (<MODE>mode))
     {
@@ -7921,28 +8065,26 @@
 	}
       DONE;
     }
-}")
+})
 
 (define_insn "neg<mode>2_internal"
   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
 	(neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
-  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
-  "*
+  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
 {
   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
-    return \"fneg %L0,%L1\;fneg %0,%1\";
-  else
-    return \"fneg %0,%1\;fneg %L0,%L1\";
-}"
+    return "fneg %L0,%L1\;fneg %0,%1";
+  else
+    return "fneg %0,%1\;fneg %L0,%L1";
+}
   [(set_attr "type" "fpsimple")
    (set_attr "length" "8")])
 
 (define_expand "abs<mode>2"
-  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
-	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
+	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
   "FLOAT128_IEEE_P (<MODE>mode)
    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
-  "
 {
   rtx label;
 
@@ -7975,26 +8117,25 @@
   label = gen_label_rtx ();
   if (<MODE>mode == TFmode)
     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
-  else if (<MODE>mode == TFmode)
+  else if (<MODE>mode == IFmode)
     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
   else
     FAIL;
   emit_label (label);
   DONE;
-}")
+})
 
 (define_expand "abs<mode>2_internal"
-  [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
-	(match_operand:IBM128 1 "gpc_reg_operand" ""))
+  [(set (match_operand:IBM128 0 "gpc_reg_operand")
+	(match_operand:IBM128 1 "gpc_reg_operand"))
    (set (match_dup 3) (match_dup 5))
    (set (match_dup 5) (abs:DF (match_dup 5)))
    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
-			   (label_ref (match_operand 2 "" ""))
+			   (label_ref (match_operand 2 ""))
 			   (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
-  "
+  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
 {
   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
@@ -8002,14 +8143,14 @@
   operands[4] = gen_reg_rtx (CCFPmode);
   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
-}")
+})
 
 
 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
 ;; register
 
 (define_expand "ieee_128bit_negative_zero"
-  [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
+  [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
   "TARGET_FLOAT128_TYPE"
 {
   rtvec v = rtvec_alloc (16);
@@ -8019,7 +8160,7 @@
     RTVEC_ELT (v, i) = const0_rtx;
 
   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
-  RTVEC_ELT (v, high) = GEN_INT (0x80);
+  RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
 
   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
   DONE;
@@ -8128,8 +8269,8 @@
 ;; We use expand to convert from IBM double double to IEEE 128-bit
 ;; and trunc for the opposite.
 (define_expand "extendiftf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:TF 0 "gpc_reg_operand")
+	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
@@ -8137,8 +8278,8 @@
 })
 
 (define_expand "extendifkf2"
-  [(set (match_operand:KF 0 "gpc_reg_operand" "")
-	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:KF 0 "gpc_reg_operand")
+	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
@@ -8146,8 +8287,17 @@
 })
 
 (define_expand "extendtfkf2"
-  [(set (match_operand:KF 0 "gpc_reg_operand" "")
-	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:KF 0 "gpc_reg_operand")
+	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
+  "TARGET_FLOAT128_TYPE"
+{
+  rs6000_expand_float128_convert (operands[0], operands[1], false);
+  DONE;
+})
+
+(define_expand "extendtfif2"
+  [(set (match_operand:IF 0 "gpc_reg_operand")
+	(float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
@@ -8155,8 +8305,8 @@
 })
 
 (define_expand "trunciftf2"
-  [(set (match_operand:IF 0 "gpc_reg_operand" "")
-	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:TF 0 "gpc_reg_operand")
+	(float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
@@ -8164,8 +8314,8 @@
 })
 
 (define_expand "truncifkf2"
-  [(set (match_operand:IF 0 "gpc_reg_operand" "")
-	(float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:KF 0 "gpc_reg_operand")
+	(float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
@@ -8173,8 +8323,8 @@
 })
 
 (define_expand "trunckftf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:TF 0 "gpc_reg_operand")
+	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
@@ -8182,14 +8332,40 @@
 })
 
 (define_expand "trunctfif2"
-  [(set (match_operand:IF 0 "gpc_reg_operand" "")
-	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:IF 0 "gpc_reg_operand")
+	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
+(define_insn_and_split "*extend<mode>tf2_internal"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
+	(float_extend:TF
+	 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
+   "TARGET_FLOAT128_TYPE
+    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 2))]
+{
+  operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
+})
+
+(define_insn_and_split "*extendtf<mode>2_internal"
+  [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
+	(float_extend:IFKF
+	 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
+   "TARGET_FLOAT128_TYPE
+    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 2))]
+{
+  operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
+})
+
 
 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
 ;; must have 3 arguments, and scratch register constraint must be a single
@@ -8362,8 +8538,8 @@
    (set_attr "type" "three")])
 
 (define_split
-  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
-	(match_operand:FMOVE128_GPR 1 "input_operand" ""))]
+  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
+	(match_operand:FMOVE128_GPR 1 "input_operand"))]
   "reload_completed
    && (int_reg_operand (operands[0], <MODE>mode)
        || int_reg_operand (operands[1], <MODE>mode))
@@ -8487,16 +8663,16 @@
 
 (define_insn "*movdi_internal32"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-         "=Y,        r,         r,         ^m,        ^d,         ^d,
-          r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
+         "=Y,        r,         r,         m,         ^d,         ^d,
+          r,         wY,        Z,         ^wb,       $wv,        ^wi,
           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
           *wv")
 
 	(match_operand:DI 1 "input_operand"
-          "r,        Y,         r,         d,         m,          d,
-           IJKnGHF,  wb,        wv,        wY,        Z,          wi,
-           Oj,       wM,        OjwM,      Oj,        wM,         wS,
-           wB"))]
+         "r,         Y,         r,         ^d,        m,          ^d,
+          IJKnGHF,   ^wb,       $wv,       wY,        Z,          ^wi,
+          Oj,        wM,        OjwM,      Oj,        wM,         wS,
+          wB"))]
 
   "! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
@@ -8529,14 +8705,13 @@
    (set_attr "size" "64")])
 
 (define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(match_operand:DI 1 "const_int_operand" ""))]
+  [(set (match_operand:DI 0 "gpc_reg_operand")
+	(match_operand:DI 1 "const_int_operand"))]
   "! TARGET_POWERPC64 && reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])
    && !direct_move_p (operands[0], operands[1])"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 1))]
-  "
 {
   HOST_WIDE_INT value = INTVAL (operands[1]);
   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
@@ -8545,11 +8720,11 @@
 				       DImode);
   operands[4] = GEN_INT (value >> 32);
   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
-}")
+})
 
 (define_split
-  [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
-        (match_operand:DIFD 1 "input_operand" ""))]
+  [(set (match_operand:DIFD 0 "nonimmediate_operand")
+        (match_operand:DIFD 1 "input_operand"))]
   "reload_completed && !TARGET_POWERPC64
    && gpr_or_gpr_p (operands[0], operands[1])
    && !direct_move_p (operands[0], operands[1])"
@@ -8563,18 +8738,18 @@
 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
 (define_insn "*movdi_internal64"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-               "=Y,        r,         r,         r,         r,          r,
-                ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
+               "=YZ,       r,         r,         r,         r,          r,
+                m,         ^d,        ^d,        wY,        Z,          $wb,
                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
                 *wi,       *wv,       *wv,       r,         *h,         *h,
                 ?*r,       ?*wg,      ?*r,       ?*wj")
 
 	(match_operand:DI 1 "input_operand"
-                "r,        Y,         r,         I,         L,          nF,
-                 d,        m,         d,         wb,        wv,         wY,
-                 Z,        wi,        Oj,        wM,        OjwM,       Oj,
-                 wM,       wS,        wB,        *h,        r,          0,
-                 wg,       r,         wj,        r"))]
+               "r,         YZ,        r,         I,         L,          nF,
+                ^d,        m,         ^d,        ^wb,       $wv,        wY,
+                Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
+                wM,        wS,        wB,        *h,        r,          0,
+                wg,        r,         wj,        r"))]
 
   "TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
@@ -8644,36 +8819,34 @@
 ;; When non-easy constants can go in the TOC, this should use
 ;; easy_fp_constant predicate.
 (define_split
-  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
-	(match_operand:DI 1 "const_int_operand" ""))]
+  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
+	(match_operand:DI 1 "const_int_operand"))]
   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
   [(set (match_dup 0) (match_dup 2))
    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
-  "
 {
   if (rs6000_emit_set_const (operands[0], operands[1]))
     DONE;
   else
     FAIL;
-}")
+})
 
 (define_split
-  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
-	(match_operand:DI 1 "const_scalar_int_operand" ""))]
+  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
+	(match_operand:DI 1 "const_scalar_int_operand"))]
   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
   [(set (match_dup 0) (match_dup 2))
    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
-  "
 {
   if (rs6000_emit_set_const (operands[0], operands[1]))
     DONE;
   else
     FAIL;
-}")
+})
 
 (define_split
-  [(set (match_operand:DI 0 "altivec_register_operand" "")
-	(match_operand:DI 1 "s5bit_cint_operand" ""))]
+  [(set (match_operand:DI 0 "altivec_register_operand")
+	(match_operand:DI 1 "s5bit_cint_operand"))]
   "TARGET_VSX && reload_completed"
   [(const_int 0)]
 {
@@ -8694,8 +8867,8 @@
 ;; Split integer constants that can be loaded with XXSPLTIB and a
 ;; sign extend operation.
 (define_split
-  [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
-	(match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
+  [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
+	(match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
   "TARGET_P9_VECTOR && reload_completed"
   [(const_int 0)]
 {
@@ -8728,37 +8901,11 @@
    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
-  "*
-{
-  switch (which_alternative)
-    {
-    default:
-      gcc_unreachable ();
-    case 0:
-      if (TARGET_STRING)
-        return \"stswi %1,%P0,16\";
-      /* FALLTHRU */
-    case 1:
-      return \"#\";
-    case 2:
-      /* If the address is not used in the output, we can use lsi.  Otherwise,
-	 fall through to generating four loads.  */
-      if (TARGET_STRING
-          && ! reg_overlap_mentioned_p (operands[0], operands[1]))
-	return \"lswi %0,%P1,16\";
-      /* fall through */
-    case 3:
-    case 4:
-    case 5:
-      return \"#\";
-    }
-}"
+  "#"
   [(set_attr "type" "store,store,load,load,*,*")
    (set_attr "update" "yes")
    (set_attr "indexed" "yes")
-   (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
-   			                  (const_string "always")
-					  (const_string "conditional")))])
+   (set_attr "cell_micro" "conditional")])
 
 (define_insn "*mov<mode>_ppc64"
   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
@@ -8773,14 +8920,13 @@
    (set_attr "length" "8")])
 
 (define_split
-  [(set (match_operand:TI2 0 "int_reg_operand" "")
-	(match_operand:TI2 1 "const_scalar_int_operand" ""))]
+  [(set (match_operand:TI2 0 "int_reg_operand")
+	(match_operand:TI2 1 "const_scalar_int_operand"))]
   "TARGET_POWERPC64
    && (VECTOR_MEM_NONE_P (<MODE>mode)
        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
-  "
 {
   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
 				       <MODE>mode);
@@ -8798,11 +8944,11 @@
     }
   else
     FAIL;
-}")
+})
 
 (define_split
-  [(set (match_operand:TI2 0 "nonimmediate_operand" "")
-        (match_operand:TI2 1 "input_operand" ""))]
+  [(set (match_operand:TI2 0 "nonimmediate_operand")
+        (match_operand:TI2 1 "input_operand"))]
   "reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])
    && !direct_move_p (operands[0], operands[1])
@@ -8810,344 +8956,12 @@
   [(pc)]
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
-(define_expand "load_multiple"
-  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
-			  (match_operand:SI 1 "" ""))
-		     (use (match_operand:SI 2 "" ""))])]
-  "TARGET_STRING && !TARGET_POWERPC64"
-  "
-{
-  int regno;
-  int count;
-  rtx op1;
-  int i;
-
-  /* Support only loading a constant number of fixed-point registers from
-     memory and only bother with this if more than two; the machine
-     doesn't support more than eight.  */
-  if (GET_CODE (operands[2]) != CONST_INT
-      || INTVAL (operands[2]) <= 2
-      || INTVAL (operands[2]) > 8
-      || GET_CODE (operands[1]) != MEM
-      || GET_CODE (operands[0]) != REG
-      || REGNO (operands[0]) >= 32)
-    FAIL;
-
-  count = INTVAL (operands[2]);
-  regno = REGNO (operands[0]);
-
-  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
-  op1 = replace_equiv_address (operands[1],
-			       force_reg (SImode, XEXP (operands[1], 0)));
-
-  for (i = 0; i < count; i++)
-    XVECEXP (operands[3], 0, i)
-      = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
-		     adjust_address_nv (op1, SImode, i * 4));
-}")
-
-(define_insn "*ldmsi8"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
-     (set (match_operand:SI 7 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
-     (set (match_operand:SI 8 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 24))))
-     (set (match_operand:SI 9 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi7"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
-     (set (match_operand:SI 7 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
-     (set (match_operand:SI 8 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi6"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
-     (set (match_operand:SI 7 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi5"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi4"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi3"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_expand "store_multiple"
-  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
-			  (match_operand:SI 1 "" ""))
-		     (clobber (scratch:SI))
-		     (use (match_operand:SI 2 "" ""))])]
-  "TARGET_STRING && !TARGET_POWERPC64"
-  "
-{
-  int regno;
-  int count;
-  rtx to;
-  rtx op0;
-  int i;
-
-  /* Support only storing a constant number of fixed-point registers to
-     memory and only bother with this if more than two; the machine
-     doesn't support more than eight.  */
-  if (GET_CODE (operands[2]) != CONST_INT
-      || INTVAL (operands[2]) <= 2
-      || INTVAL (operands[2]) > 8
-      || GET_CODE (operands[0]) != MEM
-      || GET_CODE (operands[1]) != REG
-      || REGNO (operands[1]) >= 32)
-    FAIL;
-
-  count = INTVAL (operands[2]);
-  regno = REGNO (operands[1]);
-
-  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
-  to = force_reg (SImode, XEXP (operands[0], 0));
-  op0 = replace_equiv_address (operands[0], to);
-
-  XVECEXP (operands[3], 0, 0)
-    = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
-  XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
-						 gen_rtx_SCRATCH (SImode));
-
-  for (i = 1; i < count; i++)
-    XVECEXP (operands[3], 0, i + 1)
-      = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
-		     gen_rtx_REG (SImode, regno + i));
-}")
-
-(define_insn "*stmsi8"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
-	  (match_operand:SI 8 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
-	  (match_operand:SI 9 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
-	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi7"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
-	  (match_operand:SI 8 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
-	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi6"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
-	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi5"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi4"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi3"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
 (define_expand "setmemsi"
-  [(parallel [(set (match_operand:BLK 0 "" "")
-		   (match_operand 2 "const_int_operand" ""))
-	      (use (match_operand:SI 1 "" ""))
-	      (use (match_operand:SI 3 "" ""))])]
-  ""
-  "
+  [(parallel [(set (match_operand:BLK 0 "")
+		   (match_operand 2 "const_int_operand"))
+	      (use (match_operand:SI 1 ""))
+	      (use (match_operand:SI 3 ""))])]
+  ""
 {
   /* If value to set is not zero, use the library routine.  */
   if (operands[2] != const0_rtx)
@@ -9157,7 +8971,7 @@
     DONE;
   else
     FAIL;
-}")
+})
 
 ;; String compare N insn.
 ;; Argument 0 is the target (result)
@@ -9233,198 +9047,17 @@
 ;; Argument 3 is the alignment
 
 (define_expand "movmemsi"
-  [(parallel [(set (match_operand:BLK 0 "" "")
-		   (match_operand:BLK 1 "" ""))
-	      (use (match_operand:SI 2 "" ""))
-	      (use (match_operand:SI 3 "" ""))])]
-  ""
-  "
+  [(parallel [(set (match_operand:BLK 0 "")
+		   (match_operand:BLK 1 ""))
+	      (use (match_operand:SI 2 ""))
+	      (use (match_operand:SI 3 ""))])]
+  ""
 {
   if (expand_block_move (operands))
     DONE;
   else
     FAIL;
-}")
-
-;; Move up to 32 bytes at a time.  The fixed registers are needed because the
-;; register allocator doesn't have a clue about allocating 8 word registers.
-;; rD/rS = r5 is preferred, efficient form.
-(define_expand "movmemsi_8reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI  5))
-	      (clobber (reg:SI  6))
-	      (clobber (reg:SI  7))
-	      (clobber (reg:SI  8))
-	      (clobber (reg:SI  9))
-	      (clobber (reg:SI 10))
-	      (clobber (reg:SI 11))
-	      (clobber (reg:SI 12))
-	      (clobber (match_scratch:SI 4 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
-   (clobber (reg:SI  6))
-   (clobber (reg:SI  7))
-   (clobber (reg:SI  8))
-   (clobber (reg:SI  9))
-   (clobber (reg:SI 10))
-   (clobber (reg:SI 11))
-   (clobber (reg:SI 12))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING
-   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
-       || INTVAL (operands[2]) == 0)
-   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
-   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
-   && REGNO (operands[4]) == 5"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 24 bytes at a time.  The fixed registers are needed because the
-;; register allocator doesn't have a clue about allocating 6 word registers.
-;; rD/rS = r5 is preferred, efficient form.
-(define_expand "movmemsi_6reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI  5))
-	      (clobber (reg:SI  6))
-	      (clobber (reg:SI  7))
-	      (clobber (reg:SI  8))
-	      (clobber (reg:SI  9))
-	      (clobber (reg:SI 10))
-	      (clobber (match_scratch:SI 4 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
-   (clobber (reg:SI  6))
-   (clobber (reg:SI  7))
-   (clobber (reg:SI  8))
-   (clobber (reg:SI  9))
-   (clobber (reg:SI 10))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING
-   && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
-   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
-   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
-   && REGNO (operands[4]) == 5"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
-;; problems with TImode.
-;; rD/rS = r5 is preferred, efficient form.
-(define_expand "movmemsi_4reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI 5))
-	      (clobber (reg:SI 6))
-	      (clobber (reg:SI 7))
-	      (clobber (reg:SI 8))
-	      (clobber (match_scratch:SI 4 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
-   (clobber (reg:SI 6))
-   (clobber (reg:SI 7))
-   (clobber (reg:SI 8))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING
-   && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
-   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
-   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
-   && REGNO (operands[4]) == 5"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 8 bytes at a time.
-(define_expand "movmemsi_2reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (match_scratch:DI 4 ""))
-	      (clobber (match_scratch:SI 5 ""))])]
-  "TARGET_STRING && ! TARGET_POWERPC64"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_scratch:DI 4 "=&r"))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING && ! TARGET_POWERPC64
-   && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 4 bytes at a time.
-(define_expand "movmemsi_1reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (match_scratch:SI 4 ""))
-	      (clobber (match_scratch:SI 5 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_scratch:SI 4 "=&r"))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
+})
 
 ;; Define insns that do load or store with update.  Some of these we can
 ;; get by using pre-decrement or pre-increment, but the hardware can also
@@ -9671,7 +9304,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
+  "TARGET_HARD_FLOAT && TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
@@ -9687,7 +9320,7 @@
 	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
+  "TARGET_HARD_FLOAT && TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
@@ -9735,7 +9368,7 @@
 			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
+  "TARGET_HARD_FLOAT && TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
@@ -9752,7 +9385,7 @@
 	(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_DOUBLE_FLOAT && TARGET_UPDATE
+  "TARGET_HARD_FLOAT && TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
@@ -9772,18 +9405,18 @@
 ;; Also this optimization interferes with scalars going into
 ;; altivec registers (the code does reloading through the FPRs).
 (define_peephole2
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(match_operand:DF 1 "any_operand" ""))
-   (set (match_operand:DF 2 "gpc_reg_operand" "")
+  [(set (match_operand:DF 0 "gpc_reg_operand")
+	(match_operand:DF 1 "any_operand"))
+   (set (match_operand:DF 2 "gpc_reg_operand")
 	(match_dup 0))]
   "!TARGET_VSX
    && peep2_reg_dead_p (2, operands[0])"
   [(set (match_dup 2) (match_dup 1))])
 
 (define_peephole2
-  [(set (match_operand:SF 0 "gpc_reg_operand" "")
-	(match_operand:SF 1 "any_operand" ""))
-   (set (match_operand:SF 2 "gpc_reg_operand" "")
+  [(set (match_operand:SF 0 "gpc_reg_operand")
+	(match_operand:SF 1 "any_operand"))
+   (set (match_operand:SF 2 "gpc_reg_operand")
 	(match_dup 0))]
   "!TARGET_P8_VECTOR
    && peep2_reg_dead_p (2, operands[0])"
@@ -9879,10 +9512,9 @@
    (set (match_dup 0)
    	(lo_sum:TLSmode (match_dup 3)
 	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
-  "
 {
   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
-}"
+}
   [(set (attr "length")
      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
      		   (const_int 8)
@@ -9895,8 +9527,7 @@
 			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		       UNSPEC_TLSGD)))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
-  "addis %0,%1,%2@got@tlsgd@ha"
-  [(set_attr "length" "4")])
+  "addis %0,%1,%2@got@tlsgd@ha")
 
 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
@@ -9905,8 +9536,7 @@
 			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		       UNSPEC_TLSGD)))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
-  "addi %0,%1,%2@got@tlsgd@l"
-  [(set_attr "length" "4")])
+  "addi %0,%1,%2@got@tlsgd@l")
 
 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
@@ -9938,8 +9568,7 @@
     }
   return "bl %z1(%3@tlsgd)";
 }
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
@@ -10016,10 +9645,9 @@
    (set (match_dup 0)
    	(lo_sum:TLSmode (match_dup 2)
 	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
-  "
 {
   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
-}"
+}
   [(set (attr "length")
      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
      		   (const_int 8)
@@ -10032,8 +9660,7 @@
 			(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
 		       UNSPEC_TLSLD)))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
-  "addis %0,%1,%&@got@tlsld@ha"
-  [(set_attr "length" "4")])
+  "addis %0,%1,%&@got@tlsld@ha")
 
 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
@@ -10042,8 +9669,7 @@
                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
                        UNSPEC_TLSLD)))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
-  "addi %0,%1,%&@got@tlsld@l"
-  [(set_attr "length" "4")])
+  "addi %0,%1,%&@got@tlsld@l")
 
 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
@@ -10073,8 +9699,7 @@
     }
   return "bl %z1(%&@tlsld)";
 }
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
@@ -10114,10 +9739,9 @@
    (set (match_dup 0)
 	(lo_sum:TLSmode (match_dup 3)
 	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
-  "
 {
   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
-}"
+}
   [(set (attr "length")
      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
      		   (const_int 8)
@@ -10130,8 +9754,7 @@
 			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		       UNSPEC_TLSGOTDTPREL)))]
   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
-  "addis %0,%1,%2@got@dtprel@ha"
-  [(set_attr "length" "4")])
+  "addis %0,%1,%2@got@dtprel@ha")
 
 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
@@ -10140,8 +9763,7 @@
 			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 			 UNSPEC_TLSGOTDTPREL)))]
   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
-  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
-  [(set_attr "length" "4")])
+  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)")
 
 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
@@ -10184,10 +9806,9 @@
    (set (match_dup 0)
 	(lo_sum:TLSmode (match_dup 3)
 	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
-  "
 {
   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
-}"
+}
   [(set (attr "length")
      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
      		   (const_int 8)
@@ -10200,8 +9821,7 @@
 			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		       UNSPEC_TLSGOTTPREL)))]
   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
-  "addis %0,%1,%2@got@tprel@ha"
-  [(set_attr "length" "4")])
+  "addis %0,%1,%2@got@tprel@ha")
 
 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
@@ -10210,8 +9830,7 @@
 			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 			 UNSPEC_TLSGOTTPREL)))]
   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
-  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
-  [(set_attr "length" "4")])
+  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)")
 
 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
@@ -10222,15 +9841,14 @@
   "add %0,%1,%2@tls")
 
 (define_expand "tls_get_tpointer"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+  [(set (match_operand:SI 0 "gpc_reg_operand")
 	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
   "TARGET_XCOFF && HAVE_AS_TLS"
-  "
 {
   emit_insn (gen_tls_get_tpointer_internal ());
   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
   DONE;
-}")
+})
 
 (define_insn "tls_get_tpointer_internal"
   [(set (reg:SI 3)
@@ -10240,18 +9858,17 @@
   "bla __get_tpointer")
 
 (define_expand "tls_get_addr<mode>"
-  [(set (match_operand:P 0 "gpc_reg_operand" "")
-	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
-                   (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
+  [(set (match_operand:P 0 "gpc_reg_operand")
+	(unspec:P [(match_operand:P 1 "gpc_reg_operand")
+                   (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
   "TARGET_XCOFF && HAVE_AS_TLS"
-  "
 {
   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
   emit_insn (gen_tls_get_addr_internal<mode> ());
   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
   DONE;
-}")
+})
 
 (define_insn "tls_get_addr_internal<mode>"
   [(set (reg:P 3)
@@ -10281,13 +9898,13 @@
 ;; the constant size.  The value is forced into a register if necessary.
 ;;
 (define_expand "allocate_stack"
-  [(set (match_operand 0 "gpc_reg_operand" "")
-	(minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
+  [(set (match_operand 0 "gpc_reg_operand")
+	(minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
    (set (reg 1)
 	(minus (reg 1) (match_dup 1)))]
   ""
-  "
-{ rtx chain = gen_reg_rtx (Pmode);
+{
+  rtx chain = gen_reg_rtx (Pmode);
   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
   rtx neg_op0;
   rtx insn, par, set, mem;
@@ -10333,6 +9950,9 @@
 	{
 	  rtx loop_lab, end_loop;
 	  bool rotated = CONST_INT_P (rounded_size);
+	  rtx update = GEN_INT (-probe_interval);
+	  if (probe_interval > 32768)
+	    update = force_reg (Pmode, update);
 
 	  emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
 							last_addr, rotated);
@@ -10340,13 +9960,11 @@
 	  if (Pmode == SImode)
 	    emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
 					       stack_pointer_rtx,
-					       GEN_INT (-probe_interval),
-					       chain));
+					       update, chain));
 	  else
 	    emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
 					          stack_pointer_rtx,
-					          GEN_INT (-probe_interval),
-					          chain));
+					          update, chain));
 	  emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
 						      last_addr, rotated);
 	}
@@ -10354,14 +9972,12 @@
       /* Now handle residuals.  We just have to set operands[1] correctly
 	 and let the rest of the expander run.  */
       operands[1] = residual;
-      if (!CONST_INT_P (residual))
-	operands[1] = force_reg (Pmode, operands[1]);
-    }
-
-  if (GET_CODE (operands[1]) != CONST_INT
-      || INTVAL (operands[1]) < -32767
-      || INTVAL (operands[1]) > 32768)
-    {
+    }
+
+  if (!(CONST_INT_P (operands[1])
+	&& IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
+    {
+      operands[1] = force_reg (Pmode, operands[1]);
       neg_op0 = gen_reg_rtx (Pmode);
       if (TARGET_32BIT)
 	emit_insn (gen_negsi2 (neg_op0, operands[1]));
@@ -10369,7 +9985,7 @@
 	emit_insn (gen_negdi2 (neg_op0, operands[1]));
     }
   else
-    neg_op0 = GEN_INT (- INTVAL (operands[1]));
+    neg_op0 = GEN_INT (-INTVAL (operands[1]));
 
   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
 				       : gen_movdi_di_update_stack))
@@ -10390,7 +10006,7 @@
 
   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
   DONE;
-}")
+})
 
 ;; These patterns say how to save and restore the stack pointer.  We need not
 ;; save the stack pointer at function level since we are careful to
@@ -10402,14 +10018,14 @@
 ;; save area is a memory location.
 
 (define_expand "save_stack_function"
-  [(match_operand 0 "any_operand" "")
-   (match_operand 1 "any_operand" "")]
+  [(match_operand 0 "any_operand")
+   (match_operand 1 "any_operand")]
   ""
   "DONE;")
 
 (define_expand "restore_stack_function"
-  [(match_operand 0 "any_operand" "")
-   (match_operand 1 "any_operand" "")]
+  [(match_operand 0 "any_operand")
+   (match_operand 1 "any_operand")]
   ""
   "DONE;")
 
@@ -10420,10 +10036,9 @@
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 4) (match_dup 2))
    (match_dup 5)
-   (set (match_operand 0 "register_operand" "")
-	(match_operand 1 "register_operand" ""))]
-  ""
-  "
+   (set (match_operand 0 "register_operand")
+	(match_operand 1 "register_operand"))]
+  ""
 {
   rtvec p;
 
@@ -10435,14 +10050,13 @@
   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
 				  const0_rtx);
   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
-}")
+})
 
 (define_expand "save_stack_nonlocal"
   [(set (match_dup 3) (match_dup 4))
-   (set (match_operand 0 "memory_operand" "") (match_dup 3))
-   (set (match_dup 2) (match_operand 1 "register_operand" ""))]
-  ""
-  "
+   (set (match_operand 0 "memory_operand") (match_dup 3))
+   (set (match_dup 2) (match_operand 1 "register_operand"))]
+  ""
 {
   int units_per_word = (TARGET_32BIT) ? 4 : 8;
 
@@ -10451,16 +10065,15 @@
   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
   operands[3] = gen_reg_rtx (Pmode);
   operands[4] = gen_frame_mem (Pmode, operands[1]);
-}")
+})
 
 (define_expand "restore_stack_nonlocal"
-  [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
+  [(set (match_dup 2) (match_operand 1 "memory_operand"))
    (set (match_dup 3) (match_dup 4))
    (set (match_dup 5) (match_dup 2))
    (match_dup 6)
-   (set (match_operand 0 "register_operand" "") (match_dup 3))]
-  ""
-  "
+   (set (match_operand 0 "register_operand") (match_dup 3))]
+  ""
 {
   int units_per_word = (TARGET_32BIT) ? 4 : 8;
   rtvec p;
@@ -10475,7 +10088,7 @@
   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
 				  const0_rtx);
   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
-}")
+})
 
 ;; TOC register handling.
 
@@ -10486,16 +10099,15 @@
 		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
 	      (use (reg:SI 2))])]
   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
-  "*
 {
   char buf[30];
   extern int need_toc_init;
   need_toc_init = 1;
-  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
+  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
   operands[2] = gen_rtx_REG (Pmode, 2);
-  return \"lwz %0,%1(%2)\";
-}"
+  return "lwz %0,%1(%2)";
+}
   [(set_attr "type" "load")
    (set_attr "update" "no")
    (set_attr "indexed" "no")])
@@ -10505,19 +10117,18 @@
 		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
 	      (use (reg:DI 2))])]
   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
-  "*
 {
   char buf[30];
   extern int need_toc_init;
   need_toc_init = 1;
-  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
+  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
 			       !TARGET_ELF || !TARGET_MINIMAL_TOC);
   if (TARGET_ELF)
-    strcat (buf, \"@toc\");
+    strcat (buf, "@toc");
   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
   operands[2] = gen_rtx_REG (Pmode, 2);
-  return \"ld %0,%1(%2)\";
-}"
+  return "ld %0,%1(%2)";
+}
   [(set_attr "type" "load")
    (set_attr "update" "no")
    (set_attr "indexed" "no")])
@@ -10527,8 +10138,7 @@
 	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
   "bl _GLOBAL_OFFSET_TABLE_@local-4"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_expand "load_toc_v4_PIC_1"
   [(parallel [(set (reg:SI LR_REGNO)
@@ -10544,9 +10154,8 @@
    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
-  "bcl 20,31,%0\\n%0:"
+  "bcl 20,31,%0\n%0:"
   [(set_attr "type" "branch")
-   (set_attr "length" "4")
    (set_attr "cannot_copy" "yes")])
 
 (define_insn "load_toc_v4_PIC_1_476"
@@ -10555,23 +10164,21 @@
    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
-  "*
 {
   char name[32];
   static char templ[32];
 
   get_ppc476_thunk_name (name);
-  sprintf (templ, \"bl %s\\n%%0:\", name);
+  sprintf (templ, "bl %s\n%%0:", name);
   return templ;
-}"
+}
   [(set_attr "type" "branch")
-   (set_attr "length" "4")
    (set_attr "cannot_copy" "yes")])
 
 (define_expand "load_toc_v4_PIC_1b"
   [(parallel [(set (reg:SI LR_REGNO)
 		   (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
-			       (label_ref (match_operand 1 "" ""))]
+			       (label_ref (match_operand 1 ""))]
 		           UNSPEC_TOCPTR))
 	      (match_dup 1)])]
   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
@@ -10595,41 +10202,46 @@
 		UNSPEC_TOCPTR))
    (match_dup 1)]
   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
-  "*
 {
   char name[32];
   static char templ[32];
 
   get_ppc476_thunk_name (name);
-  sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
+  sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
   return templ;
-}"
+}
   [(set_attr "type" "branch")
    (set_attr "length" "16")])
 
 (define_insn "load_toc_v4_PIC_2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
-		   (minus:SI (match_operand:SI 2 "immediate_operand" "s")
-			     (match_operand:SI 3 "immediate_operand" "s")))))]
+	(mem:SI (plus:SI
+		  (match_operand:SI 1 "gpc_reg_operand" "b")
+		  (const
+		    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
+			      (match_operand:SI 3 "immediate_operand" "s"))))))]
   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
   "lwz %0,%2-%3(%1)"
   [(set_attr "type" "load")])
 
 (define_insn "load_toc_v4_PIC_3b"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
-		 (high:SI
-		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
-			     (match_operand:SI 3 "symbol_ref_operand" "s")))))]
+	(plus:SI
+	  (match_operand:SI 1 "gpc_reg_operand" "b")
+	  (high:SI
+	    (const
+	      (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
+			(match_operand:SI 3 "symbol_ref_operand" "s"))))))]
   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
   "addis %0,%1,%2-%3@ha")
 
 (define_insn "load_toc_v4_PIC_3c"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
-		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
-			     (match_operand:SI 3 "symbol_ref_operand" "s"))))]
+	(lo_sum:SI
+	  (match_operand:SI 1 "gpc_reg_operand" "b")
+	  (const
+	    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
+		      (match_operand:SI 3 "symbol_ref_operand" "s")))))]
   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
   "addi %0,%1,%2-%3@l")
 
@@ -10639,11 +10251,10 @@
 ;; On Darwin, we need to reload the picbase.
 
 (define_expand "builtin_setjmp_receiver"
-  [(use (label_ref (match_operand 0 "" "")))]
+  [(use (label_ref (match_operand 0 "")))]
   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
    || (TARGET_TOC && TARGET_MINIMAL_TOC)
    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
-  "
 {
 #if TARGET_MACHO
   if (DEFAULT_ABI == ABI_DARWIN)
@@ -10654,7 +10265,7 @@
       char tmplab[20];
 
       crtl->uses_pic_offset_table = 1;
-      ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
+      ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
 				  CODE_LABEL_NUMBER (operands[0]));
       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
 
@@ -10666,7 +10277,7 @@
 #endif
     rs6000_emit_load_toc_table (FALSE);
   DONE;
-}")
+})
 
 ;; Largetoc support
 (define_insn "*largetoc_high"
@@ -10751,12 +10362,11 @@
 
 ;; Call and call_value insns
 (define_expand "call"
-  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
-		    (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
+  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
+		    (match_operand 1 ""))
+	      (use (match_operand 2 ""))
 	      (clobber (reg:SI LR_REGNO))])]
   ""
-  "
 {
 #if TARGET_MACHO
   if (MACHOPIC_INDIRECT)
@@ -10791,16 +10401,15 @@
 	  gcc_unreachable ();
 	}
     }
-}")
+})
 
 (define_expand "call_value"
-  [(parallel [(set (match_operand 0 "" "")
-		   (call (mem:SI (match_operand 1 "address_operand" ""))
-			 (match_operand 2 "" "")))
-	      (use (match_operand 3 "" ""))
+  [(parallel [(set (match_operand 0 "")
+		   (call (mem:SI (match_operand 1 "address_operand"))
+			 (match_operand 2 "")))
+	      (use (match_operand 3 ""))
 	      (clobber (reg:SI LR_REGNO))])]
   ""
-  "
 {
 #if TARGET_MACHO
   if (MACHOPIC_INDIRECT)
@@ -10835,7 +10444,7 @@
 	  gcc_unreachable ();
 	}
     }
-}")
+})
 
 ;; Call to function in current module.  No TOC pointer reload needed.
 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
@@ -10849,16 +10458,15 @@
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (clobber (reg:SI LR_REGNO))]
   "(INTVAL (operands[2]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -10868,16 +10476,15 @@
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -10888,16 +10495,15 @@
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (clobber (reg:SI LR_REGNO))]
   "(INTVAL (operands[3]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -10909,16 +10515,15 @@
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -10943,10 +10548,24 @@
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn ("creqv 6,6,6", operands);
 
-  return "b%T0l";
+  if (rs6000_speculate_indirect_jumps
+      || which_alternative == 1 || which_alternative == 3)
+    return "b%T0l";
+  else
+    return "crset 2\;beq%T0l-";
 }
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
-   (set_attr "length" "4,4,8,8")])
+   (set_attr_alternative "length"
+     [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "8")
+		    (const_string "4"))
+      (const_string "4")
+      (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "12")
+		    (const_string "8"))
+      (const_string "8")])])
 
 (define_insn_and_split "*call_nonlocal_sysv<mode>"
   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
@@ -11031,10 +10650,24 @@
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn ("creqv 6,6,6", operands);
 
-  return "b%T1l";
+  if (rs6000_speculate_indirect_jumps
+      || which_alternative == 1 || which_alternative == 3)
+    return "b%T1l";
+  else
+    return "crset 2\;beq%T1l-";
 }
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
-   (set_attr "length" "4,4,8,8")])
+   (set_attr_alternative "length"
+     [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "8")
+		    (const_string "4"))
+      (const_string "4")
+      (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "12")
+		    (const_string "8"))
+      (const_string "8")])])
 
 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
@@ -11113,8 +10746,7 @@
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z0"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*call_value_local_aix<mode>"
   [(set (match_operand 0 "" "")
@@ -11123,8 +10755,7 @@
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
   "bl %z1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 ;; Call to AIX abi function which may be in another module.
 ;; Restore the TOC pointer (r2) after the call.
@@ -11159,11 +10790,22 @@
    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
+(define_insn "*call_indirect_aix<mode>_nospec"
+  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
+	 (match_operand 1 "" "g,g"))
+   (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
+   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
+   (clobber (reg:P LR_REGNO))]
+  "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
+  "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "16")])
+
 (define_insn "*call_value_indirect_aix<mode>"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
@@ -11171,11 +10813,23 @@
    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX"
+  "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
+(define_insn "*call_value_indirect_aix<mode>_nospec"
+  [(set (match_operand 0 "" "")
+	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
+	      (match_operand 2 "" "g,g")))
+   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
+   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
+   (clobber (reg:P LR_REGNO))]
+  "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
+  "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "16")])
+
 ;; Call to indirect functions with the ELFv2 ABI.
 ;; Operand0 is the addresss of the function to call
 ;; Operand2 is the offset of the stack location holding the current TOC pointer
@@ -11185,31 +10839,52 @@
 	 (match_operand 1 "" "g,g"))
    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_ELFv2"
+  "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
   "b%T0l\;<ptrload> 2,%2(1)"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "8")])
 
+;; Variant with deliberate misprediction.
+(define_insn "*call_indirect_elfv2<mode>_nospec"
+  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
+	 (match_operand 1 "" "g,g"))
+   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
+   (clobber (reg:P LR_REGNO))]
+  "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
+  "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "12")])
+
 (define_insn "*call_value_indirect_elfv2<mode>"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
 	      (match_operand 2 "" "g,g")))
    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
    (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_ELFv2"
+  "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
   "b%T1l\;<ptrload> 2,%3(1)"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "8")])
 
+; Variant with deliberate misprediction.
+(define_insn "*call_value_indirect_elfv2<mode>_nospec"
+  [(set (match_operand 0 "" "")
+	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
+	      (match_operand 2 "" "g,g")))
+   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
+   (clobber (reg:P LR_REGNO))]
+  "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
+  "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "12")])
 
 ;; Call subroutine returning any type.
 (define_expand "untyped_call"
-  [(parallel [(call (match_operand 0 "" "")
+  [(parallel [(call (match_operand 0 "")
 		    (const_int 0))
-	      (match_operand 1 "" "")
-	      (match_operand 2 "" "")])]
-  ""
-  "
+	      (match_operand 1 "")
+	      (match_operand 2 "")])]
+  ""
 {
   int i;
 
@@ -11228,16 +10903,15 @@
   emit_insn (gen_blockage ());
 
   DONE;
-}")
+})
 
 ;; sibling call patterns
 (define_expand "sibcall"
-  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
-		    (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
+  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
+		    (match_operand 1 ""))
+	      (use (match_operand 2 ""))
 	      (simple_return)])]
   ""
-  "
 {
 #if TARGET_MACHO
   if (MACHOPIC_INDIRECT)
@@ -11254,16 +10928,15 @@
       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
     }
-}")
+})
 
 (define_expand "sibcall_value"
-  [(parallel [(set (match_operand 0 "register_operand" "")
-		(call (mem:SI (match_operand 1 "address_operand" ""))
-		      (match_operand 2 "" "")))
-	      (use (match_operand 3 "" ""))
+  [(parallel [(set (match_operand 0 "register_operand")
+		(call (mem:SI (match_operand 1 "address_operand"))
+		      (match_operand 2 "")))
+	      (use (match_operand 3 ""))
 	      (simple_return)])]
   ""
-  "
 {
 #if TARGET_MACHO
   if (MACHOPIC_INDIRECT)
@@ -11280,7 +10953,7 @@
       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
       DONE;
     }
-}")
+})
 
 (define_insn "*sibcall_local32"
   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
@@ -11288,16 +10961,15 @@
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (simple_return)]
   "(INTVAL (operands[2]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -11307,16 +10979,15 @@
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (simple_return)]
   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -11327,16 +10998,15 @@
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (simple_return)]
   "(INTVAL (operands[3]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -11347,16 +11017,15 @@
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (simple_return)]
   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
-
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
-}"
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
+}
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
@@ -11368,26 +11037,41 @@
   "(DEFAULT_ABI == ABI_DARWIN
     || DEFAULT_ABI == ABI_V4)
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
+    output_asm_insn ("creqv 6,6,6", operands);
 
   if (which_alternative >= 2)
-    return \"b%T0\";
+    {
+      if (rs6000_speculate_indirect_jumps)
+	return "b%T0";
+      else
+	/* Can use CR0 since it is volatile across sibcalls.  */
+	return "crset 2\;beq%T0-\;b $";
+    }
   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
-      return \"b %z0@plt\";
-    }
-  else
-    return \"b %z0\";
-}"
+      return "b %z0@plt";
+    }
+  else
+    return "b %z0";
+}
   [(set_attr "type" "branch")
-   (set_attr "length" "4,8,4,8")])
+   (set_attr_alternative "length"
+     [(const_string "4")
+      (const_string "8")
+      (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "12")
+		    (const_string "4"))
+      (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "16")
+		    (const_string "8"))])])
 
 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
@@ -11398,26 +11082,41 @@
   "(DEFAULT_ABI == ABI_DARWIN
     || DEFAULT_ABI == ABI_V4)
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
-  "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn ("crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
+    output_asm_insn ("creqv 6,6,6", operands);
 
   if (which_alternative >= 2)
-    return \"b%T1\";
+    {
+      if (rs6000_speculate_indirect_jumps)
+	return "b%T1";
+      else
+	/* Can use CR0 since it is volatile across sibcalls.  */
+	return "crset 2\;beq%T1-\;b $";
+    }
   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
-      return \"b %z1@plt\";
-    }
-  else
-    return \"b %z1\";
-}"
+      return "b %z1@plt";
+    }
+  else
+    return "b %z1";
+}
   [(set_attr "type" "branch")
-   (set_attr "length" "4,8,4,8")])
+   (set_attr_alternative "length"
+     [(const_string "4")
+      (const_string "8")
+      (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "12")
+		    (const_string "4"))
+      (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
+			(const_int 0))
+		    (const_string "16")
+		    (const_string "8"))])])
 
 ;; AIX ABI sibling call patterns.
 
@@ -11429,8 +11128,7 @@
   "@
    b %z0
    b%T0"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*sibcall_value_aix<mode>"
   [(set (match_operand 0 "" "")
@@ -11441,8 +11139,7 @@
   "@
    b %z1
    b%T1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 <<<<<<< local
 =======
@@ -11598,7 +11295,8 @@
 (define_insn "blockage"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
   ""
-  "")
+  ""
+  [(set_attr "length" "0")])
 
 (define_expand "probe_stack_address"
   [(use (match_operand 0 "address_operand"))]
@@ -11630,8 +11328,7 @@
    (set (attr "indexed")
 	(if_then_else (match_operand 0 "indexed_address_mem")
 		      (const_string "yes")
-		      (const_string "no")))
-   (set_attr "length" "4")])
+		      (const_string "no")))])
 
 (define_insn "probe_stack_range<P:mode>"
   [(set (match_operand:P 0 "register_operand" "=&r")
@@ -11651,11 +11348,10 @@
 
 (define_expand "cbranch<mode>4"
   [(use (match_operator 0 "comparison_operator"
-         [(match_operand:GPR 1 "gpc_reg_operand" "")
-          (match_operand:GPR 2 "reg_or_short_operand" "")]))
-   (use (match_operand 3 ""))]
-  ""
-  "
+         [(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.  */
@@ -11670,19 +11366,18 @@
 
   rs6000_emit_cbranch (<MODE>mode, operands);
   DONE;
-}")
+})
 
 (define_expand "cbranch<mode>4"
   [(use (match_operator 0 "comparison_operator"
-         [(match_operand:FP 1 "gpc_reg_operand" "")
-          (match_operand:FP 2 "gpc_reg_operand" "")]))
-   (use (match_operand 3 ""))]
-  ""
-  "
+         [(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 "cstore<mode>4_signed"
   [(use (match_operator 1 "signed_comparison_operator"
@@ -11909,13 +11604,9 @@
    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
   ""
 {
-  /* Use ISEL if the user asked for it.  */
-  if (TARGET_ISEL)
-    rs6000_emit_sISEL (<MODE>mode, operands);
-
   /* Expanding EQ and NE directly to some machine instructions does not help
      but does hurt combine.  So don't.  */
-  else if (GET_CODE (operands[1]) == EQ)
+  if (GET_CODE (operands[1]) == EQ)
     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
   else if (<MODE>mode == Pmode
 	   && GET_CODE (operands[1]) == NE)
@@ -11927,7 +11618,11 @@
       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
     }
 
-  /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
+  /* If ISEL is fast, expand to it.  */
+  else if (TARGET_ISEL)
+    rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
+
+  /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
      etc. combinations magically work out just right.  */
   else if (<MODE>mode == Pmode
 	   && unsigned_comparison_operator (operands[1], VOIDmode))
@@ -12094,18 +11789,18 @@
 
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand")
-        (match_operand:SI 1 "logical_const_operand" ""))
+        (match_operand:SI 1 "logical_const_operand"))
    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
 		       [(match_dup 0)
-			(match_operand:SI 2 "logical_const_operand" "")]))
-   (set (match_operand:CC 4 "cc_reg_operand" "")
-        (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
+			(match_operand:SI 2 "logical_const_operand")]))
+   (set (match_operand:CC 4 "cc_reg_operand")
+        (compare:CC (match_operand:SI 5 "gpc_reg_operand")
                     (match_dup 0)))
    (set (pc)
         (if_then_else (match_operator 6 "equality_operator"
                        [(match_dup 4) (const_int 0)])
-                      (match_operand 7 "" "")
-                      (match_operand 8 "" "")))]
+                      (match_operand 7 "")
+                      (match_operand 8 "")))]
   "peep2_reg_dead_p (3, operands[0])
    && peep2_reg_dead_p (4, operands[4])
    && REGNO (operands[0]) != REGNO (operands[5])"
@@ -12128,58 +11823,13 @@
   operands[10] = GEN_INT (sextc);
 })
 
-;; The following two insns don't exist as single insns, but if we provide
-;; them, we can swap an add and compare, which will enable us to overlap more
-;; of the required delay between a compare and branch.  We generate code for
-;; them by splitting.
-
-(define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
-	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
-		    (match_operand:SI 2 "short_cint_operand" "i")))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
-  ""
-  "#"
-  [(set_attr "length" "8")])
-
-(define_insn ""
-  [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
-	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
-		       (match_operand:SI 2 "u_short_cint_operand" "i")))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
-  ""
-  "#"
-  [(set_attr "length" "8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_operand" "")
-	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
-		    (match_operand:SI 2 "short_cint_operand" "")))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
-  ""
-  [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
-   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
-
-(define_split
-  [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
-	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
-		       (match_operand:SI 2 "u_short_cint_operand" "")))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
-  ""
-  [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
-   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
-
 ;; Only need to compare second words if first words equal
 (define_insn "*cmp<mode>_internal1"
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
 	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
 		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
-   && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
    (set_attr "length" "12")])
@@ -12198,7 +11848,7 @@
     (clobber (match_scratch:DF 10 "=d"))
     (clobber (match_scratch:GPR 11 "=b"))]
   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
-   && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 14))
@@ -12253,10 +11903,10 @@
 ;; cases the insns below which don't use an intermediate CR field will
 ;; be used instead.
 (define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(match_operator:SI 1 "scc_comparison_operator"
-			   [(match_operand 2 "cc_reg_operand" "y")
-			    (const_int 0)]))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(match_operator:GPR 1 "scc_comparison_operator"
+			    [(match_operand 2 "cc_reg_operand" "y")
+			     (const_int 0)]))]
   ""
   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
   [(set (attr "type")
@@ -12266,31 +11916,7 @@
 	(const_string "mfcr")))
    (set_attr "length" "8")])
 
-;; Same as above, but get the OV/ORDERED bit.
-(define_insn "move_from_CR_ov_bit"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
-		   UNSPEC_MV_CR_OV))]
-  "TARGET_ISEL"
-  "mfcr %0\;rlwinm %0,%0,%t1,1"
-  [(set_attr "type" "mfcr")
-   (set_attr "length" "8")])
-
-(define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(match_operator:DI 1 "scc_comparison_operator"
-			   [(match_operand 2 "cc_reg_operand" "y")
-			    (const_int 0)]))]
-  "TARGET_POWERPC64"
-  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
-  [(set (attr "type")
-     (cond [(match_test "TARGET_MFCRF")
-		(const_string "mfcrf")
-	   ]
-	(const_string "mfcr")))
-   (set_attr "length" "8")])
-
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
 				       [(match_operand 2 "cc_reg_operand" "y,y")
@@ -12302,25 +11928,16 @@
   "@
    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
    #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "8,16")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
-	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
-				       [(match_operand 2 "cc_reg_operand" "")
-					(const_int 0)])
-		    (const_int 0)))
-   (set (match_operand:SI 3 "gpc_reg_operand" "")
-	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
-  "TARGET_32BIT && reload_completed"
+  "&& reload_completed"
   [(set (match_dup 3)
 	(match_op_dup 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
 	(compare:CC (match_dup 3)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "shift")
+   (set_attr "dot" "yes")
+   (set_attr "length" "8,16")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -12329,7 +11946,6 @@
 				       (const_int 0)])
 		   (match_operand:SI 3 "const_int_operand" "n")))]
   ""
-  "*
 {
   int is_bit = ccr_bit (operands[1], 1);
   int put_bit = 31 - (INTVAL (operands[3]) & 31);
@@ -12343,8 +11959,8 @@
   operands[4] = GEN_INT (count);
   operands[5] = GEN_INT (put_bit);
 
-  return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
-}"
+  return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
+}
   [(set (attr "type")
      (cond [(match_test "TARGET_MFCRF")
 		(const_string "mfcrf")
@@ -12364,7 +11980,6 @@
 	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
 		   (match_dup 3)))]
   ""
-  "*
 {
   int is_bit = ccr_bit (operands[1], 1);
   int put_bit = 31 - (INTVAL (operands[3]) & 31);
@@ -12372,7 +11987,7 @@
 
   /* Force split for non-cc0 compare.  */
   if (which_alternative == 1)
-     return \"#\";
+     return "#";
 
   if (is_bit >= put_bit)
     count = is_bit - put_bit;
@@ -12382,8 +11997,8 @@
   operands[5] = GEN_INT (count);
   operands[6] = GEN_INT (put_bit);
 
-  return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
-}"
+  return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
+}
   [(set_attr "type" "shift")
    (set_attr "dot" "yes")
    (set_attr "length" "8,16")])
@@ -12409,18 +12024,130 @@
   "")
 
 
+(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
+(define_code_attr UNS [(eq "CC")
+		       (ne "CC")
+		       (lt "CC") (ltu "CCUNS")
+		       (gt "CC") (gtu "CCUNS")
+		       (le "CC") (leu "CCUNS")
+		       (ge "CC") (geu "CCUNS")])
+(define_code_attr UNSu_ [(eq "")
+			 (ne "")
+			 (lt "") (ltu "u_")
+			 (gt "") (gtu "u_")
+			 (le "") (leu "u_")
+			 (ge "") (geu "u_")])
+(define_code_attr UNSIK [(eq "I")
+			 (ne "I")
+			 (lt "I") (ltu "K")
+			 (gt "I") (gtu "K")
+			 (le "I") (leu "K")
+			 (ge "I") (geu "K")])
+
+(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
+		 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
+   (clobber (match_scratch:GPR 3 "=r"))
+   (clobber (match_scratch:GPR 4 "=r"))
+   (clobber (match_scratch:<UNS> 5 "=y"))]
+  "TARGET_ISEL
+   && !(<CODE> == EQ && operands[2] == const0_rtx)
+   && !(<CODE> == NE && operands[2] == const0_rtx
+	&& <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
+  "#"
+  "&& 1"
+  [(pc)]
+{
+  rtx_code code = <CODE>;
+  if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
+    {
+      HOST_WIDE_INT val = INTVAL (operands[2]);
+      if (code == LT && val != -0x8000)
+	{
+	  code = LE;
+	  val--;
+	}
+      if (code == GT && val != 0x7fff)
+	{
+	  code = GE;
+	  val++;
+	}
+      if (code == LTU && val != 0)
+	{
+	  code = LEU;
+	  val--;
+	}
+      if (code == GTU && val != 0xffff)
+	{
+	  code = GEU;
+	  val++;
+	}
+      operands[2] = GEN_INT (val);
+    }
+
+  if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
+    operands[3] = const0_rtx;
+  else
+    {
+      if (GET_CODE (operands[3]) == SCRATCH)
+	operands[3] = gen_reg_rtx (<GPR:MODE>mode);
+      emit_move_insn (operands[3], const0_rtx);
+    }
+
+  if (GET_CODE (operands[4]) == SCRATCH)
+    operands[4] = gen_reg_rtx (<GPR:MODE>mode);
+  emit_move_insn (operands[4], const1_rtx);
+
+  if (GET_CODE (operands[5]) == SCRATCH)
+    operands[5] = gen_reg_rtx (<UNS>mode);
+
+  rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
+  emit_insn (gen_rtx_SET (operands[5], c1));
+
+  rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
+  rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
+  emit_move_insn (operands[0], x);
+
+  DONE;
+}
+  [(set (attr "cost")
+	(if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
+				   || <CODE> == NE
+				   || <CODE> == LE || <CODE> == GE
+				   || <CODE> == LEU || <CODE> == GEU")
+		      (const_string "9")
+		      (const_string "10")))])
+
 (define_mode_attr scc_eq_op2 [(SI "rKLI")
 			      (DI "rKJI")])
 
-(define_insn_and_split "eq<mode>3"
+(define_expand "eq<mode>3"
+  [(parallel [
+     (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	  (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+		  (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
+     (clobber (match_scratch:GPR 3 "=r"))
+     (clobber (match_scratch:GPR 4 "=r"))])]
+  ""
+{
+  if (TARGET_ISEL && operands[2] != const0_rtx)
+    {
+      emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
+					   operands[2]));
+      DONE;
+    }
+})
+
+(define_insn_and_split "*eq<mode>3"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
 	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
 		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
    (clobber (match_scratch:GPR 3 "=r"))
    (clobber (match_scratch:GPR 4 "=r"))]
-  ""
-  "#"
-  ""
+  "!(TARGET_ISEL && operands[2] != const0_rtx)"
+  "#"
+  "&& 1"
   [(set (match_dup 4)
 	(clz:GPR (match_dup 3)))
    (set (match_dup 0)
@@ -12440,16 +12167,34 @@
 		      (const_string "8")
 		      (const_string "12")))])
 
-(define_insn_and_split "ne<mode>3"
+(define_expand "ne<mode>3"
+  [(parallel [
+     (set (match_operand:P 0 "gpc_reg_operand" "=r")
+	  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
+		(match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
+     (clobber (match_scratch:P 3 "=r"))
+     (clobber (match_scratch:P 4 "=r"))
+     (clobber (reg:P CA_REGNO))])]
+  ""
+{
+  if (TARGET_ISEL && operands[2] != const0_rtx)
+    {
+      emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
+					   operands[2]));
+      DONE;
+    }
+})
+
+(define_insn_and_split "*ne<mode>3"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
 	(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
 	      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
    (clobber (match_scratch:P 3 "=r"))
    (clobber (match_scratch:P 4 "=r"))
    (clobber (reg:P CA_REGNO))]
-  "!TARGET_ISEL"
-  "#"
-  ""
+  "!(TARGET_ISEL && operands[2] != const0_rtx)"
+  "#"
+  "&& 1"
   [(parallel [(set (match_dup 4)
 		   (plus:P (match_dup 3)
 			   (const_int -1)))
@@ -12702,9 +12447,9 @@
    (clobber (match_scratch:SI 3 "=r"))
    (clobber (match_scratch:SI 4 "=r"))
    (clobber (match_scratch:EXTSI 5 "=r"))]
-  ""
-  "#"
-  ""
+  "!TARGET_ISEL"
+  "#"
+  "&& 1"
   [(set (match_dup 4)
 	(clz:SI (match_dup 3)))
    (set (match_dup 5)
@@ -12728,11 +12473,10 @@
 		      (const_string "12")
 		      (const_string "16")))])
 
-;; Define both directions of branch and return.  If we need a reload
-;; register, we'd rather use CR0 since it is much easier to copy a
-;; register CC value to there.
-
-(define_insn ""
+;; Conditional branches.
+;; These either are a single bc insn, or a bc around a b.
+
+(define_insn "*cbranch"
   [(set (pc)
 	(if_then_else (match_operator 1 "branch_comparison_operator"
 				      [(match_operand 2 "cc_reg_operand" "y")
@@ -12743,9 +12487,17 @@
 {
   return output_cbranch (operands[1], "%l0", 0, insn);
 }
-  [(set_attr "type" "branch")])
-
-(define_insn ""
+  [(set_attr "type" "branch")
+   (set (attr "length")
+	(if_then_else (and (ge (minus (match_dup 0) (pc))
+			       (const_int -32768))
+			   (lt (minus (match_dup 0) (pc))
+			       (const_int 32764)))
+		      (const_int 4)
+		      (const_int 8)))])
+
+;; Conditional return.
+(define_insn "*creturn"
   [(set (pc)
 	(if_then_else (match_operator 0 "branch_comparison_operator"
 				      [(match_operand 1 "cc_reg_operand" "y")
@@ -12756,8 +12508,7 @@
 {
   return output_cbranch (operands[0], NULL, 0, insn);
 }
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "4")])
+  [(set_attr "type" "jmpreg")])
 
 ;; Logic on condition register values.
 
@@ -12768,7 +12519,7 @@
 ; which are generated by the branch logic.
 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
 
-(define_insn "*cceq_ior_compare"
+(define_insn "cceq_ior_compare"
   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
 	                [(match_operator:SI 2
@@ -12784,13 +12535,14 @@
 		      (const_int 1)))]
   ""
   "cr%q1 %E0,%j2,%j4"
-  [(set_attr "type" "cr_logical,delayed_cr")])
+  [(set_attr "type" "cr_logical")
+   (set_attr "cr_logical_3op" "no,yes")])
 
 ; Why is the constant -1 here, but 1 in the previous pattern?
 ; Because ~1 has all but the low bit set.
-(define_insn ""
+(define_insn "cceq_ior_compare_complement"
   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
-        (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
+        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
 	                [(not:SI (match_operator:SI 2
 				      "branch_positive_comparison_operator"
 				      [(match_operand 3
@@ -12804,7 +12556,8 @@
 		      (const_int -1)))]
   ""
   "cr%q1 %E0,%j2,%j4"
-  [(set_attr "type" "cr_logical,delayed_cr")])
+  [(set_attr "type" "cr_logical")
+   (set_attr "cr_logical_3op" "no,yes")])
 
 (define_insn "*cceq_rev_compare"
   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
@@ -12816,7 +12569,8 @@
 		      (const_int 0)))]
   ""
   "crnot %E0,%j1"
-  [(set_attr "type" "cr_logical,delayed_cr")])
+  [(set_attr "type" "cr_logical")
+   (set_attr "cr_logical_3op" "no,yes")])
 
 ;; If we are comparing the result of two comparisons, this can be done
 ;; using creqv or crxor.
@@ -12834,7 +12588,6 @@
   ""
   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
 				    (match_dup 5)))]
-  "
 {
   int positive_1, positive_2;
 
@@ -12870,7 +12623,7 @@
     {
       operands[5] = const1_rtx;
     }
-}")
+})
 
 ;; Unconditional branch and return.
 
@@ -12888,25 +12641,57 @@
   [(set_attr "type" "jmpreg")])
 
 (define_expand "indirect_jump"
-  [(set (pc) (match_operand 0 "register_operand"))])
+  [(set (pc) (match_operand 0 "register_operand"))]
+ ""
+{
+  if (!rs6000_speculate_indirect_jumps) {
+    rtx ccreg = gen_reg_rtx (CCmode);
+    if (Pmode == DImode)
+      emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
+    else
+      emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
+    DONE;
+  }
+})
 
 (define_insn "*indirect_jump<mode>"
   [(set (pc)
 	(match_operand:P 0 "register_operand" "c,*l"))]
-  ""
+  "rs6000_speculate_indirect_jumps"
   "b%T0"
   [(set_attr "type" "jmpreg")])
 
+(define_insn "indirect_jump<mode>_nospec"
+  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
+   (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
+  "!rs6000_speculate_indirect_jumps"
+  "crset %E1\;beq%T0- %1\;b $"
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "12")])
+
 ;; Table jump for switch statements:
 (define_expand "tablejump"
   [(use (match_operand 0))
    (use (label_ref (match_operand 1)))]
   ""
 {
-  if (TARGET_32BIT)
-    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
-  else
-    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+  if (rs6000_speculate_indirect_jumps)
+    {
+      if (TARGET_32BIT)
+      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+      else
+	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+    }
+  else
+    {
+      rtx ccreg = gen_reg_rtx (CCmode);
+      rtx jump;
+      if (TARGET_32BIT)
+	jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+      else
+	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+      emit_jump_insn (jump);
+    }
   DONE;
 })
 
@@ -12917,13 +12702,28 @@
    (parallel [(set (pc)
 		   (match_dup 3))
 	      (use (label_ref (match_operand 1)))])]
-  "TARGET_32BIT"
+  "TARGET_32BIT && rs6000_speculate_indirect_jumps"
 {
   operands[0] = force_reg (SImode, operands[0]);
   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
   operands[3] = gen_reg_rtx (SImode);
 })
 
+(define_expand "tablejumpsi_nospec"
+  [(set (match_dup 4)
+	(plus:SI (match_operand:SI 0)
+		 (match_dup 3)))
+   (parallel [(set (pc)
+		   (match_dup 4))
+	      (use (label_ref (match_operand 1)))
+	      (clobber (match_operand 2))])]
+  "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
+{
+  operands[0] = force_reg (SImode, operands[0]);
+  operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
+  operands[4] = gen_reg_rtx (SImode);
+})
+
 (define_expand "tablejumpdi"
   [(set (match_dup 4)
         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
@@ -12933,21 +12733,48 @@
    (parallel [(set (pc)
 		   (match_dup 3))
 	      (use (label_ref (match_operand 1)))])]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_speculate_indirect_jumps"
 {
   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
 })
 
+(define_expand "tablejumpdi_nospec"
+  [(set (match_dup 5)
+        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
+   (set (match_dup 4)
+	(plus:DI (match_dup 5)
+		 (match_dup 3)))
+   (parallel [(set (pc)
+		   (match_dup 4))
+	      (use (label_ref (match_operand 1)))
+	      (clobber (match_operand 2))])]
+  "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
+{
+  operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
+  operands[4] = gen_reg_rtx (DImode);
+  operands[5] = gen_reg_rtx (DImode);
+})
+
 (define_insn "*tablejump<mode>_internal1"
   [(set (pc)
 	(match_operand:P 0 "register_operand" "c,*l"))
    (use (label_ref (match_operand 1)))]
-  ""
+  "rs6000_speculate_indirect_jumps"
   "b%T0"
   [(set_attr "type" "jmpreg")])
 
+(define_insn "*tablejump<mode>_internal1_nospec"
+  [(set (pc)
+	(match_operand:P 0 "register_operand" "c,*l"))
+   (use (label_ref (match_operand 1)))
+   (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
+  "!rs6000_speculate_indirect_jumps"
+  "crset %E2\;beq%T0- %2\;b $"
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "12")])
+
 (define_insn "nop"
   [(unspec [(const_int 0)] UNSPEC_NOP)]
   ""
@@ -12957,10 +12784,15 @@
   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
   ""
 {
-  if (rs6000_cpu_attr == CPU_POWER6)
+  if (rs6000_tune == PROCESSOR_POWER6)
     return "ori 1,1,0";
   return "ori 2,2,0";
 })
+
+(define_insn "speculation_barrier"
+  [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
+  ""
+  "ori 31,31,0")
 
 ;; Define the subtract-one-and-jump insns, starting with the template
 ;; so loop.c knows what to generate.
@@ -13007,34 +12839,13 @@
 ;; rs6000_legitimate_combined_insn prevents combine creating any of
 ;; the ctr<mode> insns.
 
-(define_insn "ctr<mode>_internal1"
+(define_code_iterator eqne [eq ne])
+(define_code_attr bd [(eq "bdz") (ne "bdnz")])
+(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
+
+(define_insn "<bd>_<mode>"
   [(set (pc)
-	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
-			  (const_int 1))
-		      (label_ref (match_operand 0))
-		      (pc)))
-   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
-	(plus:P (match_dup 1)
-		(const_int -1)))
-   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
-   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
-  ""
-{
-  if (which_alternative != 0)
-    return "#";
-  else if (get_attr_length (insn) == 4)
-    return "bdnz %l0";
-  else
-    return "bdz $+8\;b %l0";
-}
-  [(set_attr "type" "branch")
-   (set_attr "length" "*,16,20,20")])
-
-;; Similar but use EQ
-
-(define_insn "ctr<mode>_internal2"
-  [(set (pc)
-	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
+	(if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
 			  (const_int 1))
 		      (label_ref (match_operand 0))
 		      (pc)))
@@ -13048,43 +12859,23 @@
   if (which_alternative != 0)
     return "#";
   else if (get_attr_length (insn) == 4)
-    return "bdz %l0";
-  else
-    return "bdnz $+8\;b %l0";
+    return "<bd> %l0";
+  else
+    return "<bd_neg> $+8\;b %l0";
 }
   [(set_attr "type" "branch")
-   (set_attr "length" "*,16,20,20")])
-
-;; Now the splitters if we could not allocate the CTR register
-
-(define_split
-  [(set (pc)
-	(if_then_else (match_operator 2 "comparison_operator"
-				      [(match_operand:P 1 "gpc_reg_operand")
-				       (const_int 1)])
-		      (match_operand 5)
-		      (match_operand 6)))
-   (set (match_operand:P 0 "int_reg_operand")
-	(plus:P (match_dup 1)
-		(const_int -1)))
-   (clobber (match_scratch:CC 3))
-   (clobber (match_scratch:P 4))]
-  "reload_completed"
-  [(set (match_dup 3)
-	(compare:CC (match_dup 1)
-		    (const_int 1)))
-   (set (match_dup 0)
-	(plus:P (match_dup 1)
-		(const_int -1)))
-   (set (pc)
-	(if_then_else (match_dup 7)
-		      (match_dup 5)
-		      (match_dup 6)))]
-{
-  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
-				const0_rtx);
-})
-
+   (set_attr_alternative "length"
+     [(if_then_else (and (ge (minus (match_dup 0) (pc))
+			     (const_int -32768))
+			 (lt (minus (match_dup 0) (pc))
+			     (const_int 32764)))
+		    (const_int 4)
+		    (const_int 8))
+      (const_string "16")
+      (const_string "20")
+      (const_string "20")])])
+
+;; Now the splitter if we could not allocate the CTR register
 (define_split
   [(set (pc)
 	(if_then_else (match_operator 2 "comparison_operator"
@@ -13097,23 +12888,141 @@
 		(const_int -1)))
    (clobber (match_scratch:CC 3))
    (clobber (match_scratch:P 4))]
-  "reload_completed && !gpc_reg_operand (operands[0], SImode)"
-  [(set (match_dup 3)
-	(compare:CC (match_dup 1)
-		    (const_int 1)))
-   (set (match_dup 4)
-	(plus:P (match_dup 1)
-		(const_int -1)))
-   (set (match_dup 0)
-	(match_dup 4))
-   (set (pc)
+  "reload_completed"
+  [(set (pc)
 	(if_then_else (match_dup 7)
 		      (match_dup 5)
 		      (match_dup 6)))]
 {
   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
 				const0_rtx);
-})
+  emit_insn (gen_rtx_SET (operands[3],
+			  gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
+  if (gpc_reg_operand (operands[0], <MODE>mode))
+    emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
+  else
+    {
+      emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
+      emit_move_insn (operands[0], operands[4]);
+    } 
+    /* No DONE so branch comes from the pattern.  */
+})
+
+;; patterns for bdnzt/bdnzf/bdzt/bdzf
+;; Note that in the case of long branches we have to decompose this into
+;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
+;; and the CR bit, which means there is no way to conveniently invert the
+;; comparison as is done with plain bdnz/bdz.
+
+(define_insn "<bd>tf_<mode>"
+  [(set (pc)
+	(if_then_else
+	  (and
+	     (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
+		   (const_int 1))
+	     (match_operator 3 "branch_comparison_operator"
+		      [(match_operand 4 "cc_reg_operand" "y,y,y,y")
+		       (const_int 0)]))
+	  (label_ref (match_operand 0))
+	  (pc)))
+   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
+	(plus:P (match_dup 1)
+		(const_int -1)))
+   (clobber (match_scratch:P 5 "=X,X,&r,r"))
+   (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
+   (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
+  ""
+{
+  if (which_alternative != 0)
+    return "#";
+  else if (get_attr_length (insn) == 4)
+    {
+      if (branch_positive_comparison_operator (operands[3],
+					       GET_MODE (operands[3])))
+	return "<bd>t %j3,%l0";
+      else
+	return "<bd>f %j3,%l0";
+    }
+  else
+    {
+      static char seq[96];
+      char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
+      sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
+      return seq;
+    }
+}
+  [(set_attr "type" "branch")
+   (set_attr_alternative "length"
+     [(if_then_else (and (ge (minus (match_dup 0) (pc))
+			     (const_int -32768))
+			 (lt (minus (match_dup 0) (pc))
+			     (const_int 32764)))
+		    (const_int 4)
+		    (const_int 8))
+      (const_string "16")
+      (const_string "20")
+      (const_string "20")])])
+
+;; Now the splitter if we could not allocate the CTR register
+(define_split
+  [(set (pc)
+	(if_then_else
+	  (and
+	     (match_operator 1 "comparison_operator"
+			     [(match_operand:P 0 "gpc_reg_operand")
+			      (const_int 1)])
+	     (match_operator 3 "branch_comparison_operator"
+		      [(match_operand 2 "cc_reg_operand")
+		       (const_int 0)]))
+	  (match_operand 4)
+	  (match_operand 5)))
+   (set (match_operand:P 6 "int_reg_operand")
+	(plus:P (match_dup 0)
+		(const_int -1)))
+   (clobber (match_scratch:P 7))
+   (clobber (match_scratch:CC 8))
+   (clobber (match_scratch:CCEQ 9))]
+  "reload_completed"
+[(pc)]
+{
+  rtx ctr = operands[0];
+  rtx ctrcmp = operands[1];
+  rtx ccin = operands[2];
+  rtx cccmp = operands[3];
+  rtx dst1 = operands[4];
+  rtx dst2 = operands[5];
+  rtx ctrout = operands[6];
+  rtx ctrtmp = operands[7];
+  enum rtx_code cmpcode = GET_CODE (ctrcmp);
+  bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
+  if (!ispos)
+    cmpcode = reverse_condition (cmpcode);
+  /* Generate crand/crandc here.  */
+  emit_insn (gen_rtx_SET (operands[8],
+			  gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
+  rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
+
+  rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
+  if (ispos)
+     emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
+				      operands[8], cccmp, ccin));
+  else
+     emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
+						 operands[8], cccmp, ccin));
+  if (gpc_reg_operand (operands[0], <MODE>mode))
+     emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
+  else
+    {
+      emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
+      emit_move_insn (ctrout, ctrtmp);
+    }
+  rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
+  emit_jump_insn (gen_rtx_SET (pc_rtx,
+			       gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
+						     dst1, dst2)));
+  DONE;
+})
+
 
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 0))]
@@ -13157,7 +13066,6 @@
 				     (match_operand 3 "immediate_operand" "n")]
 			  UNSPEC_MOVESI_FROM_CR))])]
   "TARGET_MFCRF"
-  "*
 {
   int mask = 0;
   int i;
@@ -13165,10 +13073,10 @@
   {
     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
     operands[4] = GEN_INT (mask);
-    output_asm_insn (\"mfcr %1,%4\", operands);
+    output_asm_insn ("mfcr %1,%4", operands);
   }
-  return \"\";
-}"
+  return "";
+}
   [(set_attr "type" "mfcrf")])
 
 ;; Don't include the volatile CRs since their values are not used wrt CR save
@@ -13226,8 +13134,7 @@
 			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
   ""
   "bl %1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*save_gpregs_<mode>_r12"
   [(match_parallel 0 "any_parallel_operand"
@@ -13238,8 +13145,7 @@
 			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
   ""
   "bl %1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*save_gpregs_<mode>_r1"
   [(match_parallel 0 "any_parallel_operand"
@@ -13250,8 +13156,7 @@
 			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
   ""
   "bl %1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*save_fpregs_<mode>_r11"
   [(match_parallel 0 "any_parallel_operand"
@@ -13262,8 +13167,7 @@
 			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
   ""
   "bl %1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*save_fpregs_<mode>_r12"
   [(match_parallel 0 "any_parallel_operand"
@@ -13274,8 +13178,7 @@
 			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
   ""
   "bl %1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 (define_insn "*save_fpregs_<mode>_r1"
   [(match_parallel 0 "any_parallel_operand"
@@ -13286,8 +13189,7 @@
 			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
   ""
   "bl %1"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
+  [(set_attr "type" "branch")])
 
 ; This is to explain that changes to the stack pointer should
 ; not be moved over loads from or stores to stack memory.
@@ -13327,8 +13229,8 @@
 ; faster; for instance, on the 601 and 750.
 
 (define_expand "movsi_to_cr_one"
-  [(set (match_operand:CC 0 "cc_reg_operand" "")
-        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand")
+        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
 		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
   ""
   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
@@ -13340,15 +13242,14 @@
 				     (match_operand 3 "immediate_operand" "n")]
 				    UNSPEC_MOVESI_TO_CR))])]
  ""
- "*
 {
   int mask = 0;
   int i;
   for (i = 0; i < XVECLEN (operands[0], 0); i++)
     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
   operands[4] = GEN_INT (mask);
-  return \"mtcrf %4,%2\";
-}"
+  return "mtcrf %4,%2";
+}
   [(set_attr "type" "mtcr")])
 
 (define_insn "*mtcrfsi"
@@ -13378,8 +13279,7 @@
    (set_attr "indexed" "yes")
    (set_attr "cell_micro" "always")])
 
-; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
-; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
+; FIXME: "any_parallel_operand" is a bit flexible...
 
 ; The following comment applies to:
 ;     save_gpregs_*
@@ -13405,8 +13305,7 @@
 			(match_operand:P 3 "memory_operand" "m"))])]
  ""
  "bl %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*restore_gpregs_<mode>_r12"
  [(match_parallel 0 "any_parallel_operand"
@@ -13417,8 +13316,7 @@
 			(match_operand:P 3 "memory_operand" "m"))])]
  ""
  "bl %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*restore_gpregs_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
@@ -13429,8 +13327,7 @@
 			(match_operand:P 3 "memory_operand" "m"))])]
  ""
  "bl %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_gpregs_<mode>_r11"
  [(match_parallel 0 "any_parallel_operand"
@@ -13442,8 +13339,7 @@
 			(match_operand:P 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_gpregs_<mode>_r12"
  [(match_parallel 0 "any_parallel_operand"
@@ -13455,8 +13351,7 @@
 			(match_operand:P 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_gpregs_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
@@ -13468,8 +13363,7 @@
 			(match_operand:P 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_fpregs_<mode>_r11"
  [(match_parallel 0 "any_parallel_operand"
@@ -13481,8 +13375,7 @@
 			(match_operand:DF 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_fpregs_<mode>_r12"
  [(match_parallel 0 "any_parallel_operand"
@@ -13494,8 +13387,7 @@
 			(match_operand:DF 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_fpregs_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
@@ -13507,8 +13399,7 @@
 			(match_operand:DF 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
  [(match_parallel 0 "any_parallel_operand"
@@ -13519,8 +13410,7 @@
 			(match_operand:DF 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
@@ -13531,21 +13421,19 @@
 			(match_operand:DF 3 "memory_operand" "m"))])]
  ""
  "b %1"
- [(set_attr "type" "branch")
-  (set_attr "length" "4")])
+ [(set_attr "type" "branch")])
 
 ; This is used in compiling the unwind routines.
 (define_expand "eh_return"
-  [(use (match_operand 0 "general_operand" ""))]
-  ""
-  "
+  [(use (match_operand 0 "general_operand"))]
+  ""
 {
   if (TARGET_32BIT)
     emit_insn (gen_eh_set_lr_si (operands[0]));
   else
     emit_insn (gen_eh_set_lr_di (operands[0]));
   DONE;
-}")
+})
 
 ; We can't expand this before we know where the link register is stored.
 (define_insn "eh_set_lr_<mode>"
@@ -13556,27 +13444,44 @@
   "#")
 
 (define_split
-  [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
-   (clobber (match_scratch 1 ""))]
+  [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
+   (clobber (match_scratch 1))]
   "reload_completed"
   [(const_int 0)]
-  "
 {
   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
   DONE;
-}")
+})
 
 (define_insn "prefetch"
   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
 	     (match_operand:SI 1 "const_int_operand" "n")
 	     (match_operand:SI 2 "const_int_operand" "n"))]
   ""
-  "*
-{
-  if (GET_CODE (operands[0]) == REG)
-    return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
-  return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
-}"
+{
+
+
+  /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
+     AIX does not support the dcbtstt and dcbtt extended mnemonics.
+     The AIX assembler does not support the three operand form of dcbt
+     and dcbtst on Power 7 (-mpwr7).  */
+  int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
+
+  if (REG_P (operands[0]))
+    {
+      if (INTVAL (operands[1]) == 0)
+        return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
+      else
+        return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
+    }
+  else
+    {
+      if (INTVAL (operands[1]) == 0)
+        return inst_select ? "dcbt %a0" : "dcbt %a0,16";
+      else
+        return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
+    }
+}
   [(set_attr "type" "load")])
 
 ;; Handle -fsplit-stack.
@@ -13623,7 +13528,7 @@
 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
 ;; after the call to __morestack.
 (define_insn "split_stack_return"
-  [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
+  [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
   ""
   "blr"
   [(set_attr "type" "jmpreg")])
@@ -13660,11 +13565,11 @@
 ;; Note that the conditions for expansion are in the FMA_F iterator.
 
 (define_expand "fma<mode>4"
-  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
+  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
 	(fma:FMA_F
-	  (match_operand:FMA_F 1 "gpc_reg_operand" "")
-	  (match_operand:FMA_F 2 "gpc_reg_operand" "")
-	  (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
+	  (match_operand:FMA_F 1 "gpc_reg_operand")
+	  (match_operand:FMA_F 2 "gpc_reg_operand")
+	  (match_operand:FMA_F 3 "gpc_reg_operand")))]
   ""
   "")
 
@@ -13674,21 +13579,20 @@
 	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
 	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
 	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fmadd<Ftrad> %0,%1,%2,%3
    xsmadda<Fvsx> %x0,%x1,%x2
    xsmaddm<Fvsx> %x0,%x1,%x3"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_maddsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 ; Altivec only has fma and nfms.
 (define_expand "fms<mode>4"
-  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
+  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
 	(fma:FMA_F
-	  (match_operand:FMA_F 1 "gpc_reg_operand" "")
-	  (match_operand:FMA_F 2 "gpc_reg_operand" "")
-	  (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
+	  (match_operand:FMA_F 1 "gpc_reg_operand")
+	  (match_operand:FMA_F 2 "gpc_reg_operand")
+	  (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
   "")
 
@@ -13698,44 +13602,43 @@
 	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
 	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
 	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fmsub<Ftrad> %0,%1,%2,%3
    xsmsuba<Fvsx> %x0,%x1,%x2
    xsmsubm<Fvsx> %x0,%x1,%x3"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_maddsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
 (define_expand "fnma<mode>4"
-  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
+  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
 	(neg:FMA_F
 	  (fma:FMA_F
-	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
-	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
-	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
+	    (match_operand:FMA_F 1 "gpc_reg_operand")
+	    (match_operand:FMA_F 2 "gpc_reg_operand")
+	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
   "")
 
 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
 (define_expand "fnms<mode>4"
-  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
+  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
 	(neg:FMA_F
 	  (fma:FMA_F
-	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
-	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
-	    (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
+	    (match_operand:FMA_F 1 "gpc_reg_operand")
+	    (match_operand:FMA_F 2 "gpc_reg_operand")
+	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
   "")
 
 ; Not an official optab name, but used from builtins.
 (define_expand "nfma<mode>4"
-  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
+  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
 	(neg:FMA_F
 	  (fma:FMA_F
-	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
-	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
-	    (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
+	    (match_operand:FMA_F 1 "gpc_reg_operand")
+	    (match_operand:FMA_F 2 "gpc_reg_operand")
+	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
   "")
 
@@ -13746,22 +13649,21 @@
 	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
 	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
 	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fnmadd<Ftrad> %0,%1,%2,%3
    xsnmadda<Fvsx> %x0,%x1,%x2
    xsnmaddm<Fvsx> %x0,%x1,%x3"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_maddsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 ; Not an official optab name, but used from builtins.
 (define_expand "nfms<mode>4"
-  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
+  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
 	(neg:FMA_F
 	  (fma:FMA_F
-	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
-	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
-	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
+	    (match_operand:FMA_F 1 "gpc_reg_operand")
+	    (match_operand:FMA_F 2 "gpc_reg_operand")
+	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
   ""
   "")
 
@@ -13773,17 +13675,16 @@
 	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
 	  (neg:SFDF
 	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
-  "TARGET_<MODE>_FPR"
+  "TARGET_HARD_FLOAT"
   "@
    fnmsub<Ftrad> %0,%1,%2,%3
    xsnmsuba<Fvsx> %x0,%x1,%x2
    xsnmsubm<Fvsx> %x0,%x1,%x3"
-  [(set_attr "type" "fp")
-   (set_attr "fp_type" "fp_maddsub_<Fs>")])
+  [(set_attr "type" "fp")])
 
 
 (define_expand "rs6000_get_timebase"
-  [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
+  [(use (match_operand:DI 0 "gpc_reg_operand"))]
   ""
 {
   if (TARGET_POWERPC64)
@@ -13849,6 +13750,43 @@
 })
 
 
+;; The ISA 3.0 mffsl instruction is a lower latency instruction
+;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
+(define_insn "rs6000_mffsl_hw"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+        (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
+  "TARGET_HARD_FLOAT"
+  "mffsl %0")
+
+(define_expand "rs6000_mffsl"
+  [(set (match_operand:DF 0 "gpc_reg_operand")
+	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
+  "TARGET_HARD_FLOAT"
+{
+  /* If the low latency mffsl instruction (ISA 3.0) is available use it,
+     otherwise fall back to the older mffs instruction to emulate the mffsl
+     instruction.  */
+
+  if (!TARGET_P9_MISC)
+    {
+       rtx tmp_di = gen_reg_rtx (DImode);
+       rtx tmp_df = gen_reg_rtx (DFmode);
+
+       /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
+          instruction using the mffs instruction and masking off the bits
+          the mmsl instruciton actually reads.  */
+       emit_insn (gen_rs6000_mffs (tmp_df));
+       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
+       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
+
+       operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
+       DONE;
+    }
+
+    emit_insn (gen_rs6000_mffsl_hw (operands[0]));
+    DONE;
+})
+
 (define_insn "rs6000_mffs"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
 	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
@@ -13862,80 +13800,32 @@
   "TARGET_HARD_FLOAT"
   "mtfsf %0,%1")
 
+(define_insn "rs6000_mtfsf_hi"
+  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
+		     (match_operand:DF 1 "gpc_reg_operand" "d")]
+		    UNSPECV_MTFSF_HI)]
+  "TARGET_HARD_FLOAT"
+  "mtfsf %0,%1,0,1")
+
 
 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
 ;; register that is being loaded.  The fused ops must be physically adjacent.
 
-;; There are two parts to addis fusion.  The support for fused TOCs occur
-;; before register allocation, and is meant to reduce the lifetime for the
-;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
-;; to use the register that is being load.  The peephole2 then gathers any
-;; other fused possibilities that it can find after register allocation.  If
-;; power9 fusion is selected, we also fuse floating point loads/stores.
-
-;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
-;; before register allocation, so that we can avoid allocating a temporary base
-;; register that won't be used, and that we try to load into base registers,
-;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
-;; (addis followed by load) even on power8.
-
-(define_split
-  [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
-	(match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
-  "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
-  [(parallel [(set (match_dup 0) (match_dup 2))
-	      (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
-	      (use (match_dup 3))
-	      (clobber (scratch:DI))])]
-{
-  operands[2] = fusion_wrap_memory_address (operands[1]);
-  operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
-})
-
-(define_insn "*toc_fusionload_<mode>"
-  [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
-	(match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
-   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
-   (use (match_operand:DI 2 "base_reg_operand" "r,r"))
-   (clobber (match_scratch:DI 3 "=X,&b"))]
-  "TARGET_TOC_FUSION_INT"
-{
-  if (base_reg_operand (operands[0], <MODE>mode))
-    return emit_fusion_gpr_load (operands[0], operands[1]);
-
-  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
-}
-  [(set_attr "type" "load")
-   (set_attr "length" "8")])
-
-(define_insn "*toc_fusionload_di"
-  [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
-	(match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
-   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
-   (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
-   (clobber (match_scratch:DI 3 "=X,&b,&b"))]
-  "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
-   && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
-{
-  if (base_reg_operand (operands[0], DImode))
-    return emit_fusion_gpr_load (operands[0], operands[1]);
-
-  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
-}
-  [(set_attr "type" "load")
-   (set_attr "length" "8")])
-
-
+;; On Power8 GPR loads, we try to use the register that is being load.  The
+;; peephole2 then gathers any other fused possibilities that it can find after
+;; register allocation.  If power9 fusion is selected, we also fuse floating
+;; point loads/stores.
+
 ;; Find cases where the addis that feeds into a load instruction is either used
 ;; once or is the same as the target register, and replace it with the fusion
 ;; insn
 
 (define_peephole2
-  [(set (match_operand:P 0 "base_reg_operand" "")
-	(match_operand:P 1 "fusion_gpr_addis" ""))
-   (set (match_operand:INT1 2 "base_reg_operand" "")
-	(match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
+  [(set (match_operand:P 0 "base_reg_operand")
+	(match_operand:P 1 "fusion_gpr_addis"))
+   (set (match_operand:INT1 2 "base_reg_operand")
+	(match_operand:INT1 3 "fusion_gpr_mem_load"))]
   "TARGET_P8_FUSION
    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
 			 operands[3])"
@@ -13948,7 +13838,7 @@
 ;; Fusion insn, created by the define_peephole2 above (and eventually by
 ;; reload)
 
-(define_insn "fusion_gpr_load_<mode>"
+(define_insn "*fusion_gpr_load_<mode>"
   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
 	(unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
 		     UNSPEC_FUSION_GPR))]
@@ -13963,10 +13853,10 @@
 ;; ISA 3.0 (power9) fusion support
 ;; Merge addis with floating load/store to FPRs (or GPRs).
 (define_peephole2
-  [(set (match_operand:P 0 "base_reg_operand" "")
-	(match_operand:P 1 "fusion_gpr_addis" ""))
-   (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
-	(match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
+  [(set (match_operand:P 0 "base_reg_operand")
+	(match_operand:P 1 "fusion_gpr_addis"))
+   (set (match_operand:SFDF 2 "p9_fusion_reg_operand")
+	(match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
   [(const_int 0)]
@@ -13976,10 +13866,10 @@
 })
 
 (define_peephole2
-  [(set (match_operand:P 0 "base_reg_operand" "")
-	(match_operand:P 1 "fusion_gpr_addis" ""))
-   (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
-	(match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
+  [(set (match_operand:P 0 "base_reg_operand")
+	(match_operand:P 1 "fusion_gpr_addis"))
+   (set (match_operand:SFDF 2 "offsettable_mem_operand")
+	(match_operand:SFDF 3 "p9_fusion_reg_operand"))]
   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
    && !rtx_equal_p (operands[0], operands[3])"
@@ -13990,22 +13880,22 @@
 })
 
 (define_peephole2
-  [(set (match_operand:SDI 0 "int_reg_operand" "")
-	(match_operand:SDI 1 "upper16_cint_operand" ""))
+  [(set (match_operand:SDI 0 "int_reg_operand")
+	(match_operand:SDI 1 "upper16_cint_operand"))
    (set (match_dup 0)
 	(ior:SDI (match_dup 0)
-		 (match_operand:SDI 2 "u_short_cint_operand" "")))]
+		 (match_operand:SDI 2 "u_short_cint_operand")))]
   "TARGET_P9_FUSION"
   [(set (match_dup 0)
 	(unspec:SDI [(match_dup 1)
 		     (match_dup 2)] UNSPEC_FUSION_P9))])
 
 (define_peephole2
-  [(set (match_operand:SDI 0 "int_reg_operand" "")
-	(match_operand:SDI 1 "upper16_cint_operand" ""))
-   (set (match_operand:SDI 2 "int_reg_operand" "")
+  [(set (match_operand:SDI 0 "int_reg_operand")
+	(match_operand:SDI 1 "upper16_cint_operand"))
+   (set (match_operand:SDI 2 "int_reg_operand")
 	(ior:SDI (match_dup 0)
-		 (match_operand:SDI 3 "u_short_cint_operand" "")))]
+		 (match_operand:SDI 3 "u_short_cint_operand")))]
   "TARGET_P9_FUSION
    && !rtx_equal_p (operands[0], operands[2])
    && peep2_reg_dead_p (2, operands[0])"
@@ -14017,7 +13907,7 @@
 ;; reload).  Because we want to eventually have secondary_reload generate
 ;; these, they have to have a single alternative that gives the register
 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
-(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
+(define_insn "*fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
 	(unspec:GPR_FUSION
 	 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
@@ -14035,7 +13925,7 @@
   [(set_attr "type" "load")
    (set_attr "length" "8")])
 
-(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
+(define_insn "*fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
 	(unspec:GPR_FUSION
 	 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
@@ -14048,7 +13938,7 @@
   [(set_attr "type" "store")
    (set_attr "length" "8")])
 
-(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
+(define_insn "*fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
 	(unspec:FPR_FUSION
 	 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
@@ -14061,7 +13951,7 @@
   [(set_attr "type" "fpload")
    (set_attr "length" "8")])
 
-(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
+(define_insn "*fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
 	(unspec:FPR_FUSION
 	 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
@@ -14081,7 +13971,7 @@
 		    UNSPEC_FUSION_P9))]	
   "TARGET_P9_FUSION"
 {
-  emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
+  emit_fusion_addis (operands[0], operands[1]);
   return "ori %0,%0,%2";
 }
   [(set_attr "type" "two")
@@ -14170,8 +14060,7 @@
 		   UNSPEC_ADDG6S))]
   "TARGET_POPCNTD"
   "addg6s %0,%1,%2"
-  [(set_attr "type" "integer")
-   (set_attr "length" "4")])
+  [(set_attr "type" "integer")])
 
 (define_insn "cdtbcd"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -14179,8 +14068,7 @@
 		   UNSPEC_CDTBCD))]
   "TARGET_POPCNTD"
   "cdtbcd %0,%1"
-  [(set_attr "type" "integer")
-   (set_attr "length" "4")])
+  [(set_attr "type" "integer")])
 
 (define_insn "cbcdtd"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -14188,18 +14076,13 @@
 		   UNSPEC_CBCDTD))]
   "TARGET_POPCNTD"
   "cbcdtd %0,%1"
-  [(set_attr "type" "integer")
-   (set_attr "length" "4")])
+  [(set_attr "type" "integer")])
 
 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
-					UNSPEC_DIVEO
-					UNSPEC_DIVEU
-					UNSPEC_DIVEUO])
+					UNSPEC_DIVEU])
 
 (define_int_attr div_extend [(UNSPEC_DIVE	"e")
-			     (UNSPEC_DIVEO	"eo")
-			     (UNSPEC_DIVEU	"eu")
-			     (UNSPEC_DIVEUO	"euo")])
+			     (UNSPEC_DIVEU	"eu")])
 
 (define_insn "div<div_extend>_<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=r")
@@ -14221,10 +14104,10 @@
 			    (KF "DI")])
 
 (define_expand "unpack<mode>"
-  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
+  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
 	(unspec:<FP128_64>
-	 [(match_operand:FMOVE128 1 "register_operand" "")
-	  (match_operand:QI 2 "const_0_to_1_operand" "")]
+	 [(match_operand:FMOVE128 1 "register_operand")
+	  (match_operand:QI 2 "const_0_to_1_operand")]
 	 UNSPEC_UNPACK_128BIT))]
   "FLOAT128_2REG_P (<MODE>mode)"
   "")
@@ -14250,8 +14133,7 @@
 
   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
 }
-  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
-   (set_attr "length" "4")])
+  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
 
 (define_insn_and_split "unpack<mode>_nodm"
   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
@@ -14274,20 +14156,17 @@
 
   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
 }
-  [(set_attr "type" "fp,fpstore")
-   (set_attr "length" "4")])
+  [(set_attr "type" "fp,fpstore")])
 
 (define_insn_and_split "pack<mode>"
-  [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
+  [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
 	(unspec:FMOVE128
-	 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
-	  (match_operand:<FP128_64> 2 "register_operand" "d,d")]
+	 [(match_operand:<FP128_64> 1 "register_operand" "d")
+	  (match_operand:<FP128_64> 2 "register_operand" "d")]
 	 UNSPEC_PACK_128BIT))]
   "FLOAT128_2REG_P (<MODE>mode)"
-  "@
-   fmr %L0,%2
-   #"
-  "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
+  "#"
+  "&& reload_completed"
   [(set (match_dup 3) (match_dup 1))
    (set (match_dup 4) (match_dup 2))]
 {
@@ -14300,8 +14179,8 @@
   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
 }
-  [(set_attr "type" "fpsimple,fp")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "fp")
+   (set_attr "length" "8")])
 
 (define_insn "unpack<mode>"
   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
@@ -14359,7 +14238,7 @@
 	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsmulqp %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "div<mode>3"
@@ -14391,11 +14270,8 @@
     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
 					 operands[2]));
   else
-    {
-      rtx tmp = gen_reg_rtx (<MODE>mode);
-      emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
-					   operands[2], tmp));
-    }
+    emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
+					 operands[2]));
   DONE;
 })
 
@@ -14414,9 +14290,9 @@
   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
 	(unspec:IEEE128
 	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
-	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
-	  (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
-	 UNSPEC_COPYSIGN))]
+	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
+	 UNSPEC_COPYSIGN))
+   (clobber (match_scratch:IEEE128 3 "=&v"))]
   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
   [(set_attr "type" "veccomplex")
@@ -14461,7 +14337,7 @@
 	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsmaddqp %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "*fms<mode>4_hw"
@@ -14473,7 +14349,7 @@
 	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsmsubqp %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "*nfma<mode>4_hw"
@@ -14485,7 +14361,7 @@
 	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsnmaddqp %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "*nfms<mode>4_hw"
@@ -14498,7 +14374,7 @@
 	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsnmsubqp %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
@@ -14577,49 +14453,45 @@
    (set_attr "length" "8")])
 
 ;; Conversion between IEEE 128-bit and integer types
-(define_insn "fix_<mode>di2_hw"
-  [(set (match_operand:DI 0 "altivec_register_operand" "=v")
-	(fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
-  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
-  "xscvqpsdz %0,%1"
-  [(set_attr "type" "vecfloat")
-   (set_attr "size" "128")])
-
-(define_insn "fixuns_<mode>di2_hw"
-  [(set (match_operand:DI 0 "altivec_register_operand" "=v")
-	(unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
-  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
-  "xscvqpudz %0,%1"
+
+;; The fix function for DImode and SImode was declared earlier as a
+;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
+;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
+;; unless we have the IEEE 128-bit hardware.
+;;
+;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
+;; to provide a GPR target that used direct move and a conversion in the GPR
+;; which works around QImode/HImode not being allowed in vector registers in
+;; ISA 2.07 (power8).
+(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
+  [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
+	(any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
+  "xscvqp<su><wd>z %0,%1"
   [(set_attr "type" "vecfloat")
    (set_attr "size" "128")])
 
-(define_insn "fix_<mode>si2_hw"
-  [(set (match_operand:SI 0 "altivec_register_operand" "=v")
-	(fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
-  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
-  "xscvqpswz %0,%1"
+(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
+  [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
+	(any_fix:QHI
+	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
+  "xscvqp<su>wz %0,%1"
   [(set_attr "type" "vecfloat")
    (set_attr "size" "128")])
 
-(define_insn "fixuns_<mode>si2_hw"
-  [(set (match_operand:SI 0 "altivec_register_operand" "=v")
-	(unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
-  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
-  "xscvqpuwz %0,%1"
-  [(set_attr "type" "vecfloat")
-   (set_attr "size" "128")])
-
-;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
-;; floating point value to 32-bit integer to GPR in order to save it.
-(define_insn_and_split "*fix<uns>_<mode>_mem"
-  [(set (match_operand:SI 0 "memory_operand" "=Z")
-	(any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
-   (clobber (match_scratch:SI 2 "=v"))]
+;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
+;; floating point value to 8/16/32-bit integer to GPR in order to save it.
+(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
+  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
+	(any_fix:QHSI
+	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
+   (clobber (match_scratch:QHSI 2 "=v"))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
-	(any_fix:SI (match_dup 1)))
+	(any_fix:QHSI (match_dup 1)))
    (set (match_dup 0)
 	(match_dup 2))])
 
@@ -14645,6 +14517,9 @@
 {
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (DImode);
+
+  if (MEM_P (operands[1]))
+    operands[1] = rs6000_address_for_fpconvert (operands[1]);
 })
 
 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
@@ -14708,6 +14583,9 @@
 {
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (DImode);
+
+  if (MEM_P (operands[1]))
+    operands[1] = rs6000_address_for_fpconvert (operands[1]);
 })
 
 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
@@ -14742,6 +14620,47 @@
    (set_attr "type" "vecfloat")
    (set_attr "size" "128")])
 
+;; IEEE 128-bit round to integer built-in functions
+(define_insn "floor<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+	(unspec:IEEE128
+	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+	 UNSPEC_FRIM))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 1,%0,%1,3"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
+(define_insn "ceil<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+	(unspec:IEEE128
+	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+	 UNSPEC_FRIP))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 1,%0,%1,2"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
+(define_insn "btrunc<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+	(unspec:IEEE128
+	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+	 UNSPEC_FRIZ))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 1,%0,%1,1"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
+(define_insn "round<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+	(unspec:IEEE128
+	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+	 UNSPEC_FRIN))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 0,%0,%1,0"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
 ;; IEEE 128-bit instructions with round to odd semantics
 (define_insn "add<mode>3_odd"
   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
@@ -14773,7 +14692,7 @@
 	 UNSPEC_MUL_ROUND_TO_ODD))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsmulqpo %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "div<mode>3_odd"
@@ -14806,7 +14725,7 @@
 	 UNSPEC_FMA_ROUND_TO_ODD))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsmaddqpo %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "*fms<mode>4_odd"
@@ -14819,7 +14738,7 @@
 	 UNSPEC_FMA_ROUND_TO_ODD))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsmsubqpo %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "*nfma<mode>4_odd"
@@ -14832,7 +14751,7 @@
 	  UNSPEC_FMA_ROUND_TO_ODD)))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsnmaddqpo %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "*nfms<mode>4_odd"
@@ -14846,7 +14765,7 @@
 	  UNSPEC_FMA_ROUND_TO_ODD)))]
   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "xsnmsubqpo %0,%1,%2"
-  [(set_attr "type" "vecfloat")
+  [(set_attr "type" "qmul")
    (set_attr "size" "128")])
 
 (define_insn "trunc<mode>df2_odd"
@@ -14875,6 +14794,5 @@
 (include "vsx.md")
 (include "altivec.md")
 (include "dfp.md")
-(include "paired.md")
 (include "crypto.md")
 (include "htm.md")