(tstdi, cmpdi, addsi_lshrsi_31, ashldi_extsi): New patterns.
authorRichard Kenner <kenner@gcc.gnu.org>
Fri, 12 May 1995 20:51:53 +0000 (16:51 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Fri, 12 May 1995 20:51:53 +0000 (16:51 -0400)
(extendqidi2, extendhidi2, extendsidi2): Allow "general_operand" instead
of "register_operand" 0.
(adddid_sexthishl32, subdid_sexthishl32, subdi_dishl32): Likewise.
(adddi_dilshr32): Operand 0 constraint changed from "ro" to "do";
Code generation fixed.
(adddi_mem, subdi_mem): Fixed for "<" and ">" operand 0.
(adddi3, subdi3): Operand 2 constraint changed from "ao" to "*ao"
(ashldi_sexthi, ashrdi_const32): Allow only "register_operand"
instead of "general_operand" 0.
(ash[lr]di_const, ash[lr]di3): Allow also 8 and 16 as shift count.
(subreg1ashrdi_const32): Pattern deleted.
(subreghi1ashrdi_const32, subregsi1ashrdi_const32): New pattern.
(lshrsi_31): New implementation.
(scc0_di, scc_di, beq0_di, bne0_di, bge0_di, blt0_di): New patterns.

From-SVN: r9666

gcc/config/m68k/m68k.md

index f6d623251a005e556cfa5d3b9c61e252d6049f68..118479d37a0fb0222c7c1bb52c2fe06eca44a2c0 100644 (file)
 ;; We don't want to allow a constant operand for test insns because
 ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
 ;; be folded while optimizing anyway.
+
+(define_insn "tstdi"
+  [(set (cc0)
+       (match_operand:DI 0 "nonimmediate_operand" "do"))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[0]) == REG)
+    operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+  else
+    operands[1] = adj_offsettable_operand (operands[0], 4);
+  /* Just in case we come here. I hope all tst:DI are combined !!! */
+  return \"neg%.l %1\;negx%.l %0\;neg%.l %1\;negx%.l %0\";
+}")
+
 (define_insn "tstsi"
   [(set (cc0)
        (match_operand:SI 0 "nonimmediate_operand" "rm"))]
 \f
 ;; compare instructions.
 
+(define_insn "cmpdi"
+  [(set (cc0)
+;;     (compare (match_operand:DI 0 "general_operand" "=&d*a")
+;;     (compare (match_operand:DI 0 "general_operand" "+&d*a")
+;;     (compare (match_operand:DI 0 "general_operand" "+d*a")
+       (compare (match_operand:DI 0 "general_operand" "d*a")
+                (match_operand:DI 1 "general_operand" "d")))
+   (clobber (match_scratch:DI 2 "=0"))]
+  ""
+  "*
+{
+  operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+  operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+  if (DATA_REG_P (operands[0]))
+    return \"sub%.l %3,%2\;subx%.l %1,%0\";
+  else
+    return \"exg %/d0,%2\;sub%.l %3,%/d0\;exg %/d0,%0\;subx%.l %1,%/d0\;exg %/d0,%2\";
+}")
+
 ;; This is the second "hook" for PIC code (in addition to movsi). See
 ;; comment of movsi for a description of PIC handling.
 (define_expand "cmpsi"
 \f
 ;; zero extension instructions
 
-;; this one is the canonical form for (lshiftrt:DI x 32)
+;; this is the canonical form for (lshiftrt:DI x 32)
 (define_insn "zero_extendsidi2"
   [(set (match_operand:DI 0 "general_operand" "ro,<,>")
     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,rm,rm")))]
 ;; sign extension instructions
 
 (define_insn "extendqidi2"
-  [(set (match_operand:DI 0 "register_operand" "=d")
+  [(set (match_operand:DI 0 "general_operand" "=d")
        (sign_extend:DI
         (match_operand:QI 1 "general_operand" "rm")))]
   ""
 }")
 
 (define_insn "extendhidi2"
-  [(set (match_operand:DI 0 "register_operand" "=d")
+  [(set (match_operand:DI 0 "general_operand" "=d")
        (sign_extend:DI
         (match_operand:HI 1 "general_operand" "rm")))]
   ""
 }")
 
 (define_insn "extendsidi2"
-  [(set (match_operand:DI 0 "register_operand" "=d")
+  [(set (match_operand:DI 0 "general_operand" "=d")
        (sign_extend:DI
         (match_operand:SI 1 "general_operand" "rm")))]
   ""
 } ")
 
 (define_insn "adddid_sexthishl32"
-  [(set (match_operand:DI 0 "register_operand" "+do")
+  [(set (match_operand:DI 0 "general_operand" "+ro")
     (plus:DI (ashift:DI (sign_extend:DI
           (match_operand:HI 1 "general_operand" "rm"))
             (const_int 32))
 } ")
 
 (define_insn "adddi_dilshr32"
-  [(set (match_operand:DI 0 "general_operand" "=ro")
+  [(set (match_operand:DI 0 "general_operand" "=do")
+;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
+;;     (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
+;;            (const_int 32))))]
     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
             (const_int 32))
         (match_operand:DI 2 "general_operand" "0")))]
 {
   CC_STATUS_INIT;
   if (GET_CODE (operands[0]) == REG)
-    operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+    operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
   else
-    operands[0] = adj_offsettable_operand (operands[0], 4);
-  return \"add%.l %1,%0\";
+    operands[2] = adj_offsettable_operand (operands[0], 4);
+  return \"add%.l %1,%2\;negx%.l %0\;neg%.l %0\";
 } ")
 
 (define_insn "adddi_dishl32"
   [(set (match_operand:DI 0 "general_operand" "=ro")
+;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
+;;     (ashift:DI (match_operand:DI 1 "general_operand" "ro")
+;;            (const_int 32))))]
     (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro")
             (const_int 32))
         (match_operand:DI 2 "general_operand" "0")))]
 } ")
 
 (define_insn "adddi_mem"
-  [(set (match_operand:DI 0 "general_operand" "=m")
-       (plus:DI (match_operand:DI 1 "general_operand" "%0")
-                (match_operand:DI 2 "general_operand" "d")))
-   (clobber (match_scratch:SI 3 "=d"))]
+  [(set (match_operand:DI 0 "general_operand" "=o,<,>")
+       (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0")
+                (match_operand:DI 2 "general_operand" "d,d,d")))
+   (clobber (match_scratch:SI 3 "=d,d,d"))]
   ""
   "*
 {
   CC_STATUS_INIT;
-  operands[1] = adj_offsettable_operand (operands[0], 4);
   operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+  if (which_alternative == 2)
+    {
+      operands[1] = gen_rtx (MEM, SImode,
+              gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
+                       gen_rtx (CONST_INT, VOIDmode, -8)));
+      return \"move%.l %0,%3\;add%.l %4,%0\;addx%.l %2,%3\;move%.l %3,%1\";
+    }
+  if (which_alternative == 1)
+    {
+      operands[1] = XEXP(operands[0], 0);
+      return \"add%.l %4,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
+    }
+  operands[1] = adj_offsettable_operand (operands[0], 4);
   return \"add%.l %4,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
 } ")
 
 (define_insn "adddi3"
   [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
        (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
-                (match_operand:DI 2 "general_operand" "ao,>,d,<")))]
+                (match_operand:DI 2 "general_operand" "*ao,>,d,<")))]
   ""
   "*
 {
   return \"add%.l %3,%1\;negx%.l %0\;neg%.l %0\;add%.l %2,%0\";
 } ")
 
+(define_insn "addsi_lshrsi_31"
+  [(set (match_operand:SI 0 "general_operand" "=dm")
+    (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
+            (const_int 31))
+        (match_operand:SI 2 "general_operand" "1")))]
+  ""
+  "*
+{
+  operands[2] = operands[0];
+  operands[3] = gen_label_rtx();
+  if (GET_CODE (operands[0]) == MEM)
+    {
+      if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+        operands[0] = gen_rtx (MEM, SImode, XEXP (XEXP (operands[0], 0), 0));
+      else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+        operands[2] = gen_rtx (MEM, SImode, XEXP (XEXP (operands[0], 0), 0));
+    }
+  output_asm_insn (\"mov%.l %1,%0\", operands);
+#ifdef MOTOROLA
+  output_asm_insn (\"jbpl %l3\", operands);
+#else
+  output_asm_insn (\"jpl %l3\", operands);
+#endif
+#ifndef NO_ADDSUB_Q
+  output_asm_insn (\"addq%.l %#1,%2\", operands);
+#else
+  output_asm_insn (\"add%.l %#1,%2\", operands);
+#endif
+  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+                               CODE_LABEL_NUMBER (operands[3]));
+  return \"\";
+}")
+
 ;; Note that the middle two alternatives are near-duplicates
 ;; in order to handle insns generated by reload.
 ;; This is needed since they are not themselves reloaded,
 } ")
 
 (define_insn "subdid_sexthishl32"
-  [(set (match_operand:DI 0 "register_operand" "+do")
+  [(set (match_operand:DI 0 "general_operand" "+ro")
     (minus:DI (match_dup 0)
         (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
             (const_int 32))))
 } ")
 
 (define_insn "subdi_dishl32"
-  [(set (match_operand:DI 0 "register_operand" "+d")
+  [(set (match_operand:DI 0 "general_operand" "+ro")
     (minus:DI (match_dup 0)
-        (ashift:DI (match_operand:DI 1 "register_operand" "d")
+        (ashift:DI (match_operand:DI 1 "general_operand" "ro")
             (const_int 32))))]
   ""
   "*
 {
   CC_STATUS_INIT;
-  operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+  if (GET_CODE (operands[1]) == REG)
+    operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+  else
+    operands[1] = adj_offsettable_operand (operands[1], 4);
   return \"sub%.l %1,%0\";
 } ")
 
 (define_insn "subdi_mem"
-  [(set (match_operand:DI 0 "general_operand" "=m")
-       (minus:DI (match_operand:DI 1 "general_operand" "0")
-                (match_operand:DI 2 "general_operand" "d")))
-   (clobber (match_scratch:SI 3 "=d"))]
+  [(set (match_operand:DI 0 "general_operand" "=o,<,>")
+       (minus:DI (match_operand:DI 1 "general_operand" "0,0,0")
+                (match_operand:DI 2 "register_operand" "d,d,d")))
+   (clobber (match_scratch:SI 3 "=d,d,d"))]
   ""
   "*
 {
   CC_STATUS_INIT;
-  operands[1] = adj_offsettable_operand (operands[0], 4);
   operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+  if (which_alternative == 2)
+    {
+      operands[1] = gen_rtx (MEM, SImode,
+              gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
+                       gen_rtx (CONST_INT, VOIDmode, -8)));
+      return \"move%.l %0,%3\;sub%.l %4,%0\;subx%.l %2,%3\;move%.l %3,%1\";
+    }
+  if (which_alternative == 1)
+    {
+      operands[1] = XEXP(operands[0], 0);
+      return \"sub%.l %4,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
+    }
+  operands[1] = adj_offsettable_operand (operands[0], 4);
   return \"sub%.l %4,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
 } ")
 
 (define_insn "subdi3"
   [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
        (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
-                (match_operand:DI 2 "general_operand" "ao,>,d,<")))]
+                (match_operand:DI 2 "general_operand" "*ao,>,d,<")))]
   ""
   "*
 {
 ;; arithmetic shift instructions
 ;; We don't need the shift memory by 1 bit instruction
 
+(define_insn "ashldi_extsi"
+  [(set (match_operand:DI 0 "general_operand" "=ro")
+    (ashift:DI
+      (match_operator:DI 2 "extend_operator"
+        [(match_operand:SI 1 "general_operand" "rm")])
+      (const_int 32)))]
+  ""
+  "*
+{
+  CC_STATUS_INIT;
+  if (GET_CODE (operands[0]) == REG)
+    operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+  else
+    operands[2] = adj_offsettable_operand (operands[0], 4);
+  if (ADDRESS_REG_P (operands[0]))
+    return \"move%.l %1,%0\;sub%.l %2,%2\";
+  else
+    return \"move%.l %1,%0\;clr%.l %2\";
+} ")
+
 (define_insn "ashldi_sexthi"
-  [(set (match_operand:DI 0 "general_operand" "=*da")
+  [(set (match_operand:DI 0 "register_operand" "=*da")
     (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
         (const_int 32)))]
   ""
     return \"move%.l %3,%0\;clr%.l %2\";
 } ")
 
+;; The predicate below must be general_operand, because ashldi3 allows that
 (define_insn "ashldi_const"
   [(set (match_operand:DI 0 "general_operand" "=d")
        (ashift:DI (match_operand:DI 1 "general_operand" "0")
                     (match_operand 2 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 1
+    || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
    || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
   "*
 {
   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
   if (INTVAL (operands[2]) == 1)
     return \"add%.l %1,%1\;addx%.l %0,%0\";
+  else if (INTVAL (operands[2]) == 8)
+    return \"rol%.l %#8,%1\;rol%.l %#8,%0\;mov%.b %1,%0\;clr%.b %1\";
+  else if (INTVAL (operands[2]) == 16)
+    return \"swap %1\;swap %0\;mov%.w %1,%0\;clr%.w %1\";
   else if (INTVAL (operands[2]) == 2)
     return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\";
   else/* if (INTVAL (operands[2]) == 3)*/
 } ")
 
 (define_expand "ashldi3"
-  [(set (match_operand:DI 0 "general_operand" "=rm")
-       (ashift:DI (match_operand:DI 1 "general_operand" "rm")
-                    (match_operand 2 "const_int_operand" "n")))]
+  [(set (match_operand:DI 0 "general_operand" "")
+       (ashift:DI (match_operand:DI 1 "general_operand" "")
+                    (match_operand 2 "const_int_operand" "")))]
   ""
   "
 {
   if (GET_CODE (operands[2]) != CONST_INT
   || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
+     && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
      && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
     FAIL;
 } ")
   return \"swap %0\;asr%.w %2,%0\;ext%.l %0\";
 }")
 
-(define_insn "subreg1ashrdi_const32"
+(define_insn "subreghi1ashrdi_const32"
+  [(set (match_operand:HI 0 "general_operand" "=rm")
+    (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
+            (const_int 32)) 1))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[1]) != REG)
+    operands[1] = adj_offsettable_operand (operands[1], 2);
+  return \"move%.w %1,%0\";
+} ")
+
+(define_insn "subregsi1ashrdi_const32"
   [(set (match_operand:SI 0 "general_operand" "=rm")
     (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
             (const_int 32)) 1))]
 } ")
 
 (define_insn "ashrdi_const32"
-  [(set (match_operand:DI 0 "general_operand" "=d")
+  [(set (match_operand:DI 0 "register_operand" "=d")
        (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
                     (const_int 32)))]
   ""
     return \"move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\";
 } ")
 
+;; The predicate below must be general_operand, because ashrdi3 allows that
 (define_insn "ashrdi_const"
   [(set (match_operand:DI 0 "general_operand" "=d")
        (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
                     (match_operand 2 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 1
+    || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
   || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
   "*
 {
   CC_STATUS_INIT;
   if (INTVAL (operands[2]) == 1)
     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\";
+  else if (INTVAL (operands[2]) == 8)
+    return \"mov%.b %0,%1\;asr%.l %#8,%0\;ror%.l %#8,%1\";
+  else if (INTVAL (operands[2]) == 16)
+    return \"mov%.w %0,%1\;clr%.w %0\;swap %1\;ext%.l %0\";
   else if (INTVAL (operands[2]) == 2)
     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
   else/* if (INTVAL (operands[2]) == 3)*/
 } ")
 
 (define_expand "ashrdi3"
-  [(set (match_operand:DI 0 "general_operand" "=rm")
-       (ashiftrt:DI (match_operand:DI 1 "general_operand" "rm")
-                    (match_operand 2 "const_int_operand" "n")))]
+  [(set (match_operand:DI 0 "general_operand" "")
+       (ashiftrt:DI (match_operand:DI 1 "general_operand" "")
+                    (match_operand 2 "const_int_operand" "")))]
   ""
   "
 {
   if (GET_CODE (operands[2]) != CONST_INT
   || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
+     && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
      && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
     FAIL;
 } ")
 \f
 ;; logical shift instructions
 
+(define_insn ""
+        [(set (cc0)
+            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
+                    (const_int 32)) 1))
+        (set (match_operand:SI 1 "general_operand" "=dm")
+            (subreg:SI (lshiftrt:DI (match_operand:DI 2 "general_operand" "0")
+                    (const_int 32)) 1))]
+  ""
+  "*
+{
+  return \"move%.l %0,%1\";
+} ")
+
+(define_insn ""
+        [(set (cc0)
+            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
+                    (const_int 32)) 0))
+        (set (match_operand:DI 1 "general_operand" "=do")
+            (lshiftrt:DI (match_operand:DI 2 "general_operand" "0")
+                (const_int 32)))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[1]) == REG)
+    operands[2] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+  else
+    operands[2] = adj_offsettable_operand (operands[1], 4);
+  return \"move%.l %0,%2\;clr%.l %1\";
+} ")
+
 (define_insn "subreg1lshrdi_const32"
   [(set (match_operand:SI 0 "general_operand" "=rm")
     (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
     return \"move%.l %1,%2\;clr%.l %0\";
 } ")
 
+;; The predicate below must be general_operand, because lshrdi3 allows that
 (define_insn "lshrdi_const"
   [(set (match_operand:DI 0 "general_operand" "=d")
        (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
                     (match_operand 2 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 1 
+    || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
     || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
   "*
 {
   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
   if (INTVAL (operands[2]) == 1)
     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\";
+  else if (INTVAL (operands[2]) == 8)
+    return \"mov%.b %0,%1\;lsr%.l %#8,%0\;ror%.l %#8,%1\";
+  else if (INTVAL (operands[2]) == 16)
+    return \"mov%.w %0,%1\;clr%.w %0\;swap %1\;swap %0\";
   else if (INTVAL (operands[2]) == 2)
     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\";
   else /*if (INTVAL (operands[2]) == 3)*/
 } ")
 
 (define_expand "lshrdi3"
-  [(set (match_operand:DI 0 "general_operand" "=rm")
-       (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
-                    (match_operand 2 "const_int_operand" "n")))]
+  [(set (match_operand:DI 0 "general_operand" "")
+       (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
+                    (match_operand 2 "const_int_operand" "")))]
   ""
   "
 {
   if (GET_CODE (operands[2]) != CONST_INT
   || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
+     && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
       && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
     FAIL;
 } ")
   ""
   "*
 {
-#if defined(MOTOROLA) && !defined(CRDS)
-  return \"roxl%.l %#1,%0\;moveq%.l %#0,%d0\;roxl%.l %#1,%0\";
-#else
-  return \"roxl%.l %#1,%0\;moveq %#0,%d0\;roxl%.l %#1,%0\";
-#endif
+  return \"add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0\";
 }")
 
 ;; On all 68k models, this makes faster code in a special case.
   return \"bftst %0{%b2:%b1}\";
 }")
 \f
+(define_insn "scc0_di"
+  [(set (match_operand:QI 0 "general_operand" "=dm")
+    (match_operator 1 "valid_dbcc_comparison_p"
+      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
+  ""
+  "*
+{
+  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
+} ")
+
+(define_insn "scc_di"
+  [(set (match_operand:QI 0 "general_operand" "=dm,dm")
+    (match_operator 1 "valid_dbcc_comparison_p"
+      [(match_operand:DI 2 "general_operand" "ro,r")
+       (match_operand:DI 3 "general_operand" "r,ro")]))]
+  ""
+  "*
+{
+  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
+} ")
+
 (define_insn "seq"
   [(set (match_operand:QI 0 "general_operand" "=d")
        (eq:QI (cc0) (const_int 0)))]
 \f
 ;; Basic conditional jump instructions.
 
+(define_insn "beq0_di"
+  [(set (pc)
+    (if_then_else (eq (match_operand:DI 0 "general_operand" "d*ao,<>")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ","))
+        (pc)))
+   (clobber (match_scratch:SI 2 "=d,d"))]
+  ""
+  "*
+{
+  if (which_alternative == 1)
+    return \"move%.l %0,%2\;or%.l %0,%2\;jbeq %l1\";
+  if (GET_CODE (operands[0]) == REG)
+    operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+  else
+    operands[3] = adj_offsettable_operand (operands[0], 4);
+  if (! ADDRESS_REG_P (operands[0]))
+    return \"move%.l %0,%2\;or%.l %3,%2\;jbeq %l1\";
+  operands[4] = gen_label_rtx();
+  output_asm_insn (\"tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1\", operands);
+  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+                               CODE_LABEL_NUMBER (operands[4]));
+  return \"\";
+} ")
+
+(define_insn "bne0_di"
+  [(set (pc)
+    (if_then_else (ne (match_operand:DI 0 "general_operand" "do,*a")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ","))
+        (pc)))
+   (clobber (match_scratch:SI 2 "=d,"))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[0]) == REG)
+    operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+  else
+    operands[3] = adj_offsettable_operand (operands[0], 4);
+  if (ADDRESS_REG_P (operands[0]))
+    return \"tst%.l %0\;jbne %l1\;tst%.l %3\;jbne %l1\";
+  else
+    return \"move%.l %0,%2\;or%.l %3,%2\;jbne %l1\";
+} ")
+
+(define_insn "bge0_di"
+  [(set (pc)
+    (if_then_else (ge (match_operand:DI 0 "general_operand" "ro")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ""))
+        (pc)))]
+  ""
+  "*
+{
+  return \"tst%.l %0\;jbge %l1\";
+} ")
+
+(define_insn "blt0_di"
+  [(set (pc)
+    (if_then_else (lt (match_operand:DI 0 "general_operand" "ro")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ""))
+        (pc)))]
+  ""
+  "*
+{
+  return \"tst%.l %0\;jbmi %l1\";
+} ")
+
 (define_insn "beq"
   [(set (pc)
        (if_then_else (eq (cc0)