OSDN Git Service

* rs6000.md (movstrsi_?reg): Use preferred rD/rS = r5 form.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Oct 1999 00:39:30 +0000 (00:39 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Oct 1999 00:39:30 +0000 (00:39 +0000)
        (scc patterns): Disable most SImode variants if TARGET_POWERPC64.
        * rs6000.c (expand_block_move): Match movstrsi_?reg register
        changes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29895 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index 0b52bb6..ef282fe 100644 (file)
@@ -1,3 +1,10 @@
+Sun Oct 10 20:05:21 1999  David Edelsohn  <edelsohn@gnu.org>
+
+       * rs6000.md (movstrsi_?reg): Use preferred rD/rS = r5 form.
+       (scc patterns): Disable most SImode variants if TARGET_POWERPC64.
+       * rs6000.c (expand_block_move): Match movstrsi_?reg register
+       changes.
+
 Sun Oct 10 16:37:01 1999  Richard Henderson  <rth@cygnus.com>
 
        * haifa-sched.c (sched_reg_n_calls_crossed): Delete.
@@ -242,7 +249,7 @@ Thu Oct  7 22:53:00 1999  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
         (make_lang_type_fn): Likewise.
         * rs6000.c (rs6000_build_va_list): Use make_lang_type.
 
-Thu Oct  7 00:36:17 MDT 1999   Diego Novillo <dnovillo@cygnus.com>
+Thu Oct  7 00:36:17 1999  Diego Novillo  <dnovillo@cygnus.com>
 
        * config/rs6000/rs6000.c (secondary_reload_class): For TARGET_ELF
        make sure that HIGH instructions are copied into BASE_REGS.
index 4080919..c2de411 100644 (file)
@@ -2136,12 +2136,12 @@ expand_block_move (operands)
                                            align_rtx));
            }
          else if (bytes > 16   /* move up to 24 bytes at a time */
+                  && ! fixed_regs[5]
+                  && ! fixed_regs[6]
                   && ! fixed_regs[7]
                   && ! fixed_regs[8]
                   && ! fixed_regs[9]
-                  && ! fixed_regs[10]
-                  && ! fixed_regs[11]
-                  && ! fixed_regs[12])
+                  && ! fixed_regs[10])
            {
              move_bytes = (bytes > 24) ? 24 : bytes;
              emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode,
@@ -2154,10 +2154,10 @@ expand_block_move (operands)
                                            align_rtx));
            }
          else if (bytes > 8    /* move up to 16 bytes at a time */
-                  && ! fixed_regs[9]
-                  && ! fixed_regs[10]
-                  && ! fixed_regs[11]
-                  && ! fixed_regs[12])
+                  && ! fixed_regs[5]
+                  && ! fixed_regs[6]
+                  && ! fixed_regs[7]
+                  && ! fixed_regs[8])
            {
              move_bytes = (bytes > 16) ? 16 : bytes;
              emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode,
index ee32350..5cc70c2 100644 (file)
 }")
 
 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
-;; register allocator doesn't have a clue about allocating 8 word registers
+;; register allocator doesn't have a clue about allocating 8 word registers.
+;; rD/rS = r5 is preferred, efficient form.
 (define_expand "movstrsi_8reg"
   [(parallel [(set (match_operand 0 "" "")
                   (match_operand 1 "" ""))
    (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "=q"))]
   "TARGET_STRING && TARGET_POWER
-   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
+   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
+       || INTVAL (operands[2]) == 0)
    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 5"
    (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "X"))]
   "TARGET_STRING && ! TARGET_POWER
-   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
+   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
+       || INTVAL (operands[2]) == 0)
    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 5"
    (set_attr "length" "8")])
 
 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
-;; register allocator doesn't have a clue about allocating 6 word registers
+;; register allocator doesn't have a clue about allocating 6 word registers.
+;; rD/rS = r5 is preferred, efficient form.
 (define_expand "movstrsi_6reg"
   [(parallel [(set (match_operand 0 "" "")
                   (match_operand 1 "" ""))
              (use (match_operand 2 "" ""))
              (use (match_operand 3 "" ""))
+             (clobber (reg:SI  5))
+             (clobber (reg:SI  6))
              (clobber (reg:SI  7))
              (clobber (reg:SI  8))
              (clobber (reg:SI  9))
              (clobber (reg:SI 10))
-             (clobber (reg:SI 11))
-             (clobber (reg:SI 12))
              (clobber (match_scratch:SI 4 ""))])]
   "TARGET_STRING"
   "")
    (use (match_operand:SI 2 "immediate_operand" "i"))
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
+   (clobber (reg:SI  6))
+   (clobber (reg:SI  7))
    (clobber (reg:SI  8))
    (clobber (reg:SI  9))
    (clobber (reg:SI 10))
-   (clobber (reg:SI 11))
-   (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "=q"))]
   "TARGET_STRING && TARGET_POWER
    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
-   && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
-   && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
-   && REGNO (operands[4]) == 7"
+   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
+   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
+   && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
    (set_attr "length" "8")])
    (use (match_operand:SI 2 "immediate_operand" "i"))
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
+   (clobber (reg:SI  6))
+   (clobber (reg:SI  7))
    (clobber (reg:SI  8))
    (clobber (reg:SI  9))
    (clobber (reg:SI 10))
-   (clobber (reg:SI 11))
-   (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "X"))]
   "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
-   && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
-   && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
-   && REGNO (operands[4]) == 7"
+   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
+   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
+   && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
    (set_attr "length" "8")])
 
-;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
-;; with TImode
+;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
+;; problems with TImode.
+;; rD/rS = r5 is preferred, efficient form.
 (define_expand "movstrsi_4reg"
   [(parallel [(set (match_operand 0 "" "")
                   (match_operand 1 "" ""))
              (use (match_operand 2 "" ""))
              (use (match_operand 3 "" ""))
-             (clobber (reg:SI  9))
-             (clobber (reg:SI 10))
-             (clobber (reg:SI 11))
-             (clobber (reg:SI 12))
+             (clobber (reg:SI 5))
+             (clobber (reg:SI 6))
+             (clobber (reg:SI 7))
+             (clobber (reg:SI 8))
              (clobber (match_scratch:SI 4 ""))])]
   "TARGET_STRING"
   "")
    (use (match_operand:SI 2 "immediate_operand" "i"))
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
-   (clobber (reg:SI 10))
-   (clobber (reg:SI 11))
-   (clobber (reg:SI 12))
+   (clobber (reg:SI 6))
+   (clobber (reg:SI 7))
+   (clobber (reg:SI 8))
    (clobber (match_scratch:SI 5 "=q"))]
   "TARGET_STRING && TARGET_POWER
    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
-   && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
-   && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
-   && REGNO (operands[4]) == 9"
+   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
+   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
+   && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
    (set_attr "length" "8")])
    (use (match_operand:SI 2 "immediate_operand" "i"))
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
-   (clobber (reg:SI 10))
-   (clobber (reg:SI 11))
-   (clobber (reg:SI 12))
+   (clobber (reg:SI 6))
+   (clobber (reg:SI 7))
+   (clobber (reg:SI 8))
    (clobber (match_scratch:SI 5 "X"))]
   "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
-   && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
-   && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
-   && REGNO (operands[4]) == 9"
+   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
+   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
+   && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
    (set_attr "length" "8")])
              (use (match_operand 3 "" ""))
              (clobber (match_scratch:DI 4 ""))
              (clobber (match_scratch:SI 5 ""))])]
-  "TARGET_STRING && ! TARGET_64BIT"
+  "TARGET_STRING && ! TARGET_POWERPC64"
   "")
 
 (define_insn ""
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_scratch:DI 4 "=&r"))
    (clobber (match_scratch:SI 5 "=q"))]
-  "TARGET_STRING && TARGET_POWER && ! TARGET_64BIT
+  "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_scratch:DI 4 "=&r"))
    (clobber (match_scratch:SI 5 "X"))]
-  "TARGET_STRING && ! TARGET_POWER && ! TARGET_64BIT
+  "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
        (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
               (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")))
    (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
    {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
        (eq:SI (match_dup 1) (match_dup 2)))
    (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
    {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
                        (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))
                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
    {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
          (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
    {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
        (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
    {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
        (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
                       (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
    {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
                  (const_int 31))
                 (match_operand:SI 2 "gpc_reg_operand" "r")))
    (clobber (match_scratch:SI 3 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
   [(set_attr "length" "8")])
 
                  (match_operand:SI 2 "gpc_reg_operand" "r"))
         (const_int 0)))
    (clobber (match_scratch:SI 3 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
   [(set_attr "type" "compare")
    (set_attr "length" "8")])
        (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
                 (match_dup 2)))
    (clobber (match_scratch:SI 3 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
   [(set_attr "type" "compare")
    (set_attr "length" "8")])
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                (match_operand:SI 2 "reg_or_short_operand" "rI")))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
   [(set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+               (match_operand:DI 2 "reg_or_short_operand" "rI")))]
+  "TARGET_POWERPC64"
+  "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0"
+  [(set_attr "length" "12")])
+
+(define_insn ""
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+       (compare:CC
+        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                (match_operand:DI 2 "reg_or_short_operand" "rI"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (leu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64"
+  "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
        (compare:CC
         (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
         (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (leu:SI (match_dup 1) (match_dup 2)))]
-   ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
   [(set_attr "type" "compare")
    (set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+       (compare:CC
+        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                (match_operand:DI 2 "reg_or_short_operand" "rI"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (leu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64"
+  "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                         (match_operand:SI 2 "reg_or_short_operand" "rI"))
                 (match_operand:SI 3 "gpc_reg_operand" "r")))
    (clobber (match_scratch:SI 4 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
   [(set_attr "length" "8")])
 
                  (match_operand:SI 3 "gpc_reg_operand" "r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
   [(set_attr "type" "compare")
    (set_attr "length" "8")])
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
   [(set_attr "type" "compare")
    (set_attr "length" "8")])
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                        (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
    [(set_attr "length" "12")])
 
                         (match_operand:SI 2 "reg_or_short_operand" "rI")))
                (match_operand:SI 3 "gpc_reg_operand" "r")))
    (clobber (match_scratch:SI 4 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
   [(set_attr "length" "12")])
 
                 (match_operand:SI 3 "gpc_reg_operand" "r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
   [(set_attr "type" "compare")
    (set_attr "length" "12")])
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
   [(set_attr "type" "compare")
    (set_attr "length" "12")])
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
    {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
         (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ltu:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
    {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
                 (match_operand:SI 3 "reg_or_short_operand" "rI,rI")))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
   {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
                  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
    {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
    {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                        (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
    {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
   [(set_attr "length" "12")])
 
 ;; This is (and (neg (ge X (const_int 0))) Y).
+;; srawi sign-extends, so these patterrns are 64-bit safe.
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (and:SI (neg:SI
   [(set_attr "length" "8")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (and:DI (neg:DI
+                (lshiftrt:DI
+                 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+                 (const_int 63)))
+               (match_operand:DI 2 "gpc_reg_operand" "r")))
+   (clobber (match_scratch:DI 3 "=&r"))]
+  "TARGET_POWERPC64"
+  "sradi %3,%1,63\;andc %0,%2,%3"
+  [(set_attr "length" "8")])
+
+(define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
        (compare:CC
         (and:SI (neg:SI
    (set_attr "length" "8")])
 
 (define_insn ""
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+       (compare:CC
+        (and:DI (neg:DI
+                 (lshiftrt:DI
+                  (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+                  (const_int 63)))
+                (match_operand:DI 2 "gpc_reg_operand" "r"))
+        (const_int 0)))
+   (clobber (match_scratch:DI 3 "=&r"))]
+  "TARGET_POWERPC64"
+  "sradi %3,%1,63\;andc. %3,%2,%3"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8")])
+
+(define_insn ""
   [(set (match_operand:CC 4 "cc_reg_operand" "=x")
        (compare:CC
         (and:SI (neg:SI
    (set_attr "length" "8")])
 
 (define_insn ""
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+       (compare:CC
+        (and:DI (neg:DI
+                 (lshiftrt:DI
+                  (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+                  (const_int 63)))
+                (match_operand:DI 2 "gpc_reg_operand" "r"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1))
+                                    (const_int 63)))
+               (match_dup 2)))
+   (clobber (match_scratch:SI 3 "=&r"))]
+  "TARGET_POWERPC64"
+  "sradi %3,%1,63\;andc. %0,%2,%3"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
    {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
   [(set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+               (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))]
+  "TARGET_POWERPC64"
+  "@
+   subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
+   addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
+  [(set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
        (compare:CC
         (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
         (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (geu:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
    {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
    (set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
+       (compare:CC
+        (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                (match_operand:DI 2 "reg_or_neg_short_operand" "r,P"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (geu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64"
+  "@
+   subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
+   addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
                 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
    {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
                  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
    {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
    {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                        (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
    {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
                (match_operand:SI 3 "gpc_reg_operand" "r,r")))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
    {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
    {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
    {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
               (const_int 0)))]
-  ""
+  "! TARGET_POWERPC64"
   "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
   [(set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+              (const_int 0)))]
+  "TARGET_POWERPC64"
+  "subfic %0,%1,0\;addme %0,%0\;srdi %0,%0,63"
+  [(set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:CC 2 "cc_reg_operand" "=x")
        (compare:CC
         (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
         (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (gt:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_POWERPC64"
   "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
   [(set_attr "type" "delayed_compare")
    (set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+       (compare:CC
+        (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (gt:DI (match_dup 1) (const_int 0)))]
+  "TARGET_POWERPC64"
+  "subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
               (match_operand:SI 2 "reg_or_short_operand" "r")))]
                        (const_int 0))
                 (match_operand:SI 2 "gpc_reg_operand" "r")))
    (clobber (match_scratch:SI 3 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
   [(set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                       (const_int 0))
+                (match_operand:DI 2 "gpc_reg_operand" "r")))
+   (clobber (match_scratch:DI 3 "=&r"))]
+  "TARGET_POWERPC64"
+  "addc %3,%1,%1\;subfe %3,%1,%3\;addze %0,%2"
+  [(set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
        (compare:CC
         (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                  (match_operand:SI 2 "gpc_reg_operand" "r"))
         (const_int 0)))
    (clobber (match_scratch:SI 3 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
   [(set_attr "type" "compare")
    (set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+       (compare:CC
+        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                        (const_int 0))
+                 (match_operand:DI 2 "gpc_reg_operand" "r"))
+        (const_int 0)))
+   (clobber (match_scratch:DI 3 "=&r"))]
+  "TARGET_POWERPC64"
+  "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:CC 4 "cc_reg_operand" "=x")
        (compare:CC
         (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
    (clobber (match_scratch:SI 3 "=&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
   [(set_attr "type" "compare")
    (set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+       (compare:CC
+        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                        (const_int 0))
+                 (match_operand:DI 2 "gpc_reg_operand" "r"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
+   (clobber (match_scratch:DI 3 "=&r"))]
+  "TARGET_POWERPC64"
+  "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %0,%2"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                        (match_operand:SI 2 "reg_or_short_operand" "r"))
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                       (const_int 0))))]
-  ""
+  "! TARGET_POWERPC64"
   "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
   [(set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (neg:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                      (const_int 0))))]
+  "TARGET_POWERPC64"
+  "subfic %0,%1,0\;addme %0,%0\;sradi} %0,%0,63"
+  [(set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                       (match_operand:SI 2 "reg_or_short_operand" "r"))))]
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                (match_operand:SI 2 "reg_or_short_operand" "rI")))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
   [(set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+               (match_operand:DI 2 "reg_or_short_operand" "rI")))]
+  "TARGET_POWERPC64"
+  "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg %0,%0"
+  [(set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
        (compare:CC
         (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
         (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (gtu:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
   [(set_attr "type" "compare")
    (set_attr "length" "12")])
 
 (define_insn ""
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+       (compare:CC
+        (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                (match_operand:DI 2 "reg_or_short_operand" "rI"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (gtu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64"
+  "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                         (match_operand:SI 2 "reg_or_short_operand" "I,rI"))
                 (match_operand:SI 3 "reg_or_short_operand" "r,rI")))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
    {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
   [(set_attr "length" "8,12")])
 
 (define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:DI 2 "reg_or_short_operand" "I,rI"))
+                (match_operand:DI 3 "reg_or_short_operand" "r,rI")))
+   (clobber (match_scratch:DI 4 "=&r,&r"))]
+  "TARGET_POWERPC64"
+  "@
+   addic %4,%1,%k2\;addze %0,%3
+   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subf%I3c %0,%4,%3"
+  [(set_attr "length" "8,12")])
+
+(define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
        (compare:CC
         (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3
    {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
    (set_attr "length" "8,12")])
 
 (define_insn ""
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+       (compare:CC
+        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                         (match_operand:DI 2 "reg_or_short_operand" "I,r"))
+                 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
+        (const_int 0)))
+   (clobber (match_scratch:DI 4 "=&r,&r"))]
+  "TARGET_POWERPC64"
+  "@
+   addic %4,%1,%k2\;addze. %4,%3
+   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8,12")])
+
+(define_insn ""
   [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
        (compare:CC
         (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
    {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
    (set_attr "length" "8,12")])
 
 (define_insn ""
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+       (compare:CC
+        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                         (match_operand:DI 2 "reg_or_short_operand" "I,r"))
+                 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:DI 4 "=&r,&r"))]
+  "TARGET_POWERPC64"
+  "@
+   addic %4,%1,%k2\;addze. %0,%3
+   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %0,%4,%3"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8,12")])
+
+(define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                        (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
-  ""
+  "! TARGET_POWERPC64"
   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
   [(set_attr "length" "8")])
+
+(define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (neg:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+                       (match_operand:DI 2 "reg_or_short_operand" "rI"))))]
+  "TARGET_POWERPC64"
+  "subf%I2c %0,%1,%2\;subfe %0,%0,%0"
+  [(set_attr "length" "8")])
 \f
 ;; Define both directions of branch and return.  If we need a reload
 ;; register, we'd rather use CR0 since it is much easier to copy a