OSDN Git Service

* config/rs6000/spe.md (SPE_ACC_REGNO): Delete definition.
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.md
index 06670d2..92648a0 100644 (file)
@@ -1,6 +1,6 @@
 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
 ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
 ;; Free Software Foundation, Inc.
 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
 
 ;;
+;; REGNOS
+;;
+
+(define_constants
+  [(MQ_REGNO                   64)
+   (LR_REGNO                   65)
+   (CTR_REGNO                  66)
+   (CR0_REGNO                  68)
+   (CR1_REGNO                  69)
+   (CR2_REGNO                  70)
+   (CR3_REGNO                  71)
+   (CR4_REGNO                  72)
+   (CR5_REGNO                  73)
+   (CR6_REGNO                  74)
+   (CR7_REGNO                  75)
+   (MAX_CR_REGNO               75)
+   (XER_REGNO                  76)
+   (FIRST_ALTIVEC_REGNO                77)
+   (LAST_ALTIVEC_REGNO         108)
+   (VRSAVE_REGNO               109)
+   (VSCR_REGNO                 110)
+   (SPE_ACC_REGNO              111)
+   (SPEFSCR_REGNO              112)
+   (SFP_REGNO                  113)
+  ])
+
+;;
 ;; UNSPEC usage
 ;;
 
@@ -55,7 +82,7 @@
    (UNSPEC_TLSGOTTPREL         28)
    (UNSPEC_TLSTLS              29)
    (UNSPEC_FIX_TRUNC_TF                30)     ; fadd, rounding towards zero
-   (UNSPEC_MV_CR_GT            31)     ; move_from_CR_eq_bit
+   (UNSPEC_MV_CR_GT            31)     ; move_from_CR_gt_bit
    (UNSPEC_STFIWX              32)
    (UNSPEC_POPCNTB             33)
    (UNSPEC_FRES                        34)
 \f
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
-(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c"
+(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr"
   (const_string "integer"))
 
 ;; Length (in bytes).
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000.h.
 
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5,power6,cell"
   (const (symbol_ref "rs6000_cpu_attr")))
 
+
+;; If this instruction is microcoded on the CELL processor
+; The default for load and stores is conditional
+; The default for load extended and the recorded instructions is always microcoded
+(define_attr "cell_micro" "not,conditional,always"
+  (if_then_else (ior (ior (eq_attr "type" "load")
+                          (eq_attr "type" "store"))
+                     (ior (eq_attr "type" "fpload")
+                          (eq_attr "type" "fpstore")))
+               (const_string "conditional")
+                (if_then_else (ior (eq_attr "type" "load_ext")
+                                  (ior (eq_attr "type" "compare")
+                                       (eq_attr "type" "delayed_compare")))
+                             (const_string "always")
+                              (const_string "not"))))
+
+
 (automata_option "ndfa")
 
 (include "rios1.md")
 (include "8540.md")
 (include "power4.md")
 (include "power5.md")
+(include "power6.md")
+(include "cell.md")
 
 (include "predicates.md")
+(include "constraints.md")
 
 (include "darwin.md")
 
 (define_mode_macro FP [(SF "TARGET_HARD_FLOAT")
   (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
   (TF "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")])
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128")])
 
 ; Various instructions that come in SI and DI forms.
 ; A generic w/d attribute, for things like cmpw/cmpd.
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
        (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC64"
-  "extsb %0,%1")
+  "extsb %0,%1"
+  [(set_attr "type" "exts")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
   "@
    lha%U1%X1 %0,%1
    extsh %0,%1"
-  [(set_attr "type" "load_ext,*")])
+  [(set_attr "type" "load_ext,exts")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
   "@
    lwa%U1%X1 %0,%1
    extsw %0,%1"
-  [(set_attr "type" "load_ext,*")])
+  [(set_attr "type" "load_ext,exts")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC"
-  "extsb %0,%1")
+  "extsb %0,%1"
+  [(set_attr "type" "exts")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
        (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC"
-  "extsb %0,%1")
+  "extsb %0,%1"
+  [(set_attr "type" "exts")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
   "@
    lha%U1%X1 %0,%1
    {exts|extsh} %0,%1"
-  [(set_attr "type" "load_ext,*")])
+  [(set_attr "type" "load_ext,exts")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
                  (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
   ""
-  "
 {
   if (<MODE>mode == DImode && ! TARGET_POWERPC64)
     {
   else if (GET_CODE (operands[2]) == CONST_INT
           && ! add_operand (operands[2], <MODE>mode))
     {
-      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+      rtx tmp = ((!can_create_pseudo_p ()
+                 || rtx_equal_p (operands[0], operands[1]))
                 ? operands[0] : gen_reg_rtx (<MODE>mode));
 
       HOST_WIDE_INT val = INTVAL (operands[2]);
       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
-      if (<MODE>mode == DImode && !CONST_OK_FOR_LETTER_P (rest, 'L'))
+      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
        FAIL;
 
       /* The ordering here is important for the prolog expander.
       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
       DONE;
     }
-}")
+})
 
 ;; Discourage ai/addic because of carry but provide it in an alternative
 ;; allowing register zero as source.
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r")
        (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b")
                  (match_operand:GPR 2 "add_operand" "r,I,I,L")))]
-  ""
+  "!DECIMAL_FLOAT_MODE_P (GET_MODE (operands[0])) && !DECIMAL_FLOAT_MODE_P (GET_MODE (operands[1]))"
   "@
    {cax|add} %0,%1,%2
    {cal %0,%2(%1)|addi %0,%1,%2}
   ""
   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
-"
 {
   HOST_WIDE_INT val = INTVAL (operands[2]);
   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
   operands[4] = GEN_INT (low);
-  if (<MODE>mode == SImode || CONST_OK_FOR_LETTER_P (rest, 'L'))
+  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
     operands[3] = GEN_INT (rest);
-  else if (! no_new_pseudos)
+  else if (can_create_pseudo_p ())
     {
       operands[3] = gen_reg_rtx (DImode);
       emit_move_insn (operands[3], operands[2]);
     }
   else
     FAIL;
-}")
+})
 
 (define_insn "one_cmpl<mode>2"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
        (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
   ""
-  "{cntlz|cntlz<wd>} %0,%1")
+  "{cntlz|cntlz<wd>} %0,%1"
+  [(set_attr "type" "cntlz")])
 
 (define_expand "ctz<mode>2"
   [(set (match_dup 2)
-       (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))
+       (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
    (parallel [(set (match_dup 3) (and:GPR (match_dup 1)
                                          (match_dup 2)))
              (clobber (scratch:CC))])
    (set (match_dup 4) (clz:GPR (match_dup 3)))
-   (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+   (set (match_operand:GPR 0 "gpc_reg_operand" "")
        (minus:GPR (match_dup 5) (match_dup 4)))]
   ""
   {
 
 (define_expand "ffs<mode>2"
   [(set (match_dup 2)
-       (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))
+       (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
    (parallel [(set (match_dup 3) (and:GPR (match_dup 1)
                                          (match_dup 2)))
              (clobber (scratch:CC))])
    (set (match_dup 4) (clz:GPR (match_dup 3)))
-   (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+   (set (match_operand:GPR 0 "gpc_reg_operand" "")
        (minus:GPR (match_dup 5) (match_dup 4)))]
   ""
   {
      operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
   })
 
-(define_expand "popcount<mode>2"
-  [(set (match_dup 2)
-       (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
-                    UNSPEC_POPCNTB))
-   (set (match_dup 3)
-       (mult:GPR (match_dup 2) (match_dup 4)))
-   (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
-       (lshiftrt:GPR (match_dup 3) (match_dup 5)))]
-  "TARGET_POPCNTB"
-  {
-    operands[2] = gen_reg_rtx (<MODE>mode);
-    operands[3] = gen_reg_rtx (<MODE>mode);
-    operands[4] = force_reg (<MODE>mode,
-                            <MODE>mode == SImode
-                            ? GEN_INT (0x01010101)
-                            : GEN_INT ((HOST_WIDE_INT)
-                                       0x01010101 << 32 | 0x01010101));
-    operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 8);
-  })
-
 (define_insn "popcntb<mode>2"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
   "TARGET_POPCNTB"
   "popcntb %0,%1")
 
+(define_expand "popcount<mode>2"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
+       (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
+  "TARGET_POPCNTB"
+  {
+    rs6000_emit_popcount (operands[0], operands[1]);
+    DONE;
+  })
+
+(define_expand "parity<mode>2"
+  [(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]);
+    DONE;
+  })
+
+(define_insn "bswapsi2"
+  [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
+       (bswap:SI (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
+  ""
+  "@
+   {lbrx|lwbrx} %0,%y1
+   {stbrx|stwbrx} %1,%y0
+   #"
+  [(set_attr "length" "4,4,12")])
+
+(define_split
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+       (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (rotate:SI (match_dup 1) (const_int 8)))
+   (set (zero_extract:SI (match_dup 0)
+                        (const_int 8)
+                        (const_int 0))
+       (match_dup 1))
+   (set (zero_extract:SI (match_dup 0)
+                        (const_int 8)
+                        (const_int 16))
+       (rotate:SI (match_dup 1)
+                  (const_int 16)))]
+  "")
+
 (define_expand "mulsi3"
   [(use (match_operand:SI 0 "gpc_reg_operand" ""))
    (use (match_operand:SI 1 "gpc_reg_operand" ""))
                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC && ! TARGET_POWER"
   "div<wd>u %0,%1,%2"
-  [(set_attr "type" "idiv")])
+   [(set (attr "type")
+      (cond [(match_operand:SI 0 "" "")
+               (const_string "idiv")]
+       (const_string "ldiv")))])
+
 
 ;; For powers of two we can do srai/aze for divide and then adjust for
 ;; modulus.  If it isn't a power of two, FAIL on POWER so divmodsi4 will be
     ;
   else if (TARGET_POWERPC)
     {
-      operands[2] = force_reg (SImode, operands[2]);
+      operands[2] = force_reg (<MODE>mode, operands[2]);
       if (TARGET_POWER)
        {
          emit_insn (gen_divsi3_mq (operands[0], operands[1], operands[2]));
                 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC && ! TARGET_POWER"
   "div<wd> %0,%1,%2"
-  [(set_attr "type" "idiv")])
+  [(set (attr "type")
+     (cond [(match_operand:SI 0 "" "")
+               (const_string "idiv")]
+       (const_string "ldiv")))])
 
 (define_expand "mod<mode>3"
   [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
         (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
                               (sign_extend:DI (reg:SI 4)))
                      (const_int 32))))
-   (clobber (match_scratch:SI 0 "=l"))]
+   (clobber (reg:SI LR_REGNO))]
   "! TARGET_POWER && ! TARGET_POWERPC"
   "bla __mulh"
   [(set_attr "type" "imul")])
   [(set (reg:DI 3)
        (mult:DI (sign_extend:DI (reg:SI 3))
                 (sign_extend:DI (reg:SI 4))))
-   (clobber (match_scratch:SI 0 "=l"))
+   (clobber (reg:SI LR_REGNO))
    (clobber (reg:SI 0))]
   "! TARGET_POWER && ! TARGET_POWERPC"
   "bla __mull"
        (div:SI (reg:SI 3) (reg:SI 4)))
    (set (reg:SI 4)
        (mod:SI (reg:SI 3) (reg:SI 4)))
-   (clobber (match_scratch:SI 0 "=l"))
+   (clobber (reg:SI LR_REGNO))
    (clobber (reg:SI 0))]
   "! TARGET_POWER && ! TARGET_POWERPC"
   "bla __divss"
        (udiv:SI (reg:SI 3) (reg:SI 4)))
    (set (reg:SI 4)
        (umod:SI (reg:SI 3) (reg:SI 4)))
-   (clobber (match_scratch:SI 0 "=l"))
+   (clobber (reg:SI LR_REGNO))
    (clobber (reg:SI 0))
-   (clobber (match_scratch:CC 1 "=x"))
-   (clobber (reg:CC 69))]
+   (clobber (match_scratch:CC 0 "=x"))
+   (clobber (reg:CC CR1_REGNO))]
   "! TARGET_POWER && ! TARGET_POWERPC"
   "bla __divus"
   [(set_attr "type" "idiv")])
 (define_insn "quoss_call"
   [(set (reg:SI 3)
        (div:SI (reg:SI 3) (reg:SI 4)))
-   (clobber (match_scratch:SI 0 "=l"))]
+   (clobber (reg:SI LR_REGNO))]
   "! TARGET_POWER && ! TARGET_POWERPC"
   "bla __quoss"
   [(set_attr "type" "idiv")])
 (define_insn "quous_call"
   [(set (reg:SI 3)
        (udiv:SI (reg:SI 3) (reg:SI 4)))
-   (clobber (match_scratch:SI 0 "=l"))
+   (clobber (reg:SI LR_REGNO))
    (clobber (reg:SI 0))
-   (clobber (match_scratch:CC 1 "=x"))
-   (clobber (reg:CC 69))]
+   (clobber (match_scratch:CC 0 "=x"))
+   (clobber (reg:CC CR1_REGNO))]
   "! TARGET_POWER && ! TARGET_POWERPC"
   "bla __quous"
   [(set_attr "type" "idiv")])
       && ! logical_operand (operands[2], SImode))
     {
       HOST_WIDE_INT value = INTVAL (operands[2]);
-      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+      rtx tmp = ((!can_create_pseudo_p ()
+                 || rtx_equal_p (operands[0], operands[1]))
                 ? operands[0] : gen_reg_rtx (SImode));
 
       emit_insn (gen_iorsi3 (tmp, operands[1],
       && ! logical_operand (operands[2], SImode))
     {
       HOST_WIDE_INT value = INTVAL (operands[2]);
-      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+      rtx tmp = ((!can_create_pseudo_p ()
+                 || rtx_equal_p (operands[0], operands[1]))
                 ? operands[0] : gen_reg_rtx (SImode));
 
       emit_insn (gen_xorsi3 (tmp, operands[1],
 {
   /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
      the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
-     compiler if the address of the structure is taken later.  */
+     compiler if the address of the structure is taken later.  Likewise, do
+     not handle invalid E500 subregs.  */
   if (GET_CODE (operands[0]) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
+      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
+         || ((TARGET_E500_DOUBLE || TARGET_SPE)
+             && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
     FAIL;
 
   if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
 
   operands[1] = GEN_INT (64 - start - size);
   return \"rldimi %0,%3,%H1,%H2\";
-}")
+}"
+  [(set_attr "type" "insert_dword")])
 
 (define_insn "*insvdi_internal2"
   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
     operands[3] = GEN_INT (start + size);
   return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
 }"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "delayed_compare")
    (set_attr "length" "4,8")])
 
 (define_split
     operands[3] = GEN_INT (start + size);
   return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
 }"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "delayed_compare")
    (set_attr "length" "4,8")])
 
 (define_split
   [(set_attr "type" "compare")])
 
 (define_insn "rotlsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                  (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                  (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
   ""
-  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
+  "@
+   {rlnm|rlwnm} %0,%1,%2,0xffffffff
+   {rlinm|rlwinm} %0,%1,%h2,0xffffffff"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotlsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff
+   {rlnm.|rlwnm.} %3,%1,%2,0xffffffff
+   {rlinm.|rlwinm.} %3,%1,%h2,0xffffffff
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotlsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (rotate:SI (match_dup 1) (match_dup 2)))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff
+   {rlnm.|rlwnm.} %0,%1,%2,0xffffffff
+   {rlinm.|rlwinm.} %0,%1,%h2,0xffffffff
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotlsi3_internal4"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                          (match_operand:SI 2 "reg_or_cint_operand" "ri"))
-               (match_operand:SI 3 "mask_operand" "n")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                          (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
+               (match_operand:SI 3 "mask_operand" "n,n")))]
   ""
-  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
+  "@
+   {rlnm|rlwnm} %0,%1,%2,%m3,%M3
+   {rlinm|rlwinm} %0,%1,%h2,%m3,%M3"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotlsi3_internal5"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (and:SI
-                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                               (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
-                    (match_operand:SI 3 "mask_operand" "n,n"))
+                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                               (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
+                    (match_operand:SI 3 "mask_operand" "n,n,n,n"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r,r"))]
+   (clobber (match_scratch:SI 4 "=r,r,r,r"))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3
+   {rlnm.|rlwnm.} %4,%1,%2,%m3,%M3
+   {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotlsi3_internal6"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (and:SI
-                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                               (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
-                    (match_operand:SI 3 "mask_operand" "n,n"))
+                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                               (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
+                    (match_operand:SI 3 "mask_operand" "n,n,n,n"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3
+   {rlnm.|rlwnm.} %0,%1,%2,%m3,%M3
+   {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
   "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
 
 (define_insn "*rotlsi3_internal8"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:SI
                     (subreg:QI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff
+   {rlnm.|rlwnm.} %3,%1,%2,0xff
+   {rlinm.|rlwinm.} %3,%1,%h2,0xff
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotlsi3_internal9"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:SI
                     (subreg:QI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff
+   {rlnm.|rlwnm.} %0,%1,%2,0xff
+   {rlinm.|rlwinm.} %0,%1,%h2,0xff
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotlsi3_internal10"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI
         (subreg:HI
-         (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                    (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
+         (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))]
   ""
-  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
+  "@
+   {rlnm|rlwnm} %0,%1,%2,0xffff
+   {rlinm|rlwinm} %0,%1,%h2,0xffff"
+  [(set_attr "type" "var_shift_rotate,integer")])
+
 
 (define_insn "*rotlsi3_internal11"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:SI
                     (subreg:HI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff
+   {rlnm.|rlwnm.} %3,%1,%2,0xffff
+   {rlinm.|rlwinm.} %3,%1,%h2,0xffff
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotlsi3_internal12"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:SI
                     (subreg:HI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
   ""
   "@
-   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff
+   {rlnm.|rlwnm.} %0,%1,%2,0xffff
+   {rlinm.|rlwinm.} %0,%1,%h2,0xffff
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
    {sli|slwi} %0,%1,%h2")
 
 (define_insn "ashlsi3_no_power"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                  (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                  (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
   "! TARGET_POWER"
-  "{sl|slw}%I2 %0,%1,%h2")
+  "@
+   {sl|slw} %0,%1,%2
+   {sli|slwi} %0,%1,%h2"
+  [(set_attr "type" "var_shift_rotate,shift")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
   "! TARGET_POWER && TARGET_32BIT"
   "@
-   {sl|slw}%I2. %3,%1,%h2
+   {sl.|slw.} %3,%1,%2
+   {sli.|slwi.} %3,%1,%h2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (ashift:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER && TARGET_32BIT"
   "@
-   {sl|slw}%I2. %0,%1,%h2
+   {sl.|slw.} %0,%1,%2
+   {sli.|slwi.} %0,%1,%h2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   {s%A2i|s%A2wi} %0,%1,%h2")
 
 (define_insn "lshrsi3_no_power"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-       (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                    (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
+       (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+                    (match_operand:SI 2 "reg_or_cint_operand" "O,r,i")))]
   "! TARGET_POWER"
   "@
   mr %0,%1
-  {sr|srw}%I2 %0,%1,%h2")
+  {sr|srw} %0,%1,%2
+  {sri|srwi} %0,%1,%h2"
+  [(set_attr "type" "integer,var_shift_rotate,shift")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
-       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=X,r,X,r"))]
+   (clobber (match_scratch:SI 3 "=X,r,r,X,r,r"))]
   "! TARGET_POWER && TARGET_32BIT"
   "@
    mr. %1,%1
-   {sr|srw}%I2. %3,%1,%h2
+   {sr.|srw.} %3,%1,%2
+   {sri.|srwi.} %3,%1,%h2
+   #
    #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,4,8,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
-       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
        (lshiftrt:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER && TARGET_32BIT"
   "@
    mr. %0,%1
-   {sr|srw}%I2. %0,%1,%h2
+   {sr.|srw.} %0,%1,%2
+   {sri.|srwi.} %0,%1,%h2
+   #
    #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,4,8,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   "TARGET_POWER"
   "@
    srea %0,%1,%2
-   {srai|srawi} %0,%1,%h2")
+   {srai|srawi} %0,%1,%h2"
+  [(set_attr "type" "shift")])
 
 (define_insn "ashrsi3_no_power"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                    (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
   "! TARGET_POWER"
-  "{sra|sraw}%I2 %0,%1,%h2")
+  "@
+   {sra|sraw} %0,%1,%2
+   {srai|srawi} %0,%1,%h2"
+  [(set_attr "type" "var_shift_rotate,shift")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
   "! TARGET_POWER"
   "@
-   {sra|sraw}%I2. %3,%1,%h2
+   {sra.|sraw.} %3,%1,%2
+   {srai.|srawi.} %3,%1,%h2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER"
   "@
-   {sra|sraw}%I2. %0,%1,%h2
+   {sra.|sraw.} %0,%1,%2
+   {srai.|srawi.} %0,%1,%h2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 \f
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
              (clobber (match_dup 4))
              (clobber (match_dup 5))
              (clobber (match_dup 6))])]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
   "
 {
   if (TARGET_E500_DOUBLE)
       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
       DONE;
     }
+  if (TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS)
+    {
+      rtx t1 = gen_reg_rtx (DImode);
+      emit_insn (gen_floatsidf_ppc64_mfpgpr (operands[0], operands[1], t1));
+      DONE;
+    }
   if (TARGET_POWERPC64)
     {
       rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
-  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[4]))"
+  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
   "
 {
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
-  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[4]))"
+  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
   [(pc)]
   "
 {
      DONE;
     }
   operands[2] = gen_reg_rtx (DImode);
+  if (TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+      && gpc_reg_operand(operands[0], GET_MODE (operands[0])))
+    {
+      operands[3] = gen_reg_rtx (DImode);
+      emit_insn (gen_fix_truncdfsi2_mfpgpr (operands[0], operands[1],
+                                           operands[2], operands[3]));
+      DONE;
+    }
   if (TARGET_PPC_GFXOPT)
     {
       rtx orig_dest = operands[0];
    (clobber (match_operand:DI 3 "memory_operand" "=o"))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
-  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[3]))"
+  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
   [(pc)]
   "
 {
 }"
   [(set_attr "length" "16")])
 
+(define_insn_and_split "fix_truncdfsi2_mfpgpr"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+       (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
+   (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "#"
+  "&& 1"
+  [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ))
+   (set (match_dup 3) (match_dup 2))
+   (set (match_dup 0) (subreg:SI (match_dup 3) 4))]
+  ""
+  [(set_attr "length" "12")])
+
 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
 ; because the first makes it clear that operand 0 is not live
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
+(define_insn_and_split "floatsidf_ppc64_mfpgpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+       (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=r"))]
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "#"
+  "&& 1"
+  [(set (match_dup 2) (sign_extend:DI (match_dup 1)))
+   (set (match_dup 0) (float:DF (match_dup 2)))]
+  "")
+
 (define_insn_and_split "floatsidf_ppc64"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (clobber (match_operand:DI 2 "memory_operand" "=o"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
    (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
   "&& 1"
   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (truncate:SI
         (lshiftrt:DI (mult:DI (sign_extend:DI
-                               (match_operand:SI 1 "gpc_reg_operand" "%r"))
+                               (match_operand:SI 1 "gpc_reg_operand" ""))
                               (sign_extend:DI
-                               (match_operand:SI 2 "gpc_reg_operand" "r")))
+                               (match_operand:SI 2 "gpc_reg_operand" "")))
                      (const_int 32))))]
   ""
   "
   "@
    {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
    sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "shift")
+   (set_attr "length" "8")])
 
 (define_insn "ashrdi3_no_power"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
   [(set_attr "type" "lmul")])
 
 (define_insn "rotldi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                  (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                  (match_operand:DI 2 "reg_or_cint_operand" "r,i")))]
   "TARGET_POWERPC64"
-  "rld%I2cl %0,%1,%H2,0")
+  "@
+   rldcl %0,%1,%2,0
+   rldicl %0,%1,%H2,0"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotldi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %3,%1,%H2,0
+   rldcl. %3,%1,%2,0
+   rldicl. %3,%1,%H2,0
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (rotate:DI (match_dup 1) (match_dup 2)))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %0,%1,%H2,0
+   rldcl. %0,%1,%2,0
+   rldicl. %0,%1,%H2,0
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal4"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-       (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                          (match_operand:DI 2 "reg_or_cint_operand" "ri"))
-               (match_operand:DI 3 "mask64_operand" "n")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                          (match_operand:DI 2 "reg_or_cint_operand" "r,i"))
+               (match_operand:DI 3 "mask64_operand" "n,n")))]
   "TARGET_POWERPC64"
-  "rld%I2c%B3 %0,%1,%H2,%S3")
+  "@
+   rldc%B3 %0,%1,%2,%S3
+   rldic%B3 %0,%1,%H2,%S3"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotldi3_internal5"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (and:DI
-                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                               (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
-                    (match_operand:DI 3 "mask64_operand" "n,n"))
+                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                               (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
+                    (match_operand:DI 3 "mask64_operand" "n,n,n,n"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 4 "=r,r"))]
+   (clobber (match_scratch:DI 4 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   rld%I2c%B3. %4,%1,%H2,%S3
+   rldc%B3. %4,%1,%2,%S3
+   rldic%B3. %4,%1,%H2,%S3
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal6"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (and:DI
-                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                               (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
-                    (match_operand:DI 3 "mask64_operand" "n,n"))
+                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                               (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
+                    (match_operand:DI 3 "mask64_operand" "n,n,n,n"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_64BIT"
   "@
-   rld%I2c%B3. %0,%1,%H2,%S3
+   rldc%B3. %0,%1,%2,%S3
+   rldic%B3. %0,%1,%H2,%S3
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal7"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI
         (subreg:QI
-         (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                    (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
+         (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
   "TARGET_POWERPC64"
-  "rld%I2cl %0,%1,%H2,56")
+  "@
+   rldcl %0,%1,%2,56
+   rldicl %0,%1,%H2,56"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotldi3_internal8"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:DI
                     (subreg:QI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %3,%1,%H2,56
+   rldcl. %3,%1,%2,56
+   rldicl. %3,%1,%H2,56
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal9"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:DI
                     (subreg:QI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %0,%1,%H2,56
+   rldcl. %0,%1,%2,56
+   rldicl. %0,%1,%H2,56
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal10"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI
         (subreg:HI
-         (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                    (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
+         (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
   "TARGET_POWERPC64"
-  "rld%I2cl %0,%1,%H2,48")
+  "@
+   rldcl %0,%1,%2,48
+   rldicl %0,%1,%H2,48"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotldi3_internal11"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:DI
                     (subreg:HI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %3,%1,%H2,48
+   rldcl. %3,%1,%2,48
+   rldicl. %3,%1,%H2,48
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal12"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:DI
                     (subreg:HI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %0,%1,%H2,48
+   rldcl. %0,%1,%2,48
+   rldicl. %0,%1,%H2,48
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal13"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI
         (subreg:SI
-         (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                    (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
+         (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
   "TARGET_POWERPC64"
-  "rld%I2cl %0,%1,%H2,32")
+  "@
+   rldcl %0,%1,%2,32
+   rldicl %0,%1,%H2,32"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotldi3_internal14"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:DI
                     (subreg:SI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %3,%1,%H2,32
+   rldcl. %3,%1,%2,32
+   rldicl. %3,%1,%H2,32
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*rotldi3_internal15"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC (zero_extend:DI
                     (subreg:SI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
   "TARGET_64BIT"
   "@
-   rld%I2cl. %0,%1,%H2,32
+   rldcl. %0,%1,%2,32
+   rldicl. %0,%1,%H2,32
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
 }")
 
 (define_insn "*ashldi3_internal1"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-       (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                  (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                  (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
   "TARGET_POWERPC64"
-  "sld%I2 %0,%1,%H2")
+  "@
+   sld %0,%1,%2
+   sldi %0,%1,%H2"
+  [(set_attr "type" "var_shift_rotate,shift")])
 
 (define_insn "*ashldi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   sld%I2. %3,%1,%H2
+   sld. %3,%1,%2
+   sldi. %3,%1,%H2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*ashldi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (ashift:DI (match_dup 1) (match_dup 2)))]
   "TARGET_64BIT"
   "@
-   sld%I2. %0,%1,%H2
+   sld. %0,%1,%2
+   sldi. %0,%1,%H2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
 }")
 
 (define_insn "*lshrdi3_internal1"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-       (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                    (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
   "TARGET_POWERPC64"
-  "srd%I2 %0,%1,%H2")
+  "@
+   srd %0,%1,%2
+   srdi %0,%1,%H2"
+  [(set_attr "type" "var_shift_rotate,shift")])
 
 (define_insn "*lshrdi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT "
   "@
-   srd%I2. %3,%1,%H2
+   srd. %3,%1,%2
+   srdi. %3,%1,%H2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*lshrdi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (lshiftrt:DI (match_dup 1) (match_dup 2)))]
   "TARGET_64BIT"
   "@
-   srd%I2. %0,%1,%H2
+   srd. %0,%1,%2
+   srdi. %0,%1,%H2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
 }")
 
 (define_insn "*ashrdi3_internal1"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-       (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                    (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                    (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
   "TARGET_POWERPC64"
-  "srad%I2 %0,%1,%H2")
+  "@
+   srad %0,%1,%2
+   sradi %0,%1,%H2"
+  [(set_attr "type" "var_shift_rotate,shift")])
 
 (define_insn "*ashrdi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_64BIT"
   "@
-   srad%I2. %3,%1,%H2
+   srad. %3,%1,%2
+   sradi. %3,%1,%H2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
   "")
 
 (define_insn "*ashrdi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
   "TARGET_64BIT"
   "@
-   srad%I2. %0,%1,%H2
+   srad. %0,%1,%2
+   sradi. %0,%1,%H2
+   #
    #"
-  [(set_attr "type" "delayed_compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+  [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+  [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
   if (non_logical_cint_operand (operands[2], DImode))
     {
       HOST_WIDE_INT value;
-      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+      rtx tmp = ((!can_create_pseudo_p ()
+                 || rtx_equal_p (operands[0], operands[1]))
                 ? operands[0] : gen_reg_rtx (DImode));
 
       if (GET_CODE (operands[2]) == CONST_INT)
   if (non_logical_cint_operand (operands[2], DImode))
     {
       HOST_WIDE_INT value;
-      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+      rtx tmp = ((!can_create_pseudo_p ()
+                 || rtx_equal_p (operands[0], operands[1]))
                 ? operands[0] : gen_reg_rtx (DImode));
 
       if (GET_CODE (operands[2]) == CONST_INT)
       value = INTVAL (offset);
       if (value != 0)
        {
-         rtx tmp = (no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode));
+         rtx tmp = (!can_create_pseudo_p ()
+                    ? operands[0]
+                    : gen_reg_rtx (Pmode));
          emit_insn (gen_movsi_got (tmp, operands[1]));
          emit_insn (gen_addsi3 (operands[0], tmp, offset));
          DONE;
   "")
 
 (define_insn "*movcc_internal1"
-  [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,r,r,r,r,q,cl,r,m")
-       (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,h,r,r,m,r"))]
+  [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,q,cl,r,m")
+       (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,r,m,r"))]
   "register_operand (operands[0], CCmode)
    || register_operand (operands[1], CCmode)"
   "@
    mcrf %0,%1
    mtcrf 128,%1
    {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
+   crxor %0,%0,%0
    mfcr %0%Q1
    mfcr %0%Q1\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
    mr %0,%1
+   {lil|li} %0,%1
    mf%1 %0
    mt%0 %1
    mt%0 %1
    {l%U1%X1|lwz%U1%X1} %0,%1
    {st%U0%U1|stw%U0%U1} %1,%0"
   [(set (attr "type")
-     (cond [(eq_attr "alternative" "0")
+     (cond [(eq_attr "alternative" "0,3")
                (const_string "cr_logical")
            (eq_attr "alternative" "1,2")
                (const_string "mtcr")
-           (eq_attr "alternative" "5,7")
+           (eq_attr "alternative" "6,7,9")
                (const_string "integer")
-           (eq_attr "alternative" "6")
-               (const_string "mfjmpr")
            (eq_attr "alternative" "8")
+               (const_string "mfjmpr")
+           (eq_attr "alternative" "10")
                (const_string "mtjmpr")
-           (eq_attr "alternative" "9")
+           (eq_attr "alternative" "11")
                (const_string "load")
-           (eq_attr "alternative" "10")
+           (eq_attr "alternative" "12")
                (const_string "store")
            (ne (symbol_ref "TARGET_MFCRF") (const_int 0))
                (const_string "mfcrf")
           ]
        (const_string "mfcr")))
-   (set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")])
+   (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4,4")])
 \f
 ;; For floating-point, we normally deal with the floating-point registers
 ;; unless -msoft-float is used.  The sole exception is that parameter passing
          || (GET_CODE (operands[1]) == MEM
              && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
                  || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
-                 || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)))
+                 || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
+                 || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)))
        {
          /* If the low-address word is used in the address, we must load
             it last.  Otherwise, load it first.  Note that we cannot have
                                 operands[1], 0))
            return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
          else
-           return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+           return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
        }
       else
        {
                                 operands[1], 0))
            {
              output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
-             output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+             output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands);
              output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
-             return \"{lx|lwzx} %0,%1\";
+             return \"{l%X1|lwz%X1} %0,%1\";
            }
          else
            {
-             output_asm_insn (\"{lx|lwzx} %0,%1\", operands);
+             output_asm_insn (\"{l%X1|lwz%X1} %0,%1\", operands);
              output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
-             output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+             output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands);
              output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
              return \"\";
            }
          || (GET_CODE (operands[0]) == MEM
              && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM
                  || GET_CODE (XEXP (operands[0], 0)) == PRE_INC
-                 || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)))
-       return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+                 || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
+                 || GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)))
+       return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
       else
        {
          rtx addreg;
 
          addreg = find_addr_reg (XEXP (operands[0], 0));
-         output_asm_insn (\"{stx|stwx} %1,%0\", operands);
+         output_asm_insn (\"{st%X0|stw%X0} %1,%0\", operands);
          output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
-         output_asm_insn (\"{stx|stwx} %L1,%0\", operands);
+         output_asm_insn (\"{st%X0|stw%X0} %L1,%0\", operands);
          output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
          return \"\";
        }
                             operands[1], 0))
        return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
       else
-       return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+       return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
     case 2:
-      return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+      return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
     case 3:
     case 4:
     case 5:
 
 ; ld/std require word-aligned displacements -> 'Y' constraint.
 ; List Y->r and r->Y before r->r for reload.
+(define_insn "*movdf_hardfloat64_mfpgpr"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
+       (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+   && (gpc_reg_operand (operands[0], DFmode)
+       || gpc_reg_operand (operands[1], DFmode))"
+  "@
+   std%U0%X0 %1,%0
+   ld%U1%X1 %0,%1
+   mr %0,%1
+   fmr %0,%1
+   lfd%U1%X1 %0,%1
+   stfd%U0%X0 %1,%0
+   mt%0 %1
+   mf%1 %0
+   {cror 0,0,0|nop}
+   #
+   #
+   #
+   mftgpr %0,%1
+   mffgpr %0,%1"
+  [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
+   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
+
+; ld/std require word-aligned displacements -> 'Y' constraint.
+; List Y->r and r->Y before r->r for reload.
 (define_insn "*movdf_hardfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
        (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
 (define_expand "movtf"
   [(set (match_operand:TF 0 "general_operand" "")
        (match_operand:TF 1 "any_operand" ""))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+  "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
   "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
 
 ; It's important to list the o->f and f->o moves before f->f because
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
   [(set_attr "length" "8,8,8,20,20,16")])
 
+(define_insn_and_split "*movtf_softfloat"
+  [(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=r,Y,r")
+       (match_operand:TF 1 "input_operand"         "YGHF,r,r"))]
+  "!TARGET_IEEEQUAD
+   && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128
+   && (gpc_reg_operand (operands[0], TFmode)
+       || gpc_reg_operand (operands[1], TFmode))"
+  "#"
+  "&& reload_completed"
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
+  [(set_attr "length" "20,20,16")])
+
 (define_expand "extenddftf2"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "")
+       (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
+  "!TARGET_IEEEQUAD
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
+{
+  if (TARGET_E500_DOUBLE)
+    emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
+  else
+    emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
+  DONE;
+})
+
+(define_expand "extenddftf2_fprs"
   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
                   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
              (use (match_dup 2))])]
   [(set (match_operand:TF 0 "nonimmediate_operand" "")
        (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
 {
   rtx tmp = gen_reg_rtx (DFmode);
   emit_insn (gen_extendsfdf2 (tmp, operands[1]));
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
   "")
 
 (define_insn_and_split "trunctfdf2_internal1"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")])
 
-(define_insn_and_split "trunctfsf2"
+(define_expand "trunctfsf2"
+  [(set (match_operand:SF 0 "gpc_reg_operand" "")
+       (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
+  "!TARGET_IEEEQUAD
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
+{
+  if (TARGET_E500_DOUBLE)
+    emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
+  else
+    emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
+  DONE;
+})
+
+(define_insn_and_split "trunctfsf2_fprs"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
    (clobber (match_scratch:DF 2 "=f"))]
   "")
 
 (define_expand "floatsitf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
-        (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))]
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+        (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
 {
   rtx tmp = gen_reg_rtx (DFmode);
   expand_float (tmp, operands[1], false);
    (set_attr "length" "20")])
 
 (define_expand "fix_trunctfsi2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+       (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
+  "!TARGET_IEEEQUAD
+   && (TARGET_POWER2 || TARGET_POWERPC)
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
+{
+  if (TARGET_E500_DOUBLE)
+    emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
+  else
+    emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
+  DONE;
+})
+
+(define_expand "fix_trunctfsi2_fprs"
   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
                   (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
              (clobber (match_dup 2))
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
-  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[5]))"
+  "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[5]))"
   [(pc)]
 {
   rtx lowword;
   DONE;
 })
 
-(define_insn "negtf2"
+(define_expand "negtf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+       (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
+  "!TARGET_IEEEQUAD
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
+  "")
+
+(define_insn "negtf2_internal"
   [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
        (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
   "!TARGET_IEEEQUAD
    (set_attr "length" "8")])
 
 (define_expand "abstf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
-       (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+       (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
   "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
   "
 {
   rtx label = gen_label_rtx ();
-  emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
+  if (TARGET_E500_DOUBLE)
+    {
+      if (flag_unsafe_math_optimizations)
+       emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
+      else
+       emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
+    }
+  else
+    emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
   emit_label (label);
   DONE;
 }")
 
 (define_expand "abstf2_internal"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
-       (match_operand:TF 1 "gpc_reg_operand" "f"))
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+       (match_operand:TF 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)))
 ; List r->r after r->"o<>", otherwise reload will try to reload a
 ; non-offsettable address by using r->r which won't make progress.
 (define_insn "*movdi_internal32"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
+  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
        (match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))]
   "! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
 }")
 
 (define_split
-  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "")
         (match_operand:DI 1 "input_operand" ""))]
   "reload_completed && !TARGET_POWERPC64
    && gpr_or_gpr_p (operands[0], operands[1])"
   [(pc)]
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
+(define_insn "*movdi_mfpgpr"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h,r,*f")
+       (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0,*f,r"))]
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+   && (gpc_reg_operand (operands[0], DImode)
+       || gpc_reg_operand (operands[1], DImode))"
+  "@
+   mr %0,%1
+   ld%U1%X1 %0,%1
+   std%U0%X0 %1,%0
+   li %0,%1
+   lis %0,%v1
+   #
+   {cal|la} %0,%a1
+   fmr %0,%1
+   lfd%U1%X1 %0,%1
+   stfd%U0%X0 %1,%0
+   mf%1 %0
+   mt%0 %1
+   {cror 0,0,0|nop}
+   mftgpr %0,%1
+   mffgpr %0,%1"
+  [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,mftgpr,mffgpr")
+   (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")])
+
 (define_insn "*movdi_internal64"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h")
        (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
-  "TARGET_POWERPC64
+  "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS)
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
   "@
   [(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"))
+     (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_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"))
+     (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_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"))
+     (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_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"))
+     (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_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"))
+     (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_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"))
+     (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_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 "q"))
+     (clobber (match_scratch:SI 3 "=q"))
      (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_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 "q"))
+     (clobber (match_scratch:SI 3 "=q"))
      (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_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 "q"))
+     (clobber (match_scratch:SI 3 "=q"))
      (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_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 "q"))
+     (clobber (match_scratch:SI 3 "=q"))
      (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_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 "q"))
+     (clobber (match_scratch:SI 3 "=q"))
      (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_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 "q"))
+     (clobber (match_scratch:SI 3 "=q"))
      (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)))
    (clobber (reg:SI 10))
    (clobber (reg:SI 11))
    (clobber (reg:SI 12))
-   (clobber (match_scratch:SI 5 "X"))]
+   (clobber (match_scratch:SI 5 "=X"))]
   "TARGET_STRING && ! TARGET_POWER
    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
        || INTVAL (operands[2]) == 0)
    (clobber (reg:SI  8))
    (clobber (reg:SI  9))
    (clobber (reg:SI 10))
-   (clobber (match_scratch:SI 5 "X"))]
+   (clobber (match_scratch:SI 5 "=X"))]
   "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
    (clobber (reg:SI 6))
    (clobber (reg:SI 7))
    (clobber (reg:SI 8))
-   (clobber (match_scratch:SI 5 "X"))]
+   (clobber (match_scratch:SI 5 "=X"))]
   "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
    (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"))]
+   (clobber (match_scratch:SI 5 "=X"))]
   "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
    (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"))]
+   (clobber (match_scratch:SI 5 "=X"))]
   "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
 ;; We move the back-chain and decrement the stack pointer.
 
 (define_expand "allocate_stack"
-  [(set (match_operand 0 "gpc_reg_operand" "=r")
+  [(set (match_operand 0 "gpc_reg_operand" "")
        (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
    (set (reg 1)
        (minus (reg 1) (match_dup 1)))]
   [(set_attr "type" "load")])
 
 (define_insn "load_toc_v4_pic_si"
-  [(set (match_operand:SI 0 "register_operand" "=l")
+  [(set (reg:SI LR_REGNO)
        (unspec:SI [(const_int 0)] UNSPEC_TOC))]
   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
   "bl _GLOBAL_OFFSET_TABLE_@local-4"
    (set_attr "length" "4")])
 
 (define_insn "load_toc_v4_PIC_1"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-       (match_operand:SI 1 "immediate_operand" "s"))
-   (use (unspec [(match_dup 1)] UNSPEC_TOC))]
+  [(set (reg:SI LR_REGNO)
+       (match_operand:SI 0 "immediate_operand" "s"))
+   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
   "TARGET_ELF && DEFAULT_ABI != ABI_AIX
    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
-  "bcl 20,31,%1\\n%1:"
+  "bcl 20,31,%0\\n%0:"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
 (define_insn "load_toc_v4_PIC_1b"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-       (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")]
+  [(set (reg:SI LR_REGNO)
+       (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")]
                UNSPEC_TOCPTR))]
   "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
-  "bcl 20,31,$+8\\n\\t.long %1-$"
+  "bcl 20,31,$+8\\n\\t.long %0-$"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
                                  CODE_LABEL_NUMBER (operands[0]));
       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
 
-      emit_insn (gen_load_macho_picbase (picreg, tmplabrtx));
+      emit_insn (gen_load_macho_picbase (tmplabrtx));
+      emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
     }
   else
              (use (reg:SI 11))
              (set (reg:SI 2)
                   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-             (clobber (scratch:SI))])]
+             (clobber (reg:SI LR_REGNO))])]
   "TARGET_32BIT"
   "
 { operands[2] = gen_reg_rtx (SImode); }")
              (use (reg:DI 11))
              (set (reg:DI 2)
                   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-             (clobber (scratch:SI))])]
+             (clobber (reg:SI LR_REGNO))])]
   "TARGET_64BIT"
   "
 { operands[2] = gen_reg_rtx (DImode); }")
              (use (reg:SI 11))
              (set (reg:SI 2)
                   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-             (clobber (scratch:SI))])]
+             (clobber (reg:SI LR_REGNO))])]
   "TARGET_32BIT"
   "
 { operands[3] = gen_reg_rtx (SImode); }")
              (use (reg:DI 11))
              (set (reg:DI 2)
                   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-             (clobber (scratch:SI))])]
+             (clobber (reg:SI LR_REGNO))])]
   "TARGET_64BIT"
   "
 { operands[3] = gen_reg_rtx (DImode); }")
   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
                    (match_operand 1 "" ""))
              (use (match_operand 2 "" ""))
-             (clobber (scratch:SI))])]
+             (clobber (reg:SI LR_REGNO))])]
   ""
   "
 {
                                     gen_rtx_MEM (SImode, operands[0]),
                                     operands[1]),
                       gen_rtx_USE (VOIDmode, operands[2]),
-                      gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
+                      gen_rtx_CLOBBER (VOIDmode,
+                                       gen_rtx_REG (Pmode, LR_REGNO)));
       call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
       use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
       DONE;
                   (call (mem:SI (match_operand 1 "address_operand" ""))
                         (match_operand 2 "" "")))
              (use (match_operand 3 "" ""))
-             (clobber (scratch:SI))])]
+             (clobber (reg:SI LR_REGNO))])]
   ""
   "
 {
                                                               operands[1]),
                                                  operands[2])),
                       gen_rtx_USE (VOIDmode, operands[3]),
-                      gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
+                      gen_rtx_CLOBBER (VOIDmode, 
+                                       gen_rtx_REG (Pmode, LR_REGNO)));
       call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
       use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
       DONE;
   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (clobber (match_scratch:SI 3 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "(INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (clobber (match_scratch:SI 3 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
        (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (clobber (match_scratch:SI 4 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "(INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
        (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (clobber (match_scratch:SI 4 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
    (use (reg:SI 11))
    (set (reg:SI 2)
        (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-   (clobber (match_scratch:SI 2 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
   "b%T0l\;{l|lwz} 2,20(1)"
   [(set_attr "type" "jmpreg")
   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
         (match_operand 1 "" "g"))
    (use (match_operand:SI 2 "immediate_operand" "O"))
-   (clobber (match_scratch:SI 3 "=l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_32BIT
    && DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
    (use (reg:DI 11))
    (set (reg:DI 2)
        (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (match_scratch:SI 2 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
   "b%T0l\;ld 2,40(1)"
   [(set_attr "type" "jmpreg")
   [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
         (match_operand 1 "" "g"))
    (use (match_operand:SI 2 "immediate_operand" "O"))
-   (clobber (match_scratch:SI 3 "=l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT
    && DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
    (use (reg:SI 11))
    (set (reg:SI 2)
        (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-   (clobber (match_scratch:SI 3 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
   "b%T1l\;{l|lwz} 2,20(1)"
   [(set_attr "type" "jmpreg")
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
              (match_operand 2 "" "g")))
    (use (match_operand:SI 3 "immediate_operand" "O"))
-   (clobber (match_scratch:SI 4 "=l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_32BIT
    && DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
    (use (reg:DI 11))
    (set (reg:DI 2)
        (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (match_scratch:SI 3 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
   "b%T1l\;ld 2,40(1)"
   [(set_attr "type" "jmpreg")
        (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
              (match_operand 2 "" "g")))
    (use (match_operand:SI 3 "immediate_operand" "O"))
-   (clobber (match_scratch:SI 4 "=l"))]
+   (clobber (reg:SI LR_REGNO))]
   "TARGET_64BIT
    && DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
 ;; which indicates how to set cr1
 
-(define_insn "*call_indirect_nonlocal_sysv"
-  [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l,c,*l"))
+(define_insn "*call_indirect_nonlocal_sysv<mode>"
+  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
         (match_operand 1 "" "g,g,g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
-   (clobber (match_scratch:SI 3 "=l,l,l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "DEFAULT_ABI == ABI_V4
    || DEFAULT_ABI == ABI_DARWIN"
 {
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    (set_attr "length" "4,4,8,8")])
 
-(define_insn "*call_nonlocal_sysv"
-  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
+(define_insn "*call_nonlocal_sysv<mode>"
+  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (clobber (match_scratch:SI 3 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "(DEFAULT_ABI == ABI_DARWIN
    || (DEFAULT_ABI == ABI_V4
        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
 
-(define_insn "*call_value_indirect_nonlocal_sysv"
+(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "register_operand" "c,*l,c,*l"))
+       (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
              (match_operand 2 "" "g,g,g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
-   (clobber (match_scratch:SI 4 "=l,l,l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "DEFAULT_ABI == ABI_V4
    || DEFAULT_ABI == ABI_DARWIN"
 {
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    (set_attr "length" "4,4,8,8")])
 
-(define_insn "*call_value_nonlocal_sysv"
+(define_insn "*call_value_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
+       (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (clobber (match_scratch:SI 4 "=l,l"))]
+   (clobber (reg:SI LR_REGNO))]
   "(DEFAULT_ABI == ABI_DARWIN
    || (DEFAULT_ABI == ABI_V4
        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
                    (match_operand 1 "" ""))
              (use (match_operand 2 "" ""))
-             (use (match_operand 3 "" ""))
+             (use (reg:SI LR_REGNO))
              (return)])]
   ""
   "
   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
 
   operands[0] = XEXP (operands[0], 0);
-  operands[3] = gen_reg_rtx (SImode);
-
 }")
 
 ;; this and similar patterns must be marked as using LR, otherwise
   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (use (match_operand:SI 3 "register_operand" "l,l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "(INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (use (match_operand:SI 3 "register_operand" "l,l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
        (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (use (match_operand:SI 4 "register_operand" "l,l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "(INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
        (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (use (match_operand:SI 4 "register_operand" "l,l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
         (match_operand 1 "" "g"))
    (use (match_operand:SI 2 "immediate_operand" "O"))
-   (use (match_operand:SI 3 "register_operand" "l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "TARGET_32BIT
    && DEFAULT_ABI == ABI_AIX
   [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
         (match_operand 1 "" "g"))
    (use (match_operand:SI 2 "immediate_operand" "O"))
-   (use (match_operand:SI 3 "register_operand" "l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "TARGET_64BIT
    && DEFAULT_ABI == ABI_AIX
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
              (match_operand 2 "" "g")))
    (use (match_operand:SI 3 "immediate_operand" "O"))
-   (use (match_operand:SI 4 "register_operand" "l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "TARGET_32BIT
    && DEFAULT_ABI == ABI_AIX
        (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
              (match_operand 2 "" "g")))
    (use (match_operand:SI 3 "immediate_operand" "O"))
-   (use (match_operand:SI 4 "register_operand" "l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "TARGET_64BIT
    && DEFAULT_ABI == ABI_AIX
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
-(define_insn "*sibcall_nonlocal_sysv"
-  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
+(define_insn "*sibcall_nonlocal_sysv<mode>"
+  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
         (match_operand 1 "" ""))
    (use (match_operand 2 "immediate_operand" "O,n"))
-   (use (match_operand:SI 3 "register_operand" "l,l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "(DEFAULT_ABI == ABI_DARWIN
      || DEFAULT_ABI == ABI_V4)
                (call (mem:SI (match_operand 1 "address_operand" ""))
                      (match_operand 2 "" "")))
              (use (match_operand 3 "" ""))
-             (use (match_operand 4 "" ""))
+             (use (reg:SI LR_REGNO))
              (return)])]
   ""
   "
   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
 
   operands[1] = XEXP (operands[1], 0);
-  operands[4] = gen_reg_rtx (SImode);
-
 }")
 
-(define_insn "*sibcall_value_nonlocal_sysv"
+(define_insn "*sibcall_value_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
+       (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
              (match_operand 2 "" "")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (use (match_operand:SI 4 "register_operand" "l,l"))
+   (use (reg:SI LR_REGNO))
    (return)]
   "(DEFAULT_ABI == ABI_DARWIN
        || DEFAULT_ABI == ABI_V4)
 
 (define_expand "bunordered"
   [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
 
 (define_expand "bordered"
   [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
 
 (define_expand "buneq"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
 
 (define_expand "bunge"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
 
 (define_expand "bungt"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
 
 (define_expand "bunle"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
 
 (define_expand "bunlt"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
 
 (define_expand "bltgt"
 
 (define_expand "sunordered"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
 
 (define_expand "sordered"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
 
 (define_expand "suneq"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
 
 (define_expand "sunge"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
 
 (define_expand "sungt"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
 
 (define_expand "sunle"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
 
 (define_expand "sunlt"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
 
 (define_expand "sltgt"
 
 (define_expand "tablejumpdi"
   [(set (match_dup 4)
-        (sign_extend:DI (match_operand:SI 0 "lwa_operand" "rm")))
+        (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
    (set (match_dup 3)
        (plus:DI (match_dup 4)
                 (match_dup 2)))
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 0))]
   ""
-  "{t 31,0,0|trap}")
+  "{t 31,0,0|trap}"
+  [(set_attr "type" "trap")])
 
 (define_expand "conditional_trap"
   [(trap_if (match_operator 0 "trap_comparison_operator"
                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
            (const_int 0))]
   ""
-  "{t|t<wd>}%V0%I2 %1,%2")
+  "{t|t<wd>}%V0%I2 %1,%2"
+  [(set_attr "type" "trap")])
 \f
 ;; Insns related to generating the function prologue and epilogue.
 
 
 (define_insn "movesi_from_cr"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-        (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
-                   (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)]
+        (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
+                   (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
+                   (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
+                   (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
                   UNSPEC_MOVESI_FROM_CR))]
   ""
   "mfcr %0"
 
 (define_insn "*save_fpregs_<mode>"
   [(match_parallel 0 "any_parallel_operand"
-                  [(clobber (match_operand:P 1 "register_operand" "=l"))
-                   (use (match_operand:P 2 "call_operand" "s"))
-                   (set (match_operand:DF 3 "memory_operand" "=m")
-                        (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+                  [(clobber (reg:P 65))
+                   (use (match_operand:P 1 "call_operand" "s"))
+                   (set (match_operand:DF 2 "memory_operand" "=m")
+                        (match_operand:DF 3 "gpc_reg_operand" "f"))])]
   ""
-  "bl %z2"
+  "bl %z1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
 ; faster; for instance, on the 601 and 750.
 
 (define_expand "movsi_to_cr_one"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
-        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+  [(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])));")
 (define_insn "*return_and_restore_fpregs_<mode>"
  [(match_parallel 0 "any_parallel_operand"
                   [(return)
-                  (use (match_operand:P 1 "register_operand" "l"))
-                  (use (match_operand:P 2 "call_operand" "s"))
-                  (set (match_operand:DF 3 "gpc_reg_operand" "=f")
-                       (match_operand:DF 4 "memory_operand" "m"))])]
+                  (use (reg:P 65))
+                  (use (match_operand:P 1 "call_operand" "s"))
+                  (set (match_operand:DF 2 "gpc_reg_operand" "=f")
+                       (match_operand:DF 3 "memory_operand" "m"))])]
  ""
- "b %z2")
+ "b %z1")
 
 ; This is used in compiling the unwind routines.
 (define_expand "eh_return"
 (include "sync.md")
 (include "altivec.md")
 (include "spe.md")
+(include "dfp.md")