OSDN Git Service

* optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 Jan 1999 20:43:14 +0000 (20:43 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 Jan 1999 20:43:14 +0000 (20:43 +0000)
        for a target with HAVE_cc0 defined.
        (emit_cmp_and_jump_insns): New function.
        * expr.h (emit_cmp_and_jump_insns): Prototype it.
        * loop.c (check_dbra_loop): Use it to replace calls
        to emit_cmp_insn and emit_jump_insn and to canonicalise
        the comparison if necessary.
        * unroll.c (unroll_loop): Likewise.

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

gcc/ChangeLog
gcc/expr.h
gcc/loop.c
gcc/optabs.c
gcc/unroll.c

index 9321e7b..1e22252 100644 (file)
@@ -1,3 +1,14 @@
+Sun Jan  3 22:58:15 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL
+       for a target with HAVE_cc0 defined.
+       (emit_cmp_and_jump_insns): New function.
+       * expr.h (emit_cmp_and_jump_insns): Prototype it.
+       * loop.c (check_dbra_loop): Use it to replace calls
+       to emit_cmp_insn and emit_jump_insn and to canonicalise
+       the comparison if necessary.
+       * unroll.c (unroll_loop): Likewise.
+
 Sun Jan  3 21:01:04 1999  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 
        * fixincludes (sys/utsname.h): Provide forward declaration of
index 134c095..c6740c2 100644 (file)
@@ -614,6 +614,11 @@ extern void emit_0_to_1_insn PROTO((rtx));
 extern void emit_cmp_insn PROTO((rtx, rtx, enum rtx_code, rtx,
                                 enum machine_mode, int, int));
 
+/* Emit a pair of rtl insns to compare two rtx's and to jump 
+   to a label if the comparison is true.  */
+extern void emit_cmp_and_jump_insns PROTO((rtx, rtx, enum rtx_code, rtx,
+                                          enum machine_mode, int, int, rtx));
+
 /* Nonzero if a compare of mode MODE can be done straightforwardly
    (without splitting it into pieces).  */
 extern int can_compare_p PROTO((enum machine_mode));
index f1cdd03..fea8287 100644 (file)
@@ -7072,10 +7072,9 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
 
              /* Add new compare/branch insn at end of loop.  */
              start_sequence ();
-             emit_cmp_insn (reg, const0_rtx, cmp_code, NULL_RTX,
-                            GET_MODE (reg), 0, 0);
-             emit_jump_insn ((*bcc_gen_fctn[(int) cmp_code])
-                             (XEXP (jump_label, 0)));
+             emit_cmp_and_jump_insns (reg, const0_rtx, cmp_code, NULL_RTX,
+                                      GET_MODE (reg), 0, 0, 
+                                      XEXP (jump_label, 0));
              tem = gen_sequence ();
              end_sequence ();
              emit_jump_insn_before (tem, loop_end);
index eb5f72a..e57a8fc 100644 (file)
@@ -2722,6 +2722,14 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
   if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
     y = force_reg (mode, y);
 
+#ifdef HAVE_cc0
+  /* Abort if we have a non-canonical comparison.  The RTL documentation
+     states that canonical comparisons are required only for targets which
+     have cc0.  */
+  if (CONSTANT_P (x) && ! CONSTANT_P (y))
+    abort();
+#endif
+
   /* Don't let both operands fail to indicate the mode.  */
   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
     x = force_reg (mode, x);
@@ -2913,6 +2921,52 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
     abort ();
 }
 
+/* Generate code to compare X with Y so that the condition codes are
+   set and to jump to LABEL if the condition is true.  If X is a
+   constant and Y is not a constant, then the comparison is swapped to
+   ensure that the comparison RTL has the canonical form.
+
+   MODE is the mode of the inputs (in case they are const_int).
+   UNSIGNEDP nonzero says that X and Y are unsigned;
+   this matters if they need to be widened.
+
+   If they have mode BLKmode, then SIZE specifies the size of both X and Y,
+   and ALIGN specifies the known shared alignment of X and Y.
+
+   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+   It is ignored for fixed-point and block comparisons;
+   it is used only for floating-point comparisons.  */
+
+void
+emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
+     rtx x, y;
+     enum rtx_code comparison;
+     rtx size;
+     enum machine_mode mode;
+     int unsignedp;
+     int align;
+     rtx label;
+{
+  rtx op0;
+  rtx op1;
+         
+  if (GET_CODE (x) == CONST_INT)
+    {
+      /* Swap operands and condition to ensure canonical RTL.  */
+      op0 = y;
+      op1 = x;
+      comparison = swap_condition (comparison);
+    }
+  else
+    {
+      op0 = x;
+      op1 = y;
+    }
+  emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
+  emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
+}
+
+
 /* Nonzero if a compare of mode MODE can be done straightforwardly
    (without splitting it into pieces).  */
 
index 8723c35..8586e1d 100644 (file)
@@ -919,12 +919,9 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
 
          if (loop_info->comparison_code != NE)
            {
-             emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
-                            NULL_RTX, mode, 0, 0);
-             if (neg_inc)
-               emit_jump_insn (gen_ble (labels[1]));
-             else
-               emit_jump_insn (gen_bge (labels[1]));
+             emit_cmp_and_jump_insns (initial_value, final_value, 
+                                      neg_inc ? LE : GE,
+                                      NULL_RTX, mode, 0, 0, labels[1]);
              JUMP_LABEL (get_last_insn ()) = labels[1];
              LABEL_NUSES (labels[1])++;
            }
@@ -965,15 +962,9 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
                  cmp_code = LE;
                }
 
-             emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
-                            cmp_code, NULL_RTX, mode, 0, 0);
-
-             if (i == 0)
-               emit_jump_insn (gen_beq (labels[i]));
-             else if (neg_inc)
-               emit_jump_insn (gen_bge (labels[i]));
-             else
-               emit_jump_insn (gen_ble (labels[i]));
+             emit_cmp_and_jump_insns (diff, GEN_INT (abs_inc * cmp_const),
+                                      cmp_code, NULL_RTX, mode, 0, 0,
+                                      labels[i]);
              JUMP_LABEL (get_last_insn ()) = labels[i];
              LABEL_NUSES (labels[i])++;
            }
@@ -1003,13 +994,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
                  cmp_code = GE;
                }
 
-             emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,
-                            mode, 0, 0);
-
-             if (neg_inc)
-               emit_jump_insn (gen_ble (labels[0]));
-             else
-               emit_jump_insn (gen_bge (labels[0]));
+             emit_cmp_and_jump_insns (diff, GEN_INT (cmp_const), cmp_code,
+                                      NULL_RTX, mode, 0, 0, labels[0]);
              JUMP_LABEL (get_last_insn ()) = labels[0];
              LABEL_NUSES (labels[0])++;
            }