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:
parent
1cd0a8edca
commit
362cc3d434
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
54
gcc/optabs.c
54
gcc/optabs.c
@ -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). */
|
||||
|
||||
|
30
gcc/unroll.c
30
gcc/unroll.c
@ -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])++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user