optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL for a target with HAVE_cc0 defined.

* 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.

From-SVN: r24471
This commit is contained in:
Michael Hayes 1999-01-03 20:43:14 +00:00 committed by Jeff Law
parent 1cd0a8edca
commit 362cc3d434
5 changed files with 81 additions and 26 deletions

View 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

View 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));

View 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);

View 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). */

View 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])++;
}