From 362cc3d434b402148d579551c6f3ff4d4798a296 Mon Sep 17 00:00:00 2001 From: Michael Hayes Date: Sun, 3 Jan 1999 20:43:14 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++++++++++ gcc/expr.h | 5 +++++ gcc/loop.c | 7 +++---- gcc/optabs.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/unroll.c | 30 ++++++++-------------------- 5 files changed, 81 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9321e7bf9ed..1e222523dc5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Sun Jan 3 22:58:15 1999 Michael Hayes + + * 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 * fixincludes (sys/utsname.h): Provide forward declaration of diff --git a/gcc/expr.h b/gcc/expr.h index 134c095bd8c..c6740c296aa 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -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)); diff --git a/gcc/loop.c b/gcc/loop.c index f1cdd033185..fea8287b7e2 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -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); diff --git a/gcc/optabs.c b/gcc/optabs.c index eb5f72a94c4..e57a8fc3679 100644 --- a/gcc/optabs.c +++ b/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). */ diff --git a/gcc/unroll.c b/gcc/unroll.c index 8723c35330f..8586e1deb39 100644 --- a/gcc/unroll.c +++ b/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])++; }