OSDN Git Service

gcc/ada/
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.md
index 62541df..debacdc 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)
 
@@ -8,7 +8,7 @@
 
 ;; GCC is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published
-;; by the Free Software Foundation; either version 2, or (at your
+;; by the Free Software Foundation; either version 3, or (at your
 ;; option) any later version.
 
 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
 ;; License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING.  If not, write to the
-;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-;; MA 02110-1301, USA.
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
 
 ;;- 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
 ;;
 
 (include "darwin.md")
 
 \f
-;; Mode macros
+;; Mode iterators
 
-; This mode macro allows :GPR to be used to indicate the allowable size
+; This mode iterator allows :GPR to be used to indicate the allowable size
 ; of whole values in GPRs.
-(define_mode_macro GPR [SI (DI "TARGET_POWERPC64")])
+(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
 
 ; Any supported integer mode.
-(define_mode_macro INT [QI HI SI DI TI])
+(define_mode_iterator INT [QI HI SI DI TI])
 
 ; Any supported integer mode that fits in one register.
-(define_mode_macro INT1 [QI HI SI (DI "TARGET_POWERPC64")])
+(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
 
 ; extend modes for DImode
-(define_mode_macro QHSI [QI HI SI])
+(define_mode_iterator QHSI [QI HI SI])
 
 ; SImode or DImode, even if DImode doesn't fit in GPRs.
-(define_mode_macro SDI [SI DI])
+(define_mode_iterator SDI [SI DI])
 
 ; The size of a pointer.  Also, the size of the value that a record-condition
 ; (one with a '.') will compare.
-(define_mode_macro P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
+(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
 
 ; Any hardware-supported floating-point mode
-(define_mode_macro FP [(SF "TARGET_HARD_FLOAT")
+(define_mode_iterator 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")
+  (DD "TARGET_DFP")
+  (TD "TARGET_DFP")])
 
 ; Various instructions that come in SI and DI forms.
 ; A generic w/d attribute, for things like cmpw/cmpd.
   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]);
   [(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}
   operands[4] = GEN_INT (low);
   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]);
 
 (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" ""))
     ;
   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]));
         (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],
              (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)
        (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
-   (clobber (match_operand:DF 4 "memory_operand" "=o"))
+   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
    (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)]
   "
 {
        (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
-   (clobber (match_operand:DF 4 "memory_operand" "=o"))
+   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
    (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)]
   "
 {
   [(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 "memory_operand" "=o"))]
+   (clobber (match_operand:DI 3 "offsettable_mem_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)]
   "
 {
 (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 2 "offsettable_mem_operand" "=o"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
    (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
   "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS"
 (define_insn_and_split "floatunssidf_ppc64"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
-   (clobber (match_operand:DI 2 "memory_operand" "=o"))
+   (clobber (match_operand:DI 2 "offsettable_mem_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"
   [(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))))]
   ""
   "
   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;
          || (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:
   [(set_attr "length" "8,8,8,20,20,16")])
 
 (define_insn_and_split "*movtf_softfloat"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,Y,r")
+  [(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
   [(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"))]
   [(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))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
    (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
-   (clobber (match_operand:DI 5 "memory_operand" "=o"))]
+   (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
   "!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])"
 ;; 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"
   [(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"
 {
   [(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))"
        (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"
 {
        (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
   [(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<mode>"
        (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 "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")
+(include "paired.md")